45
anscamobile.com Corona SDK Code less. Play more. ®

Nate tech deck

Embed Size (px)

DESCRIPTION

Intro Cross Platform development using Corona SDK

Citation preview

Page 1: Nate tech deck

anscamobile.com

Corona SDK Code less. Play more.

®

Page 2: Nate tech deck

anscamobile.com

Corona SDK Code less. Play more.

®

Nate Ryan

Page 3: Nate tech deck
Page 4: Nate tech deck

anscamobile.com

@FullyCroisened@CoronaLabs

Page 5: Nate tech deck

anscamobile.com

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} )

Develop 10x faster

Publish to top stores

Write once

Monetize and distribute

Corona The ultimate

mobile platform

Available on

Page 6: Nate tech deck

anscamobile.com

Developers Like YouIndies + Game Studios + Publishers + Agencies

#1 #1

Page 7: Nate tech deck

anscamobile.com

Page 8: Nate tech deck

anscamobile.com

What is Corona?

same code, multiple stores

develop 5-10x faster

SDK for native apps

...

Page 9: Nate tech deck

anscamobile.com

Page 10: Nate tech deck

anscamobile.com

Lua: An Industry Standard

Page 11: Nate tech deck

anscamobile.com

Roberto Lerusalimschy one of the original Lua

founders (1993) now sits on the advisory board

with Corona Labs.

Page 12: Nate tech deck

anscamobile.com

• 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

Page 13: Nate tech deck

anscamobile.com

Other Languages –> Luaif (!carMoving) { // do something } else if (noGas) { // something else } for (i=1; i<=10; i++) { print(i) } for (j=100; j>0; j--) { print(j) }

if (not carMoving) then -- do something elseif (noGas) then -- something else end for i = 1,10 do print(i) end for j = 100,1,-1 do print(j) end

Page 14: Nate tech deck

anscamobile.com

Lua Objects are TablesmyTable = { "a", "b", 100, "hello" }

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

Page 15: Nate tech deck

anscamobile.com

• [[-- Comments --]]

• x,y = y,x (multiple assignments)

• ~= (non equality)

• 1 based indexing

• no classes, OO implemented with tables and functions

• Inheritance Implemented with metatable

Page 16: Nate tech deck

anscamobile.com

WebKit browser vie

ws

SQLite databas

e

File read/write

Full Lua scr

ipting langua

ge

Hardware-accelerat

ed graphics

GPS, compass, a

ccelerometer

Simple and complex ph

ysical bodies

Networking (TCP, FTP, HTTP, etc.)

Video playback (strea

ming or local)

Physical prop

erties (mass, fr

iction, boun

ce)

Joints, wheels,

hinges, pulle

ys, etc.

Animated sprites with ind

ependent framerates

per sprite seq

uence

Collision detectio

n, including pre

- and post-collisio

n events

OpenFeint gam

e network suppo

rt

Vector drawing APIs (sh

apes and lines)

Native UI (ke

yboard, etc.)

Crypto (md4, md5, sha1

, sha512, etc.)

Audio (sound effect

s or MP3)

Animation and transi

tion libraries

Facebook and Twitter li

braries

Improved textur

e memory handling

2D physics si

mulation

Camera and photo

library

Tons of Features/APIs

<html5>•Content scaling

•Multi-resolution images

•Simulator (instant refresh)

•Cloud services

Page 17: Nate tech deck

anscamobile.com

Small Code Size

1.4 MB Footprint

Page 18: Nate tech deck

anscamobile.com

Develop 5-10x faster

36 hours code+graphics

+sound (complete 2 level

14 hours code+graphics

+sound (gameplay only)

“Angry Birds” “Fruit Ninja” “Tiny Wings”

12 hours code+graphics

+sound (gameplay only)

“Developing directly in Xcode would have been at least 5x more code than Corona”

– Unicorn Labs, Top 20 iPad eBook

Page 19: Nate tech deck

anscamobile.com

• build.settings (ie manifest settings, permissions, etc)

• config.lua. (Corona instructions)

• Main.lua

Page 20: Nate tech deck

anscamobile.com

Page 21: Nate tech deck

anscamobile.com

Page 22: Nate tech deck

anscamobile.com

Hard Problems Made Easy

(i.e., how Corona will teach you to love physics)

Page 23: Nate tech deck

anscamobile.com

OpenGL in one linePhone SDK. // Display "myImage.png" // ---------------------------------------------------------------------------- // OpenGLESTextureAppDelegate.m // ---------------------------------------------------------------------------- #import "OpenGLESTextureAppDelegate.h" #import "EAGLView.h" #import "OpenGLESTextureViewController.h" @implementation OpenGLESTextureAppDelegate @synthesize window=_window; @synthesize viewController=_viewController; - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. self.window.rootViewController = self.viewController; return YES; } - (void)applicationDidBecomeActive:(UIApplication *)application { /* Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. */ [self.viewController drawFrame]; } - (void)dealloc { [_window release]; [_viewController release]; [super dealloc]; } @end // ---------------------------------------------------------------------------- // EAGLView.m // ---------------------------------------------------------------------------- #import <QuartzCore/QuartzCore.h> #import "EAGLView.h" @interface EAGLView (PrivateMethods) - (void)createFramebuffer; - (void)deleteFramebuffer; @end @implementation EAGLView @synthesize context; // You must implement this method + (Class)layerClass { return [CAEAGLLayer class]; } //The EAGL view is stored in the nib file. When it's unarchived it's sent -initWithCoder:. - (id)initWithCoder:(NSCoder*)coder { self = [super initWithCoder:coder]; if (self) { CAEAGLLayer *eaglLayer = (CAEAGLLayer *)self.layer; eaglLayer.opaque = TRUE; eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:FALSE], kEAGLDrawablePropertyRetainedBacking, kEAGLColorFormatRGBA8, kEAGLDrawablePropertyColorFormat, nil]; } return self; } - (void)dealloc { [self deleteFramebuffer]; [context release]; [super dealloc]; } - (void)setContext:(EAGLContext *)newContext { if (context != newContext) { [self deleteFramebuffer]; [context release]; context = [newContext retain]; [EAGLContext setCurrentContext:nil]; } } - (void)createFramebuffer { if (context && !defaultFramebuffer) {

[EAGLContext setCurrentContext:context]; // Create default framebuffer object. glGenFramebuffers(1, &defaultFramebuffer); glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer); // Create color render buffer and allocate backing store. glGenRenderbuffers(1, &colorRenderbuffer); glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer); [context renderbufferStorage:GL_RENDERBUFFER fromDrawable:(CAEAGLLayer *)self.layer]; glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &framebufferWidth); glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &framebufferHeight); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, colorRenderbuffer); if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER)); } } - (void)deleteFramebuffer { if (context) { [EAGLContext setCurrentContext:context]; if (defaultFramebuffer) { glDeleteFramebuffers(1, &defaultFramebuffer); defaultFramebuffer = 0; } if (colorRenderbuffer) { glDeleteRenderbuffers(1, &colorRenderbuffer); colorRenderbuffer = 0; } } } - (void)setFramebuffer { if (context) { [EAGLContext setCurrentContext:context]; if (!defaultFramebuffer) [self createFramebuffer]; glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer); glViewport(0, 0, framebufferWidth, framebufferHeight); } } - (BOOL)presentFramebuffer { BOOL success = FALSE; if (context) { [EAGLContext setCurrentContext:context]; glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer); success = [context presentRenderbuffer:GL_RENDERBUFFER]; } return success; } - (void)layoutSubviews { // The framebuffer will be re-created at the beginning of the next setFramebuffer method call. [self deleteFramebuffer]; } @end // ---------------------------------------------------------------------------- // OpenGLESTextureViewController.m // ---------------------------------------------------------------------------- #import <QuartzCore/QuartzCore.h> #import "OpenGLESTextureViewController.h" #import "EAGLView.h" @interface OpenGLESTextureViewController () @property (nonatomic, retain) EAGLContext *context; @property (nonatomic, assign) CADisplayLink *displayLink; - (void) loadTexture; @end @implementation OpenGLESTextureViewController @synthesize animating, context, displayLink; - (void)awakeFromNib { EAGLContext *aContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES1]; if (!aContext) NSLog(@"Failed to create ES context"); else if (![EAGLContext setCurrentContext:aContext]) NSLog(@"Failed to set ES context current"); self.context = aContext;

[aContext release]; [(EAGLView *)self.view setContext:context]; [(EAGLView *)self.view setFramebuffer]; [self loadTexture]; self.displayLink = nil; } - (void) loadTexture { glEnable(GL_TEXTURE_2D); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glGenTextures(1, &textureID); glBindTexture(GL_TEXTURE_2D, textureID); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); NSString *path = [[NSBundle mainBundle] pathForResource:@"myImage" ofType:@"png"]; NSData *texData = [[NSData alloc] initWithContentsOfFile:path]; UIImage *image = [[UIImage alloc] initWithData:texData]; GLuint width = CGImageGetWidth(image.CGImage); GLuint height = CGImageGetHeight(image.CGImage); CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); void *imageData = malloc( height width 4 ); CGContextRef image_context = CGBitmapContextCreate( imageData, width, height, 8, 4 width, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big ); CGColorSpaceRelease( colorSpace ); CGContextClearRect( image_context, CGRectMake( 0, 0, width, height ) ); CGContextTranslateCTM( image_context, 0, height - height ); CGContextDrawImage( image_context, CGRectMake( 0, 0, width, height ), image.CGImage ); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, imageData); CGContextRelease(image_context); free(imageData); [image release]; [texData release]; } - (void)dealloc { glDeleteTextures(1, &textureID); // Tear down context. if ([EAGLContext currentContext] == context) [EAGLContext setCurrentContext:nil]; [context release]; [super dealloc]; } - (void)viewDidUnload { [super viewDidUnload]; // Tear down context. if ([EAGLContext currentContext] == context) [EAGLContext setCurrentContext:nil]; self.context = nil; } - (void)drawFrame { [(EAGLView *)self.view setFramebuffer]; // Replace the implementation of this method to do your own custom drawing. static const GLfloat squareVertices[] = { -0.5f, -0.33f, 0.5f, -0.33f, -0.5f, 0.33f, 0.5f, 0.33f, }; static const GLfloat texCoords[] = { 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0 }; glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glVertexPointer(2, GL_FLOAT, 0, squareVertices); glEnableClientState(GL_VERTEX_ARRAY); glTexCoordPointer(2, GL_FLOAT, 0, texCoords); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); [(EAGLView *)self.view presentFramebuffer]; } @end

display.newImage("myImage.png")

Page 24: Nate tech deck

anscamobile.com

local sky = display.newImage( "clouds.png" )

Page 25: Nate tech deck

anscamobile.com

Page 26: Nate tech deck

anscamobile.com

local sky = display.newImage( "clouds.png" )

local ground = display.newImage( "ground.png" ) ground.x = 160 ground.y = 445

Page 27: Nate tech deck

anscamobile.com

Page 28: Nate tech deck

anscamobile.com

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

Page 29: Nate tech deck

anscamobile.com

Page 30: Nate tech deck

anscamobile.com

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

local physics = require( "physics" ) physics.start()

Page 31: Nate tech deck

anscamobile.com

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

local physics = require( "physics" ) physics.start()

physics.addBody( ground, { friction=0.5 } ) ground.bodyType = "static"

Page 32: Nate tech deck

anscamobile.com

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

local physics = require( "physics" ) physics.start()

physics.addBody( ground, { friction=0.5 } ) ground.bodyType = "static"

physics.addBody( crate, { density=2.0, friction=0.5, bounce=0.3 } )

Page 33: Nate tech deck

anscamobile.com

Page 34: Nate tech deck

anscamobile.com

What if we want lots of crates?

Page 35: Nate tech deck

anscamobile.com

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 } )

Page 36: Nate tech deck

anscamobile.com

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 )

Page 37: Nate tech deck

anscamobile.com

Page 38: Nate tech deck

anscamobile.com

What if gravity was up rather than down?

Page 39: Nate tech deck

anscamobile.com

physics.setGravity( 0, 9.8 )

Page 40: Nate tech deck

anscamobile.com

physics.setGravity( 0, -9.8 )

Page 41: Nate tech deck

anscamobile.com

Page 42: Nate tech deck

anscamobile.com

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

Page 43: Nate tech deck

anscamobile.com

• 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!

Page 44: Nate tech deck

anscamobile.com

What Questions do you have?

Page 45: Nate tech deck

anscamobile.com

www.fullycroisened.com

www.coronalabs.com

www.techority.com

www.learningcorona.com