Weitere ähnliche Inhalte Ähnlich wie Nate tech deck (20) Kürzlich hochgeladen (20) Nate tech deck1. Corona SDK
®
Code less. Play more.
anscamobile.com
2. Corona SDK
®
Code less. Play more.
Nate Ryan
anscamobile.com
5. display.newImage( "sky.png" )
local ground = display.newImage("ground.png", 0, 400)
local crate = display.newImage("crate.png", 160, 50 );
crate.rotation = 30
local physics = require("physics")
physics.start()
physics.addBody( ground, "static", { friction=0.5, bounce=0.3 } )
physics.addBody( crate, { density=0.9, friction=0.3, bounce=0.3} )
Write once
Corona
Develop 10x faster
Publish to top stores The ultimate
Monetize and distribute
mobile platform
Available on
anscamobile.com
8. What is Corona?
SDK for native apps
...
develop 5-10x faster
same code, multiple stores
anscamobile.com
11. Roberto Lerusalimschy
one of the original Lua
founders (1993) now sits
on the advisory board
with Corona Labs.
anscamobile.com
12. • Dynamically Typed
• Extremely fast and efficient
• First Class functions
• TABLES! (associative arrays, dictionary, collection)
• Can run on any platform with ANSI C
• Embeddable and extensible
anscamobile.com
13. Other Languages –> Lua
if (not carMoving) then
if (!carMoving) {
-- do something
// do something
elseif (noGas) then
} else if (noGas) {
-- something else
// something else
end
}
for i = 1,10 do
for (i=1; i<=10; i++) {
print(i)
print(i)
end
}
for j = 100,1,-1 do
for (j=100; j>0; j--) {
print(j)
print(j)
end
}
anscamobile.com
14. Lua Objects are
myTable = { "a", "b", 100, "hello" }
Tables
otherTable = { x=5, y=7, name="Joe" }
newTable = {}
newTable[1] = "a"
newTable.x = 5
newTable.hasProperties = true
newTable["name"] = "Joe"
newTable["printJoe"] = function() print("Joe") end
anscamobile.com
15. • [[-- Comments --]]
• x,y = y,x (multiple assignments)
• ~= (non equality)
• 1 based indexing
• no classes, OO implemented with tables and functions
• Inheritance Implemented with metatable
anscamobile.com
16. W e bK base
data
Tons of S Q Li t
File
e
read
/ write
i
p t in g lan
g uage
a
p hics
a scr e d gr
ll Lu lerat
Features/APIs Fu
Hard
w are-a
cce
s , acc
e lero m
eter
cal b
o d ies
mpas p hysi
• Content scaling
GP S, co
e and
co m plex
TP, HTTP
F <html5> or l
, etc.)
ocal
)
S impl TCP, g
o rk ing ( tre amin tion,
Netw (s c
ack s, f ri
playb (mas etc.
• Multi-resolution Vi de
o
i cal pr
o perti
e
n
s
g es, p
u lleys
,
n dent
Phys ls, hi de p e
images
ts, whee w i t h in g pre
Jo in es lu d i
n
sprit c
m ate d io n, in p o r t
An i d etect r k su
p
etwo
lli sion e n s an
d
Co gam shap
e
nt PIs (
• Simulator (instant Ope nFei
d ra w ing
A
, etc.)
,
ctor oard a512
refresh)
Ve
I (keyb a 1, s h
ve U 5, sh
Nati , md MP3)
(md4 ts o r
C r ypto d effec n l i b ra
(so un
n sitio
A u d io n d t ra b rarie
s
• Cloud services
io n a er li
A n i ma
t
d Tw itt y ha
n
ok a
n emor
F aceb
o
t ure m
d tex tion
Imp ro ve a
c s im u l
s anscamobile.com y i brar
p hysi oto l
18. Develop 5-10x faster
“Angry Birds” “Fruit Ninja” “Tiny Wings”
36 hours
14 hours
12 hours
code+graphics code+graphics code+graphics
+sound
+sound
+sound
(complete 2 level (gameplay only) (gameplay only)
“Developing directly in Xcode would have
been at least 5x more code than Corona”
– Unicorn Labs, Top 20 iPad eBook
anscamobile.com
19. • build.settings (ie manifest settings, permissions, etc)
• config.lua. (Corona instructions)
• Main.lua
anscamobile.com
22. Hard Problems
Made Easy
(i.e., how Corona will teach you
to love physics)
anscamobile.com
23. Phone SDK.
OpenGL in one line [EAGLContext setCurrentContext:context];
[aContext release];
// Display "myImage.png"
// Create default framebuffer object.
[(EAGLView *)self.view setContext:context];
// ----------------------------------------------------------------------------
glGenFramebuffers(1, &defaultFramebuffer);
[(EAGLView *)self.view setFramebuffer];
// OpenGLESTextureAppDelegate.m
glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer);
// ----------------------------------------------------------------------------
[self loadTexture];
// Create color render buffer and allocate backing store.
#import "OpenGLESTextureAppDelegate.h"
glGenRenderbuffers(1, &colorRenderbuffer);
self.displayLink = nil;
#import "EAGLView.h"
glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
}
#import "OpenGLESTextureViewController.h"
[context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer
*)self.layer];
- (void) loadTexture
@implementation OpenGLESTextureAppDelegate
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, {
&framebufferWidth);
glEnable(GL_TEXTURE_2D);
@synthesize window=_window;
glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, glEnable(GL_BLEND);
&framebufferHeight);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
@synthesize viewController=_viewController;
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
glGenTextures(1, &textureID);
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: colorRenderbuffer);
glBindTexture(GL_TEXTURE_2D, textureID);
(NSDictionary *)launchOptions
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
{
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
// Override point for customization after application launch.
NSLog(@"Failed to make complete framebuffer object %x",
self.window.rootViewController = self.viewController;
glCheckFramebufferStatus(GL_FRAMEBUFFER));
NSString *path = [[NSBundle mainBundle] pathForResource:@"myImage" ofType:@"png"];
return YES;
}
NSData *texData = [[NSData alloc] initWithContentsOfFile:path];
}
}
UIImage *image = [[UIImage alloc] initWithData:texData];
- (void)applicationDidBecomeActive:(UIApplication *)application
- (void)deleteFramebuffer
GLuint width = CGImageGetWidth(image.CGImage);
{
{
GLuint height = CGImageGetHeight(image.CGImage);
/*
if (context) {
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
Restart any tasks that were paused (or not yet started) while the application was [EAGLContext setCurrentContext:context];
void *imageData = malloc( height width 4 );
inactive. If the application was previously in the background, optionally refresh the user
CGContextRef image_context = CGBitmapContextCreate( imageData, width, height, 8, 4
interface.
if (defaultFramebuffer) {
width, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big );
*/
glDeleteFramebuffers(1, &defaultFramebuffer);
CGColorSpaceRelease( colorSpace );
[self.viewController drawFrame];
defaultFramebuffer = 0;
CGContextClearRect( image_context, CGRectMake( 0, 0, width, height ) );
}
}
CGContextTranslateCTM( image_context, 0, height - height );
CGContextDrawImage( image_context, CGRectMake( 0, 0, width, height ), image.CGImage );
- (void)dealloc
if (colorRenderbuffer) {
{
glDeleteRenderbuffers(1, &colorRenderbuffer);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
[_window release];
colorRenderbuffer = 0;
imageData);
[_viewController release];
}
[super dealloc];
}
CGContextRelease(image_context);
}
}
free(imageData);
@end
- (void)setFramebuffer
[image release];
{
[texData release];
display.newImage("myImage.png")
if (context) {
// ----------------------------------------------------------------------------
[EAGLContext setCurrentContext:context];
}
// EAGLView.m
// ----------------------------------------------------------------------------
if (!defaultFramebuffer)
- (void)dealloc
[self createFramebuffer];
{
#import <QuartzCore/QuartzCore.h>
glDeleteTextures(1, &textureID);
#import "EAGLView.h"
glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer);
// Tear down context.
@interface EAGLView (PrivateMethods)
glViewport(0, 0, framebufferWidth, framebufferHeight);
if ([EAGLContext currentContext] == context)
- (void)createFramebuffer;
}
[EAGLContext setCurrentContext:nil];
- (void)deleteFramebuffer;
}
@end
[context release];
- (BOOL)presentFramebuffer
@implementation EAGLView
{
[super dealloc];
BOOL success = FALSE;
}
@synthesize context;
if (context) {
- (void)viewDidUnload
// You must implement this method
[EAGLContext setCurrentContext:context];
{
+ (Class)layerClass
[super viewDidUnload];
{
glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer);
return [CAEAGLLayer class];
// Tear down context.
}
success = [context presentRenderbuffer:GL_RENDERBUFFER];
if ([EAGLContext currentContext] == context)
}
[EAGLContext setCurrentContext:nil];
//The EAGL view is stored in the nib file. When it's unarchived it's sent -initWithCoder:.
self.context = nil;
- (id)initWithCoder:(NSCoder*)coder
return success;
}
{
}
self = [super initWithCoder:coder];
- (void)drawFrame
if (self) {
- (void)layoutSubviews
{
CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer;
{
[(EAGLView *)self.view setFramebuffer];
// The framebuffer will be re-created at the beginning of the next setFramebuffer
eaglLayer.opaque = TRUE;
method call.
// Replace the implementation of this method to do your own custom drawing.
eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
[self deleteFramebuffer];
static const GLfloat squareVertices[] = {
[NSNumber numberWithBool:FALSE], }
-0.5f, -0.33f,
kEAGLDrawablePropertyRetainedBacking,
0.5f, -0.33f,
kEAGLColorFormatRGBA8, @end
-0.5f, 0.33f,
kEAGLDrawablePropertyColorFormat,
0.5f, 0.33f,
nil];
};
}
// ----------------------------------------------------------------------------
// OpenGLESTextureViewController.m
static const GLfloat texCoords[] = {
return self;
// ----------------------------------------------------------------------------
0.0, 1.0,
}
1.0, 1.0,
#import <QuartzCore/QuartzCore.h>
0.0, 0.0,
- (void)dealloc
#import "OpenGLESTextureViewController.h"
1.0, 0.0
{
#import "EAGLView.h"
};
[self deleteFramebuffer];
[context release];
@interface OpenGLESTextureViewController ()
@property (nonatomic, retain) EAGLContext *context;
glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
[super dealloc];
@property (nonatomic, assign) CADisplayLink *displayLink;
glClear(GL_COLOR_BUFFER_BIT);
}
- (void) loadTexture;
@end
glMatrixMode(GL_PROJECTION);
- (void)setContext:(EAGLContext *)newContext
glLoadIdentity();
{
@implementation OpenGLESTextureViewController
glMatrixMode(GL_MODELVIEW);
if (context != newContext) {
glLoadIdentity();
[self deleteFramebuffer];
@synthesize animating, context, displayLink;
glVertexPointer(2, GL_FLOAT, 0, squareVertices);
[context release];
- (void)awakeFromNib
glEnableClientState(GL_VERTEX_ARRAY);
context = [newContext retain];
{
glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
EAGLContext *aContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1];
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
[EAGLContext setCurrentContext:nil];
}
if (!aContext)
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
}
NSLog(@"Failed to create ES context");
anscamobile.com
else if (![EAGLContext setCurrentContext:aContext])
[(EAGLView *)self.view presentFramebuffer];
- (void)createFramebuffer
NSLog(@"Failed to set ES context current");
}
{
if (context && !defaultFramebuffer) {
self.context = aContext;
@end
24. local sky = display.newImage( "clouds.png" )
anscamobile.com
26. local sky = display.newImage( "clouds.png" )
local ground = display.newImage( "ground.png" )
ground.x = 160
ground.y = 445
anscamobile.com
28. local sky = display.newImage( "clouds.png" )
local ground = display.newImage( "ground.png" )
ground.x = 160
ground.y = 445
local crate = display.newImage( "crate.png" )
crate.x = 180
crate.y = 80
crate.rotation = 10
anscamobile.com
30. local physics = require( "physics" )
physics.start()
local sky = display.newImage( "clouds.png" )
local ground = display.newImage( "ground.png" )
ground.x = 160
ground.y = 445
local crate = display.newImage( "crate.png" )
crate.x = 180
crate.y = 80
crate.rotation = 10
anscamobile.com
31. local physics = require( "physics" )
physics.start()
local sky = display.newImage( "clouds.png" )
local ground = display.newImage( "ground.png" )
ground.x = 160
ground.y = 445
physics.addBody( ground, { friction=0.5 } )
ground.bodyType = "static"
local crate = display.newImage( "crate.png" )
crate.x = 180
crate.y = 80
crate.rotation = 10
anscamobile.com
32. local physics = require( "physics" )
physics.start()
local sky = display.newImage( "clouds.png" )
local ground = display.newImage( "ground.png" )
ground.x = 160
ground.y = 445
physics.addBody( ground, { friction=0.5 } )
ground.bodyType = "static"
local crate = display.newImage( "crate.png" )
crate.x = 180
crate.y = 80
crate.rotation = 10
physics.addBody( crate, { density=2.0,
friction=0.5, bounce=0.3 } )
anscamobile.com
34. What if we want
lots of crates?
anscamobile.com
35. local crate = display.newImage( "crate.png" )
crate.x = 180
crate.y = -100
crate.rotation = 10
physics.addBody( crate, { density=2.0,
friction=0.5, bounce=0.3 } )
anscamobile.com
36. local function spawnCrate()
local crate = display.newImage( "crate.png" )
crate.x = math.random( 320 )
crate.y = -100
crate.rotation = 10
physics.addBody( crate, { density=2.0,
friction=0.5, bounce=0.3 } )
end
timer.performWithDelay( 500, spawnCrate, 50 )
anscamobile.com
42. Take a Look at
“Corona is a ‘godsend’. My game runs at 1 fps (frame/sec)
in Flash but runs in full 30 fps in Corona.”
– Jeff Fulton, Flash Developer
anscamobile.com
43. • Test early and test often, ESPECIALLY ON A DEVICE
(or 20)
• Take time to understand dynamic image resolution
• Know what settings to include in your build.settings
file (think manifest)
• Know the limitations of the API you are using BEFORE
you start a project.
• MEMORY Matters in mobile, when is the last time you
even thought about it????
• Share what you learn!
anscamobile.com