Upload
fitc
View
475
Download
0
Tags:
Embed Size (px)
DESCRIPTION
Apps are the hottest new medium for interaction. But conventional technologies make creating graphically-rich, interactive content an enormous challenge. Learn how Corona SDK enables you to build apps 10x more quickly, whether you are a creative coder or a visual designer.
Citation preview
coronalabs.com@walterluh
CoronaBuilding Native AppsA digital canvas for everyone
®
NBC/Universal powers their campaign with Corona
coronalabs.com@walterluh
Turning an idea into something real
+ + =
Software DevelopmentCreative
coronalabs.com@walterluh
Graphics
Yesterday Today Tomorrow
coronalabs.com@walterluh
Mobile GraphicsCirca 2005
coronalabs.com@walterluh
Mobile GraphicsCirca 2008
coronalabs.com@walterluh
What is Corona?
same code, multiple stores
develop 5-10x faster
SDK for native apps
...
coronalabs.com@walterluh
Breakthrough Productivity
36 hourscode+graphics+sound(complete 2 level game)
14 hourscode+graphics+sound
(gameplay only)
“Angry Birds” “Fruit Ninja” “Tiny Wings”
12 hourscode+graphics+sound
(gameplay only)
“Developing directly in Xcode would have been at least 5x more code than Corona”
– Unicorn Labs, Top 20 iPad eBook
Ship #1 apps 10x faster
coronalabs.com@walterluh
Not Just for Games
ESP Guitars CheeseMonger Planet Sushi Thai Cook
Visually stunning business apps
coronalabs.com@walterluh
Performance
Simplicity
Flexibility
Corona
The Sweet Spot
Staff Pick
coronalabs.com@walterluh
Corona GraphicsOptimized OpenGL for 2-D
CONFIDENTIALcoronalabs.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")
coronalabs.com@walterluh
API for Designers
local image = display.newImage("myImage.png")
-- Propertiesimage.x = 100image.y = 100image.rotation = 45image.blendMode = "add"
-- Tweentransition.to( image, { alpha = 0.0 } )
coronalabs.com@walterluh
Intuitive Draw Order
Drawing Order Result
coronalabs.com@walterluh
Next-Generation GraphicsNew 2.5D engine later this year!
coronalabs.com@walterluh
CoronaRendering Engine
Virtual Machine
UserInputNetworking
Device
Device/OS
Native Mobile App
TextStrokesFills
BitmapsShapes
Objects Behaviors Dynamic Layout Events Device Capabilities Etc
Camera MicGPS Etc
Artwork Compiled Code Localized Strings Work"ow DeveloperAssets
User Interface
Architecture
coronalabs.com@walterluh
Lua: an industry standard
coronalabs.com@walterluh
Small Code Size
1.4 MB Footprint
coronalabs.com@walterluh
Lua types
nilbooleannumberstringfunctiontable
userdata
• JavaScript-like syntax• Functions are closures• Lexical scope (non-local vars)• Objects are tables
coronalabs.com@walterluh
Lua vs Other Languages
if (!carMoving) { // do something} else if (noGas) { // do something else}
for (i=1; i<=10; i++) { print(i)}
for (j=100; j>0; j-‐-‐) { print(j)}
if (not carMoving) then -‐-‐ do somethingelseif (noGas) then -‐-‐ do something elseend
for i = 1,10 do print(i)end
for j = 100,1,-‐1 do print(j)end
coronalabs.com@walterluh
array = { "a", "b", 100, "hello" }
dictionary = { x=5, y=7, name="Joe" }
t = {} -‐-‐ empty table
t[1] = "a" -‐-‐ numerical index
t["x"] = 5 -‐-‐ key index
t.x = 5 -‐-‐ equivalent property access
t.hasProperties = true
t[array] = "Joe" -‐-‐ any type can be a key!!!
t["printJoe"] = function() print("Joe") end
Lua objects are Tables
coronalabs.com@walterluh
-‐-‐ create empty tablelocal o = {}
-‐-‐ add methodfunction o:saySomething( something ) print( something )end
-‐-‐ output 'hi'o:saySomething( "hi!" )
Object methods
coronalabs.com@walterluh
-‐-‐ create empty tablelocal o = {}
-‐-‐ add methodlocal function f( self, something ) print( something )endo.saySomething = f
-‐-‐ output 'hi'o.saySomething( o, "hi!" )
The ':' is syntactic sugar
coronalabs.com@walterluh
Arrays are 1-based
// Other languages: index begins with 0 array=['a','b','c'];for ( var i=0; i<arr.length; i++) { log( array[i] )}
-‐-‐ Lua: index begins with 1local array = {'a','b','c'}
for i=1,#array do print( array[i] )end
coronalabs.com@walterluh
Corona Enterprise
• Integrate native libraries• Wrap native code in your own Lua APIs• Automate builds
Lua and Objective-C/C++ and Java
coronalabs.com@walterluh
Multiple Screen Sizes/Shapes
coronalabs.com@walterluh
Content Scaling in Corona
coronalabs.com@walterluh
Content Scaling
-‐-‐ config.luaapplication = { content = { width = 320, height = 480, scale = "letterbox", },}
• Code in content units (not screen pixels)• width/height specify content dimensions• Scale mode determines how physical display is #lled
coronalabs.com@walterluh
Retina Imaging in Corona
-‐-‐ config.luaapplication = { content = { width = 320, height = 480, scale = "letterbox",
imageSuffix = { ["-‐x15"] = 1.5, ["-‐x2"] = 2, }, },}
coronalabs.com@walterluh
Retina Imaging API
display.newImageRect( imageName, w, h )
• width/height in content units (not screen pixels)• Best matching image #le based on scale factor• Suffixes in con#g.lua determine image/scale mapping
coronalabs.com@walterluh
APIApplication Programming Interface Interaction
CONFIDENTIALcoronalabs.com
Hard Problems Made Easy(e.g. how Corona taught me to love physics)
CONFIDENTIALcoronalabs.com
local sky = display.newImage( "clouds.png" )
CONFIDENTIALcoronalabs.com
local sky = display.newImage( "clouds.png" )
local ground = display.newImage( "ground.png" )ground.x = 160ground.y = 445
CONFIDENTIALcoronalabs.com
local sky = display.newImage( "clouds.png" )
local ground = display.newImage( "ground.png" )ground.x = 160ground.y = 445
local crate = display.newImage( "crate.png" )crate.x = 180crate.y = 80crate.rotation = 10
CONFIDENTIALcoronalabs.com
local sky = display.newImage( "clouds.png" )
local ground = display.newImage( "ground.png" )ground.x = 160ground.y = 445
local crate = display.newImage( "crate.png" )crate.x = 180crate.y = 80crate.rotation = 10
local physics = require( "physics" )physics.start()
CONFIDENTIALcoronalabs.com
local sky = display.newImage( "clouds.png" )
local ground = display.newImage( "ground.png" )ground.x = 160ground.y = 445
local crate = display.newImage( "crate.png" )crate.x = 180crate.y = 80crate.rotation = 10
local physics = require( "physics" )physics.start()
physics.addBody( ground, { friction=0.5 } )ground.bodyType = "static"
CONFIDENTIALcoronalabs.com
local sky = display.newImage( "clouds.png" )
local ground = display.newImage( "ground.png" )ground.x = 160ground.y = 445
local crate = display.newImage( "crate.png" )crate.x = 180crate.y = 80crate.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 } )
CONFIDENTIALcoronalabs.com
What if we wantlots of crates?
CONFIDENTIALcoronalabs.com
local crate = display.newImage( "crate.png" )crate.x = 180crate.y = -100crate.rotation = 10physics.addBody( crate, { density=2.0,
friction=0.5, bounce=0.3 } )
CONFIDENTIALcoronalabs.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 )
CONFIDENTIALcoronalabs.com
What if gravity was up rather than down?
CONFIDENTIALcoronalabs.com
physics.setGravity( 0, 9.8 )
CONFIDENTIALcoronalabs.com
physics.setGravity( 0, -9.8 )
coronalabs.com@walterluh
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
<html5>
• OpenGL graphics• Open AL audio• Box2D Physics• Texture atlases, sprites, ...• Networking• GPS, multitouch, accelerometer, ...• Native web views, text#elds, ...• Camera, photo library, video, ...• Services: ads, analytics, IAP, ...• And much more!
coronalabs.com@walterluh
Amazing AppsWorld-class apps, developers, and community
coronalabs.com@walterluh
Thriving Ecosystem
CoronaFireworks
Photoshop Plugin
Zwoptex
TextMate
Particle Candy
Corona Remote
Corona Project Manager
Lime
Sprite Deck
LuaGlider
Texture Packer
coronalabs.com@walterluh
No Coding RequiredBuild native apps using Photoshop/Kwik
coronalabs.com@walterluh
Developers like you
#1 #1
From Designers to Coders. From Indies to Studios.
coronalabs.com@walterluh
Anyone can be #1... with Corona
coronalabs.com@walterluh
Start today! it’s free
www.CoronaLabs.com