SlideShare une entreprise Scribd logo
1  sur  89
Télécharger pour lire hors ligne
Corona    ®




   Code Less. Play More.




                           NBC/Universal powers their campaign with Corona

AMBASSADOR                                                     coronalabs.com
Street Cred




AMBASSADOR                 coronalabs.com
AMBASSADOR   coronalabs.com
AMBASSADOR   coronalabs.com
Cr eative Software Development
                   Turning an idea into something real




              +                  +                       =




AMBASSADOR                                                   coronalabs.com
AMBASSADOR   coronalabs.com
AMBASSADOR   coronalabs.com
What is Corona?
               SDK for native apps
                                           ...
                develop 5-10x faster




             same code, multiple stores




AMBASSADOR                                coronalabs.com
Breakthrough Productivity
                                       Ship #1 apps 10x faster

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




            36 hours                          14 hours                           12 hours
       code+graphics+sound              code+graphics+sound                code+graphics+sound
      (complete 2 level game)              (gameplay only)                    (gameplay only)


                                “Developing directly in Xcode would have
                                been at least 5x more code than Corona”
                                   – Unicorn Labs, Top 20 iPad eBook

AMBASSADOR                                                                           coronalabs.com
AMBASSADOR   coronalabs.com
High Performance




             “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
AMBASSADOR                                                               coronalabs.com
#1 on all Major Markets
                 iOS and Android and Amazon




CONFIDENTIAL
AMBASSADOR                                    anscamobile.com
                                               coronalabs.com
Developers like you
             From Designers to Coders. From Indies to Studios.




                                                           #1             #1




AMBASSADOR                                                       coronalabs.com
Not just for games




                                   HTML5 + OpenGL



   Cross-device/Skinnable UI                        Branded Apps
AMBASSADOR                                                coronalabs.com
Business Apps




             ESP Guitars   CheeseMonger   Planet Sushi   Thai Cook



AMBASSADOR                                                    coronalabs.com
The Sweet Spot
                                Simplicity




                            Corona
             Performance
                                                     Staff Pick

                                      Flexibility


AMBASSADOR                                          coronalabs.com
Architecture
                                      Native Mobile App
                                                                                        Developer
             Artwork User Interface Compiled Code Localized Strings Workflow
                                                                                        Assets

                                    Virtual Machine
         Objects    Behaviors   Dynamic Layout   Events   Device Capabilities     Etc
                                                                                        Corona
             Rendering Engine             Device
                                                                                 User
             Shapes Fills Strokes       Camera Mic        Networking
                                                                                Input
                Bitmaps Text              GPS Etc


                                            Device/OS

AMBASSADOR                                                                              coronalabs.com
Lua: an industry standard




AMBASSADOR                               coronalabs.com
Small Code Size


               1.4 MB
               Footprint




AMBASSADOR                     coronalabs.com
Lua types

                                              nil
                                           boolean
      • JavaScript-like syntax
                                            number
      • Functions are closures              string
      • Lexical scope (non-local vars)    function
      • Objects are tables                   table
                                          userdata


AMBASSADOR                                       coronalabs.com
Lua objects are Tables
             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
AMBASSADOR                                                                                               coronalabs.com
Lua vs Other Languages
if	
  (not	
  carMoving)	
  then         if	
  (!carMoving)	
  {
	
   -­‐-­‐	
  do	
  something           	
   //	
  do	
  something
elseif	
  (noGas)	
  then                }	
  else	
  if	
  (noGas)	
  {
	
   -­‐-­‐	
  do	
  something	
  else   	
   //	
  do	
  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                                      }

AMBASSADOR                                                          coronalabs.com
Lua is 1-based
             -­‐-­‐	
  Lua:	
  index	
  begins	
  with	
  1
             local	
  array	
  =	
  {'a','b','c'}

             for	
  i=1,#array	
  do
             	
  	
  print(	
  array[i]	
  )
             end


         //	
  Other	
  languages:	
  index	
  begins	
  with	
  0	
  
         array=['a','b','c'];
         for	
  (	
  var	
  i=0;	
  i<arr.length;	
  i++)	
  {
         	
  	
  log(	
  array[i]	
  )
         }
AMBASSADOR                                                       coronalabs.com
Corona Enterprise
                    Lua and Objective-C/C++ and Java




             • Integrate native libraries
             • Wrap native code in your own Lua APIs
             • Automate builds
AMBASSADOR                                             coronalabs.com
API
             Application Programming Interface Interaction




AMBASSADOR                                                   coronalabs.com
Over 500 APIs




AMBASSADOR                   coronalabs.com
W e bK         tabas
                                                       e
                                       e da
                               S Q Li t         write                     uage
  Tons of Features              File
                                        read
                                               /
                                            a scr
                                                     i p t in g lan
                                                                   e
                                                                        g
                                                                     d gr
                                                                             a p hics
                                     ll Lu                 lerat                    r
                                 Fu             - acce                   o mete                   s
                                         ware                   celer                     o d ie
  • OpenGL graphics               Hard
                                   GP   S, c o mpa
                                                       ss, a
                                                        co m
                                                               c
                                                               ple  x p hy
                                                                              sical
                                                                                      ,
                                                                                        b
                                                                                         etc.)
                                               and                            HTTP                   )
  • Open AL audio                   S impl
                                            e
                                            o rk  ing (
                                                           T  CP, F
                                                                       TP,
                                                                     tre  amin
                                                                                  <html5>
                                                                                   g  or l   ocal
                                                                                            tion,
                                     Netw                         (s               , f r ic
  • Box2D Physics                     Vi d eo   playb
                                                       r
                                                          ack
                                                         oper
                                                                 t ie s  (mas
                                                                                p
                                                                                  s
                                                                                  ulley
                                                                                          s, etc
                                                                                                   .
                                               cal p                    ges,                  dent
  • Texture atlases, sprites, ...      Phys
                                             i
                                              ts,  whee
                                                             ls, hi
                                                                    s
                                                                     n
                                                                        w i t h in
                                                                                     de p e
                                                                                            n
                                                                                             g pre
                                        Jo in               prite                    lu d i
                                                                                            n
  • Networking                           An im  ate d
                                                       n
                                                          s
                                                           dete
                                                                   c t io n, in
                                                                                 o
                                                                                   c
                                                                                   rk su
                                                                                            ppor
                                                                                                    t
                                               lisio                    netw                s an
                                                                                                    d
  • GPS, multitouch, accelerometer, ...  Co
                                          Ope
                                             l
                                                nFei
                                                        nt    gam   e
                                                                        A PIs (
                                                                                   shap
                                                                                          e

                                                          ra  w ing                etc.)
  • Native web views, textfields, ...      Ve  ctor
                                                        d
                                                           I  (keyb
                                                                        oard
                                                                                ,
                                                                             5, sh
                                                                                     a 1, s h
                                                                                              a512
                                                                                                       ,

                                            Nati  ve U              , md                   MP3)
  • Camera, photo library, video, ...        Cr yp
                                                     to   (md4
                                                                    d eff
                                                                              e cts o
                                                                                        r
                                                                                           n  l i b ra
                                                          (so un                    sitio
  • Services: ads, analytics, IAP, ...        A u d io
                                                          t io n a
                                                                     n  d t ra
                                                                           Tw itt
                                                                                  n
                                                                                    er li
                                                                                           b rarie
                                                                                                      s

                                               A n i ma                 d                     y ha
                                                                                                      n
  • And much more!                              F aceb
                                                          o  ok a
                                                              e d tex
                                                                     n
                                                                         t ure m
                                                                                      emor
                                                                                      n
                                                      pro v                   latio
                                                Im
                                                               ics    simu coronalabs.com y
                                                                                        ibrar
                                                        p hys                  oto l
AMBASSADOR
AMBASSADOR   coronalabs.com
AMBASSADOR   coronalabs.com
Demo




AMBASSADOR          coronalabs.com
Hard Problems Made Easy
                 (e.g. how Corona taught me to love physics)




coronalabs.com
 CONFIDENTIAL
OpenGL in one line
    Phone SDK.                                                                                               [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");


coronalabs.com
 CONFIDENTIAL
    - (void)createFramebuffer
    {
        if (context && !defaultFramebuffer) {
                                                                                                         else if (![EAGLContext setCurrentContext:aContext])
                                                                                                             NSLog(@"Failed to set ES context current");

                                                                                                         self.context = aContext;
                                                                                                                                                                                              }

                                                                                                                                                                                              @end
                                                                                                                                                                                                     [(EAGLView *)self.view presentFramebuffer];
local sky = display.newImage( "clouds.png" )




coronalabs.com
 CONFIDENTIAL
coronalabs.com
 CONFIDENTIAL
local sky = display.newImage( "clouds.png" )


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




coronalabs.com
 CONFIDENTIAL
coronalabs.com
 CONFIDENTIAL
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




coronalabs.com
 CONFIDENTIAL
coronalabs.com
 CONFIDENTIAL
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



coronalabs.com
 CONFIDENTIAL
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



coronalabs.com
 CONFIDENTIAL
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,
coronalabs.com
 CONFIDENTIAL
              friction=0.5, bounce=0.3 } )
coronalabs.com
 CONFIDENTIAL
What if we want
                 lots of crates?



coronalabs.com
 CONFIDENTIAL
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 } )




coronalabs.com
 CONFIDENTIAL
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 )




coronalabs.com
 CONFIDENTIAL
coronalabs.com
 CONFIDENTIAL
What if gravity was up
        rather than down?



coronalabs.com
 CONFIDENTIAL
physics.setGravity( 0, 9.8 )




coronalabs.com
 CONFIDENTIAL
physics.setGravity( 0, -9.8 )




coronalabs.com
 CONFIDENTIAL
coronalabs.com
 CONFIDENTIAL
Events

   • UI
   • Buttons
   • Animation
   • Timers
   • System




AMBASSADOR                coronalabs.com
Listeners
 local	
  listener	
  =	
  function(event)
 	
  	
  	
  print(	
  event.name,	
  event.time	
  )
 end

 Runtime:addEventListener("enterFrame",	
  listener)




AMBASSADOR                                              coronalabs.com
Event Types
   • enterFrame
   • system
   • orientation
   • accelerometer
   • GPS
   • heading
   • touch
   • timer
   • ...
AMBASSADOR                         coronalabs.com
Touch + Multitouch
    Properties:
    • x, y
    • xStart, yStart
    • phase
    • id
    • time


             object:addEventListener("touch",	
  listener)
AMBASSADOR                                          coronalabs.com
Let’s build a game on the fly!




coronalabs.com
 CONFIDENTIAL
www.coronalabs.com/gmic/pong.zip




AMBASSADOR                         coronalabs.com
Pong-Lesson 1
                       Basic Animation




  transition.to(ball,	
  {time=1000,x=440,y=300}	
  )




AMBASSADOR                                     coronalabs.com
Pong-Lesson 2
                      Make paddles respond to touches


  system.activate(	
  "multitouch"	
  )

  local	
  function	
  startDrag(	
  event	
  )
  	
  	
  -­‐-­‐	
  do	
  something
  end

  paddle1:addEventListener(	
  "touch",	
  startDrag	
  )
  paddle2:addEventListener(	
  "touch",	
  startDrag	
  )




AMBASSADOR                                              coronalabs.com
Pong-Lesson 2
  local	
  function	
  startDrag(	
  event	
  )
  	
  	
  local	
  t	
  =	
  event.target
  	
  	
  local	
  phase	
  =	
  event.phase

  	
   if	
  "began"	
  ==	
  phase	
  then
  	
   	
   display.getCurrentStage():setFocus(	
  t,	
  
  event.id	
  )
  	
   	
   t.isFocus	
  =	
  true

  	
   	
   -­‐-­‐	
  Store	
  initial	
  position
  	
   	
   t.x0	
  =	
  event.x	
  -­‐	
  t.x
  	
   	
   t.y0	
  =	
  event.y	
  -­‐	
  t.y
  ...

AMBASSADOR                                            coronalabs.com
Pong-Lesson 2
...
	
   elseif	
  t.isFocus	
  then
	
   	
   if	
  "moved"	
  ==	
  phase	
  then
	
   	
   	
   if	
  (	
  event.y	
  -­‐	
  t.y0	
  >	
  20	
  )
	
   	
   	
   	
   	
   	
   and	
  (	
  event.y	
  -­‐	
  t.y0	
  <	
  _H-­‐20	
  )	
  then	
  
	
   	
   	
   	
   t.y	
  =	
  event.y	
  -­‐	
  t.y0
	
   	
   	
   end
	
   	
   elseif	
  "ended"==phase	
  or	
  "cancelled"==	
  phase	
  then
	
   	
   	
   display.getCurrentStage():setFocus(	
  nil	
  )
	
   	
   	
   t.isFocus	
  =	
  false
	
   	
   end
	
   end

	
   return	
  true
end
AMBASSADOR                                                                       coronalabs.com
Pong-Lesson 3
                       Animate ball with physics

  local	
  physics	
  =	
  require("physics")
  physics.start()
  physics.setGravity(	
  0,	
  0	
  )




AMBASSADOR                                         coronalabs.com
Pong-Lesson 3
   local	
  function	
  newBall()
   	
   ball	
  =	
  display.newImage(	
  "puck_yellow.png"	
  )
   	
   ball.x	
  =	
  _W/2	
   	
   -­‐-­‐	
  center	
  it
   	
   ball.y	
  =	
  _H/2
   	
   ball:scale(	
  0.2,	
  0.2	
  )

  	
   physics.addBody(	
  ball,
  	
   	
   {density=0.3,friction=0.6,radius=radius}	
  )

  	
   xVelocity	
  =	
  velocity
  	
   yVelocity	
  =	
  0

  	
   ball:setLinearVelocity(xVelocity,	
  yVelocity)
   end
AMBASSADOR                                              coronalabs.com
Pong-Lesson 4
                         Balls should bounce on paddles

  physics.addBody(
  	
  	
  paddle1,	
  {	
  density=0.3,	
  friction=0.6	
  }	
  )
  paddle1.isFixedRotation	
  =	
  true
  paddle1.isPlatform	
  =	
  true
  paddle1.bodyType	
  =	
  "kinematic"

  physics.addBody(
  	
  	
  paddle2,	
  {	
  density=0.3,	
  friction=0.6	
  }	
  )
  paddle2.isFixedRotation	
  =	
  true
  paddle2.isPlatform	
  =	
  true
  paddle2.bodyType	
  =	
  "kinematic"

AMBASSADOR                                                    coronalabs.com
Pong-Lesson 5
                Paddles can change ball angle. Eliminate friction.


  local	
  function	
  paddleCollision(	
  self,	
  event	
  )
  	
  	
  -­‐-­‐	
  do	
  something
  end

  paddle1.collision	
  =	
  paddleCollision
  paddle1:addEventListener("collision",	
  paddle1)

  paddle2.collision	
  =	
  paddleCollision
  paddle2:addEventListener("collision",	
  paddle2)



AMBASSADOR                                                           coronalabs.com
Pong-Lesson 5
  local	
  function	
  paddleCollision(	
  self,	
  event	
  
  	
   if(	
  event.phase	
  ==	
  "began"	
  )	
  then
  	
   	
   local	
  offset	
  =	
  self.y	
  -­‐	
  event.other.y
  	
   	
   local	
  totalSize	
  =	
  (radius+paddleHeight)/2
  	
   	
   local	
  percent	
  =	
  math.abs(offset/totalSize)
  	
   	
   xVelocity	
  =	
  xVelocity	
  *	
  -­‐1
  	
   	
   if	
  offset	
  >	
  0	
  then
  	
   	
   	
   yVelocity	
  =	
  (velocity*percent)	
  *	
  -­‐1
  	
   	
   else
  	
   	
   	
   yVelocity	
  =	
  (velocity*percent)
  	
   	
   end
  	
   	
   	
   	
  
  	
   	
   ball:setLinearVelocity(xVelocity,yVelocity)
  	
   end
  end
AMBASSADOR                                               coronalabs.com
Pong-Lesson 6
                  Ball should bounce at edges of screen


  local	
  leftWall	
  =	
  display.newRect(10,0,2,_H)
  physics.addBody(	
  leftWall	
  )
  leftWall.bodyType	
  =	
  "kinematic"
  leftWall.myName	
  =	
  "leftWall"

  local	
  rightWall	
  =	
  display.newRect(470,0,2,_H)
  physics.addBody(	
  rightWall	
  )
  rightWall.bodyType	
  =	
  "kinematic"
  rightWall.myName	
  =	
  "rightWall"



AMBASSADOR                                                coronalabs.com
Pong-Lesson 6


  local	
  topWall	
  =	
  display.newRect(0,0,_W,2)
  physics.addBody(	
  topWall	
  )
  topWall.bodyType	
  =	
  "kinematic"

  local	
  bottomWall	
  =	
  display.newRect(0,_H-­‐2,_W,2)
  physics.addBody(	
  bottomWall	
  )
  bottomWall.bodyType	
  =	
  "kinematic"




AMBASSADOR                                         coronalabs.com
Pong-Lesson 7
             Maintain ball’s velocity after bouncing off top/bottom walls

  local	
  function	
  onCollide(	
  event	
  )
  	
   if(	
  event.phase	
  ==	
  "began"	
  )	
  then
  	
   	
   yVelocity	
  =	
  yVelocity	
  *	
  -­‐1
  	
   	
   ball:setLinearVelocity(xVelocity,yVelocity)
  	
   	
   return	
  true
  	
   end
  end

  topWall:addEventListener("collision",onCollide)
  bottomWall:addEventListener("collision",onCollide)



AMBASSADOR                                                                 coronalabs.com
Pong-Lesson 8
                         Detect when ball gets past the paddle
  local	
  function	
  onSideCollision(	
  event	
  )
  	
   if	
  (	
  event.phase	
  ==	
  "began"	
  )	
  then
  	
   	
   timer.performWithDelay(	
  33,	
  removeBall	
  )
  	
   	
   timer.performWithDelay(	
  1000,	
  newBall	
  )
  	
   end
  	
   return	
  true	
  
  end

  leftWall:addEventListener(
  	
   	
   	
   	
   	
   	
   	
   "collision",	
  onSideCollision	
  )

  rightWall:addEventListener(
  	
   	
   	
   	
   	
   	
   	
   "collision",	
  onSideCollision	
  )
AMBASSADOR                                                           coronalabs.com
Multiple Screen Sizes/Shapes




AMBASSADOR                                  coronalabs.com
Content Scaling in Corona




AMBASSADOR                               coronalabs.com
Content Scaling
                 -­‐-­‐	
  config.lua
                 application	
  =	
  {
                 	
  	
  	
  	
  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 filled
AMBASSADOR                                                                    coronalabs.com
Retina Displays




AMBASSADOR                     coronalabs.com
Retina Imaging in Corona
             -­‐-­‐	
  config.lua
             application	
  =	
  {
             	
  	
  	
  	
  content	
  =	
  {
             	
  	
  	
  	
  	
  	
  	
  	
  width	
  =	
  320,
             	
  	
  	
  	
  	
  	
  	
  	
  height	
  =	
  480,
             	
  	
  	
  	
  	
  	
  	
  	
  scale	
  =	
  "letterbox",

             	
  	
  	
  	
  	
  	
  	
  	
  imageSuffix	
  =	
  {
             	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  ["-­‐x15"]	
  =	
  1.5,
             	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  	
  ["-­‐x2"]	
  =	
  2,
             	
  	
  	
  	
  	
  	
  	
  	
  },
             	
  	
  	
  	
  },
             }

AMBASSADOR                                                                             coronalabs.com
Retina Imaging API

             display.newImageRect(	
  imageName,	
  w,	
  h	
  )




        • width/height in content units (not screen pixels)
        • Best matching image file based on scale factor
        • Suffixes in config.lua determine image/scale mapping


AMBASSADOR                                                  coronalabs.com
Demo




AMBASSADOR          coronalabs.com
Platforms = Trust




AMBASSADOR                       coronalabs.com
The developer community loves Corona
     “In the past, we had to drop projects made in                   “I tried Obj-C but didn’t like the results. I found Gamesalad but
       cocos2D because it was much more time                      wasn’t pleased with it and made the jump to Corona. I was loving it.
      consuming. Corona is simple enough for an                   It gave me a lot more control and speed.” – Robert Nay, 14 year old
   artist or designer to code a feature themselves.”
     — Randy Shepherd, Cocos2d/Xbox developer                     “If you're serious about
                                                               developing apps and games but         “For movement and performance,
  “Corona performance                                           don't want to get into Obj-C/       Appcelerator Titanium really wasn’t
                              “Thank you for making
  is phenomenal! I love                                       Xcode, I don't think GameSalad is    an option. Corona really impressed me
                              Corona. I found it to be
      the power and                                            the right choice. I moved from        when I saw how easy it was to get
                               the perfect SDK for a
 flexibility. It allows me                                       using GameSalad to Corona,          graphics on to the screen and have
                             Flash developer like me.”
 to make better games!”                                         which is IMHO 100x better.”          them look great on the device.” –
                               – Ferry Halim, famed
     – Joe Kauffman,                                          – Jon Beebe, ex-GameSalad user             David Fox, web developer
                                Flash Developer and
     Flash developer,
                               Webby Award winner
   ex-GameSalad user                                          “With Corona I felt right at home immediately, feels like JavaScript. I’m not
                                                          sleeping because the development is so addicting!” —Angelo Yazar, Unity Developer
             “We were able to develop our
             first application with Corona
               in just a few days! Porting                                                           “We chose Corona because we’d get new
                                                            “Coming from Flash, it looked a
             apps from Flash to Corona is                                                          component functions out more rapidly than
                                                         little too simplistic at the beginning,
             quite easy and substantially                                                          via Cocoa Touch or Cocos2d. Supporting all
                                                          but Corona’s simplicity and ease of
              lowers development costs.”                                                           of the iOS devices was a lot more seamless
                                                          use doesn’t limit what you can do.”
                   – Bohumil Vosicky,                                                                for us than was the case with Cocos2d.”
                                                           – Ruben Frosali, Flash Developer
                  educational developer                                                                   — Mark Sigal, eBook publisher

       “I explored many options for new iPhone                  “Many people think that mobile development is difficult because of the
  developers and I have to say Corona just felt right.           different programming languages (Objective-C, Java, etc.) For those
  It was easy to pick up in a short time and powerful            people, Corona is probably the best solution — it’s accessible, simple,
    enough to enable really cool things to be done.”            powerful, and not a barrier to creativity.” – Julian Paté, web developer
          – Matt Pringle, designer for EA/3DO

AMBASSADOR                                                                                                               coronalabs.com
Award-winning Technology




                 Staff Pick




coronalabs.com
 CONFIDENTIAL
AMBASSADOR   coronalabs.com
Thriving Ecosystem
                                              Zwoptex



                           Particle Candy                   Texture Packer



             Sprite Deck                                                     Corona Project Manager


                                            Corona
             Photoshop                                                           Fireworks




                                                                             iAppHost


                           Lime                             TextMate
                                            Corona Remote
AMBASSADOR                                                                              coronalabs.com
Corona in Print!




AMBASSADOR                      coronalabs.com
Corona as a career
                Over 1000+ studios in 75 countries around the world




              “In what I hope is a good omen of things to come, this December
             I'm on track to earn substantially more money developing Corona-
              based apps for clients than I will at my (pretty well-paid) day job.
                2012 may just be the year I stop working for somebody else.”
                         – Jason Schroedere, designer for EA/3DO

AMBASSADOR                                                                           coronalabs.com
Is it fun?




       “What is so great about Corona is it is so easy to just write code and get things working.
       You immediately see your results on the screen.
       That is what was so great about Applesoft or Logo. But they were just toy graphic languages.
       Yours is first class.”
                                                                                     — Dave Lazarony,
                                                                                       Creator of ADM
                                                                              (Adobe’s UI Framework)
AMBASSADOR                                                                                  coronalabs.com
Anyone can be #1... with Corona




AMBASSADOR                                     coronalabs.com
Just for fun...




AMBASSADOR                     coronalabs.com
AMBASSADOR   coronalabs.com
AMBASSADOR   coronalabs.com
Get Corona free trial




             www.CoronaLabs.com

AMBASSADOR                               coronalabs.com

Contenu connexe

Similaire à Corona SDK at GMIC SV

Fast Track - Windows 8 Apps
Fast Track - Windows 8 AppsFast Track - Windows 8 Apps
Fast Track - Windows 8 AppsAnkit Kashyap
 
Battle of NoSQL stars: Amazon's SDB vs MongoDB vs CouchDB vs RavenDB
Battle of NoSQL stars: Amazon's SDB vs MongoDB vs CouchDB vs RavenDBBattle of NoSQL stars: Amazon's SDB vs MongoDB vs CouchDB vs RavenDB
Battle of NoSQL stars: Amazon's SDB vs MongoDB vs CouchDB vs RavenDBJesse Wolgamott
 
Torquebox rubyhoedown-2012
Torquebox rubyhoedown-2012Torquebox rubyhoedown-2012
Torquebox rubyhoedown-2012Lance Ball
 
Sharded By Business Line: Migrating to a Core Database using MongoDB and Solr
Sharded By Business Line: Migrating to a Core Database using MongoDB and SolrSharded By Business Line: Migrating to a Core Database using MongoDB and Solr
Sharded By Business Line: Migrating to a Core Database using MongoDB and SolrMongoDB
 
Mongo la search platform - january 2013
Mongo la   search platform - january 2013Mongo la   search platform - january 2013
Mongo la search platform - january 2013MongoDB
 
New Artificial Intelligence and IoT Services (Lex, Polly, Rekognition, Greeng...
New Artificial Intelligence and IoT Services (Lex, Polly, Rekognition, Greeng...New Artificial Intelligence and IoT Services (Lex, Polly, Rekognition, Greeng...
New Artificial Intelligence and IoT Services (Lex, Polly, Rekognition, Greeng...Amazon Web Services
 
Nolan Wright: Appcelerator's World-Class Ecosystem
Nolan Wright: Appcelerator's World-Class Ecosystem Nolan Wright: Appcelerator's World-Class Ecosystem
Nolan Wright: Appcelerator's World-Class Ecosystem Axway Appcelerator
 
Kamaelia lightning2010opensource
Kamaelia lightning2010opensourceKamaelia lightning2010opensource
Kamaelia lightning2010opensourcekamaelian
 
FOXX - a Javascript application framework on top of ArangoDB
FOXX - a Javascript application framework on top of ArangoDBFOXX - a Javascript application framework on top of ArangoDB
FOXX - a Javascript application framework on top of ArangoDBArangoDB Database
 
Games for the Masses (Jax)
Games for the Masses (Jax)Games for the Masses (Jax)
Games for the Masses (Jax)Wooga
 
Embracing concurrency for fun utility and simpler code
Embracing concurrency for fun utility and simpler codeEmbracing concurrency for fun utility and simpler code
Embracing concurrency for fun utility and simpler codekamaelian
 
Mono for Game Developers - AltDevConf 2012
Mono for Game Developers - AltDevConf 2012Mono for Game Developers - AltDevConf 2012
Mono for Game Developers - AltDevConf 2012Xamarin
 
Devoxx 2009: The Lift Framework
Devoxx 2009: The Lift FrameworkDevoxx 2009: The Lift Framework
Devoxx 2009: The Lift FrameworkTimothy Perrett
 
Bada familiar foundations
Bada  familiar foundationsBada  familiar foundations
Bada familiar foundationsjlansdell
 
ParisJS meetup 8 - june 2011
ParisJS meetup 8  - june 2011ParisJS meetup 8  - june 2011
ParisJS meetup 8 - june 2011Alexandre Morgaut
 
A Matrix Based Character Editor For Scratchpads
A Matrix Based Character Editor For ScratchpadsA Matrix Based Character Editor For Scratchpads
A Matrix Based Character Editor For ScratchpadsKehan Harman
 

Similaire à Corona SDK at GMIC SV (20)

Fast Track - Windows 8 Apps
Fast Track - Windows 8 AppsFast Track - Windows 8 Apps
Fast Track - Windows 8 Apps
 
Battle of NoSQL stars: Amazon's SDB vs MongoDB vs CouchDB vs RavenDB
Battle of NoSQL stars: Amazon's SDB vs MongoDB vs CouchDB vs RavenDBBattle of NoSQL stars: Amazon's SDB vs MongoDB vs CouchDB vs RavenDB
Battle of NoSQL stars: Amazon's SDB vs MongoDB vs CouchDB vs RavenDB
 
Torquebox rubyhoedown-2012
Torquebox rubyhoedown-2012Torquebox rubyhoedown-2012
Torquebox rubyhoedown-2012
 
World of javascript
World of javascriptWorld of javascript
World of javascript
 
Sharded By Business Line: Migrating to a Core Database using MongoDB and Solr
Sharded By Business Line: Migrating to a Core Database using MongoDB and SolrSharded By Business Line: Migrating to a Core Database using MongoDB and Solr
Sharded By Business Line: Migrating to a Core Database using MongoDB and Solr
 
Mongo la search platform - january 2013
Mongo la   search platform - january 2013Mongo la   search platform - january 2013
Mongo la search platform - january 2013
 
New Artificial Intelligence and IoT Services (Lex, Polly, Rekognition, Greeng...
New Artificial Intelligence and IoT Services (Lex, Polly, Rekognition, Greeng...New Artificial Intelligence and IoT Services (Lex, Polly, Rekognition, Greeng...
New Artificial Intelligence and IoT Services (Lex, Polly, Rekognition, Greeng...
 
Nolan Wright: Appcelerator's World-Class Ecosystem
Nolan Wright: Appcelerator's World-Class Ecosystem Nolan Wright: Appcelerator's World-Class Ecosystem
Nolan Wright: Appcelerator's World-Class Ecosystem
 
Intro to java
Intro to javaIntro to java
Intro to java
 
Kamaelia lightning2010opensource
Kamaelia lightning2010opensourceKamaelia lightning2010opensource
Kamaelia lightning2010opensource
 
Layar @ SDForum 28 Feb 2011
Layar @ SDForum 28 Feb 2011Layar @ SDForum 28 Feb 2011
Layar @ SDForum 28 Feb 2011
 
FOXX - a Javascript application framework on top of ArangoDB
FOXX - a Javascript application framework on top of ArangoDBFOXX - a Javascript application framework on top of ArangoDB
FOXX - a Javascript application framework on top of ArangoDB
 
Droidcon - Unify Insights
Droidcon - Unify InsightsDroidcon - Unify Insights
Droidcon - Unify Insights
 
Games for the Masses (Jax)
Games for the Masses (Jax)Games for the Masses (Jax)
Games for the Masses (Jax)
 
Embracing concurrency for fun utility and simpler code
Embracing concurrency for fun utility and simpler codeEmbracing concurrency for fun utility and simpler code
Embracing concurrency for fun utility and simpler code
 
Mono for Game Developers - AltDevConf 2012
Mono for Game Developers - AltDevConf 2012Mono for Game Developers - AltDevConf 2012
Mono for Game Developers - AltDevConf 2012
 
Devoxx 2009: The Lift Framework
Devoxx 2009: The Lift FrameworkDevoxx 2009: The Lift Framework
Devoxx 2009: The Lift Framework
 
Bada familiar foundations
Bada  familiar foundationsBada  familiar foundations
Bada familiar foundations
 
ParisJS meetup 8 - june 2011
ParisJS meetup 8  - june 2011ParisJS meetup 8  - june 2011
ParisJS meetup 8 - june 2011
 
A Matrix Based Character Editor For Scratchpads
A Matrix Based Character Editor For ScratchpadsA Matrix Based Character Editor For Scratchpads
A Matrix Based Character Editor For Scratchpads
 

Corona SDK at GMIC SV

  • 1. Corona ® Code Less. Play More. NBC/Universal powers their campaign with Corona AMBASSADOR coronalabs.com
  • 2. Street Cred AMBASSADOR coronalabs.com
  • 3. AMBASSADOR coronalabs.com
  • 4. AMBASSADOR coronalabs.com
  • 5. Cr eative Software Development Turning an idea into something real + + = AMBASSADOR coronalabs.com
  • 6. AMBASSADOR coronalabs.com
  • 7. AMBASSADOR coronalabs.com
  • 8. What is Corona? SDK for native apps ... develop 5-10x faster same code, multiple stores AMBASSADOR coronalabs.com
  • 9. Breakthrough Productivity Ship #1 apps 10x faster “Angry Birds” “Fruit Ninja” “Tiny Wings” 36 hours 14 hours 12 hours code+graphics+sound code+graphics+sound code+graphics+sound (complete 2 level game) (gameplay only) (gameplay only) “Developing directly in Xcode would have been at least 5x more code than Corona” – Unicorn Labs, Top 20 iPad eBook AMBASSADOR coronalabs.com
  • 10. AMBASSADOR coronalabs.com
  • 11. High Performance “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 AMBASSADOR coronalabs.com
  • 12. #1 on all Major Markets iOS and Android and Amazon CONFIDENTIAL AMBASSADOR anscamobile.com coronalabs.com
  • 13. Developers like you From Designers to Coders. From Indies to Studios. #1 #1 AMBASSADOR coronalabs.com
  • 14. Not just for games HTML5 + OpenGL Cross-device/Skinnable UI Branded Apps AMBASSADOR coronalabs.com
  • 15. Business Apps ESP Guitars CheeseMonger Planet Sushi Thai Cook AMBASSADOR coronalabs.com
  • 16. The Sweet Spot Simplicity Corona Performance Staff Pick Flexibility AMBASSADOR coronalabs.com
  • 17. Architecture Native Mobile App Developer Artwork User Interface Compiled Code Localized Strings Workflow Assets Virtual Machine Objects Behaviors Dynamic Layout Events Device Capabilities Etc Corona Rendering Engine Device User Shapes Fills Strokes Camera Mic Networking Input Bitmaps Text GPS Etc Device/OS AMBASSADOR coronalabs.com
  • 18. Lua: an industry standard AMBASSADOR coronalabs.com
  • 19. Small Code Size 1.4 MB Footprint AMBASSADOR coronalabs.com
  • 20. Lua types nil boolean • JavaScript-like syntax number • Functions are closures string • Lexical scope (non-local vars) function • Objects are tables table userdata AMBASSADOR coronalabs.com
  • 21. Lua objects are Tables 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 AMBASSADOR coronalabs.com
  • 22. Lua vs Other Languages if  (not  carMoving)  then if  (!carMoving)  {   -­‐-­‐  do  something   //  do  something elseif  (noGas)  then }  else  if  (noGas)  {   -­‐-­‐  do  something  else   //  do  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 } AMBASSADOR coronalabs.com
  • 23. Lua is 1-based -­‐-­‐  Lua:  index  begins  with  1 local  array  =  {'a','b','c'} for  i=1,#array  do    print(  array[i]  ) end //  Other  languages:  index  begins  with  0   array=['a','b','c']; for  (  var  i=0;  i<arr.length;  i++)  {    log(  array[i]  ) } AMBASSADOR coronalabs.com
  • 24. Corona Enterprise Lua and Objective-C/C++ and Java • Integrate native libraries • Wrap native code in your own Lua APIs • Automate builds AMBASSADOR coronalabs.com
  • 25. API Application Programming Interface Interaction AMBASSADOR coronalabs.com
  • 26. Over 500 APIs AMBASSADOR coronalabs.com
  • 27. W e bK tabas e e da S Q Li t write uage Tons of Features File read / a scr i p t in g lan e g d gr a p hics ll Lu lerat r Fu - acce o mete s ware celer o d ie • OpenGL graphics Hard GP S, c o mpa ss, a co m c ple x p hy sical , b etc.) and HTTP ) • Open AL audio S impl e o rk ing ( T CP, F TP, tre amin <html5> g or l ocal tion, Netw (s , f r ic • Box2D Physics Vi d eo playb r ack oper t ie s (mas p s ulley s, etc . cal p ges, dent • Texture atlases, sprites, ... Phys i ts, whee ls, hi s n w i t h in de p e n g pre Jo in prite lu d i n • Networking An im ate d n s dete c t io n, in o c rk su ppor t lisio netw s an d • GPS, multitouch, accelerometer, ... Co Ope l nFei nt gam e A PIs ( shap e ra w ing etc.) • Native web views, textfields, ... Ve ctor d I (keyb oard , 5, sh a 1, s h a512 , Nati ve U , md MP3) • Camera, photo library, video, ... Cr yp to (md4 d eff e cts o r n l i b ra (so un sitio • Services: ads, analytics, IAP, ... A u d io t io n a n d t ra Tw itt n er li b rarie s A n i ma d y ha n • And much more! F aceb o ok a e d tex n t ure m emor n pro v latio Im ics simu coronalabs.com y ibrar p hys oto l AMBASSADOR
  • 28. AMBASSADOR coronalabs.com
  • 29. AMBASSADOR coronalabs.com
  • 30. Demo AMBASSADOR coronalabs.com
  • 31. Hard Problems Made Easy (e.g. how Corona taught me to love physics) coronalabs.com CONFIDENTIAL
  • 32. OpenGL in one line Phone SDK. [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"); coronalabs.com CONFIDENTIAL - (void)createFramebuffer { if (context && !defaultFramebuffer) { else if (![EAGLContext setCurrentContext:aContext]) NSLog(@"Failed to set ES context current"); self.context = aContext; } @end [(EAGLView *)self.view presentFramebuffer];
  • 33. local sky = display.newImage( "clouds.png" ) coronalabs.com CONFIDENTIAL
  • 35. local sky = display.newImage( "clouds.png" ) local ground = display.newImage( "ground.png" ) ground.x = 160 ground.y = 445 coronalabs.com CONFIDENTIAL
  • 37. 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 coronalabs.com CONFIDENTIAL
  • 39. 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 coronalabs.com CONFIDENTIAL
  • 40. 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 coronalabs.com CONFIDENTIAL
  • 41. 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, coronalabs.com CONFIDENTIAL friction=0.5, bounce=0.3 } )
  • 43. What if we want lots of crates? coronalabs.com CONFIDENTIAL
  • 44. 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 } ) coronalabs.com CONFIDENTIAL
  • 45. 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 ) coronalabs.com CONFIDENTIAL
  • 47. What if gravity was up rather than down? coronalabs.com CONFIDENTIAL
  • 48. physics.setGravity( 0, 9.8 ) coronalabs.com CONFIDENTIAL
  • 49. physics.setGravity( 0, -9.8 ) coronalabs.com CONFIDENTIAL
  • 51. Events • UI • Buttons • Animation • Timers • System AMBASSADOR coronalabs.com
  • 52. Listeners local  listener  =  function(event)      print(  event.name,  event.time  ) end Runtime:addEventListener("enterFrame",  listener) AMBASSADOR coronalabs.com
  • 53. Event Types • enterFrame • system • orientation • accelerometer • GPS • heading • touch • timer • ... AMBASSADOR coronalabs.com
  • 54. Touch + Multitouch Properties: • x, y • xStart, yStart • phase • id • time object:addEventListener("touch",  listener) AMBASSADOR coronalabs.com
  • 55. Let’s build a game on the fly! coronalabs.com CONFIDENTIAL
  • 57. Pong-Lesson 1 Basic Animation transition.to(ball,  {time=1000,x=440,y=300}  ) AMBASSADOR coronalabs.com
  • 58. Pong-Lesson 2 Make paddles respond to touches system.activate(  "multitouch"  ) local  function  startDrag(  event  )    -­‐-­‐  do  something end paddle1:addEventListener(  "touch",  startDrag  ) paddle2:addEventListener(  "touch",  startDrag  ) AMBASSADOR coronalabs.com
  • 59. Pong-Lesson 2 local  function  startDrag(  event  )    local  t  =  event.target    local  phase  =  event.phase   if  "began"  ==  phase  then     display.getCurrentStage():setFocus(  t,   event.id  )     t.isFocus  =  true     -­‐-­‐  Store  initial  position     t.x0  =  event.x  -­‐  t.x     t.y0  =  event.y  -­‐  t.y ... AMBASSADOR coronalabs.com
  • 60. Pong-Lesson 2 ...   elseif  t.isFocus  then     if  "moved"  ==  phase  then       if  (  event.y  -­‐  t.y0  >  20  )             and  (  event.y  -­‐  t.y0  <  _H-­‐20  )  then           t.y  =  event.y  -­‐  t.y0       end     elseif  "ended"==phase  or  "cancelled"==  phase  then       display.getCurrentStage():setFocus(  nil  )       t.isFocus  =  false     end   end   return  true end AMBASSADOR coronalabs.com
  • 61. Pong-Lesson 3 Animate ball with physics local  physics  =  require("physics") physics.start() physics.setGravity(  0,  0  ) AMBASSADOR coronalabs.com
  • 62. Pong-Lesson 3 local  function  newBall()   ball  =  display.newImage(  "puck_yellow.png"  )   ball.x  =  _W/2     -­‐-­‐  center  it   ball.y  =  _H/2   ball:scale(  0.2,  0.2  )   physics.addBody(  ball,     {density=0.3,friction=0.6,radius=radius}  )   xVelocity  =  velocity   yVelocity  =  0   ball:setLinearVelocity(xVelocity,  yVelocity) end AMBASSADOR coronalabs.com
  • 63. Pong-Lesson 4 Balls should bounce on paddles physics.addBody(    paddle1,  {  density=0.3,  friction=0.6  }  ) paddle1.isFixedRotation  =  true paddle1.isPlatform  =  true paddle1.bodyType  =  "kinematic" physics.addBody(    paddle2,  {  density=0.3,  friction=0.6  }  ) paddle2.isFixedRotation  =  true paddle2.isPlatform  =  true paddle2.bodyType  =  "kinematic" AMBASSADOR coronalabs.com
  • 64. Pong-Lesson 5 Paddles can change ball angle. Eliminate friction. local  function  paddleCollision(  self,  event  )    -­‐-­‐  do  something end paddle1.collision  =  paddleCollision paddle1:addEventListener("collision",  paddle1) paddle2.collision  =  paddleCollision paddle2:addEventListener("collision",  paddle2) AMBASSADOR coronalabs.com
  • 65. Pong-Lesson 5 local  function  paddleCollision(  self,  event     if(  event.phase  ==  "began"  )  then     local  offset  =  self.y  -­‐  event.other.y     local  totalSize  =  (radius+paddleHeight)/2     local  percent  =  math.abs(offset/totalSize)     xVelocity  =  xVelocity  *  -­‐1     if  offset  >  0  then       yVelocity  =  (velocity*percent)  *  -­‐1     else       yVelocity  =  (velocity*percent)     end             ball:setLinearVelocity(xVelocity,yVelocity)   end end AMBASSADOR coronalabs.com
  • 66. Pong-Lesson 6 Ball should bounce at edges of screen local  leftWall  =  display.newRect(10,0,2,_H) physics.addBody(  leftWall  ) leftWall.bodyType  =  "kinematic" leftWall.myName  =  "leftWall" local  rightWall  =  display.newRect(470,0,2,_H) physics.addBody(  rightWall  ) rightWall.bodyType  =  "kinematic" rightWall.myName  =  "rightWall" AMBASSADOR coronalabs.com
  • 67. Pong-Lesson 6 local  topWall  =  display.newRect(0,0,_W,2) physics.addBody(  topWall  ) topWall.bodyType  =  "kinematic" local  bottomWall  =  display.newRect(0,_H-­‐2,_W,2) physics.addBody(  bottomWall  ) bottomWall.bodyType  =  "kinematic" AMBASSADOR coronalabs.com
  • 68. Pong-Lesson 7 Maintain ball’s velocity after bouncing off top/bottom walls local  function  onCollide(  event  )   if(  event.phase  ==  "began"  )  then     yVelocity  =  yVelocity  *  -­‐1     ball:setLinearVelocity(xVelocity,yVelocity)     return  true   end end topWall:addEventListener("collision",onCollide) bottomWall:addEventListener("collision",onCollide) AMBASSADOR coronalabs.com
  • 69. Pong-Lesson 8 Detect when ball gets past the paddle local  function  onSideCollision(  event  )   if  (  event.phase  ==  "began"  )  then     timer.performWithDelay(  33,  removeBall  )     timer.performWithDelay(  1000,  newBall  )   end   return  true   end leftWall:addEventListener(               "collision",  onSideCollision  ) rightWall:addEventListener(               "collision",  onSideCollision  ) AMBASSADOR coronalabs.com
  • 71. Content Scaling in Corona AMBASSADOR coronalabs.com
  • 72. Content Scaling -­‐-­‐  config.lua application  =  {        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 filled AMBASSADOR coronalabs.com
  • 73. Retina Displays AMBASSADOR coronalabs.com
  • 74. Retina Imaging in Corona -­‐-­‐  config.lua application  =  {        content  =  {                width  =  320,                height  =  480,                scale  =  "letterbox",                imageSuffix  =  {                        ["-­‐x15"]  =  1.5,                        ["-­‐x2"]  =  2,                },        }, } AMBASSADOR coronalabs.com
  • 75. Retina Imaging API display.newImageRect(  imageName,  w,  h  ) • width/height in content units (not screen pixels) • Best matching image file based on scale factor • Suffixes in config.lua determine image/scale mapping AMBASSADOR coronalabs.com
  • 76. Demo AMBASSADOR coronalabs.com
  • 78. The developer community loves Corona “In the past, we had to drop projects made in “I tried Obj-C but didn’t like the results. I found Gamesalad but cocos2D because it was much more time wasn’t pleased with it and made the jump to Corona. I was loving it. consuming. Corona is simple enough for an It gave me a lot more control and speed.” – Robert Nay, 14 year old artist or designer to code a feature themselves.” — Randy Shepherd, Cocos2d/Xbox developer “If you're serious about developing apps and games but “For movement and performance, “Corona performance don't want to get into Obj-C/ Appcelerator Titanium really wasn’t “Thank you for making is phenomenal! I love Xcode, I don't think GameSalad is an option. Corona really impressed me Corona. I found it to be the power and the right choice. I moved from when I saw how easy it was to get the perfect SDK for a flexibility. It allows me using GameSalad to Corona, graphics on to the screen and have Flash developer like me.” to make better games!” which is IMHO 100x better.” them look great on the device.” – – Ferry Halim, famed – Joe Kauffman, – Jon Beebe, ex-GameSalad user David Fox, web developer Flash Developer and Flash developer, Webby Award winner ex-GameSalad user “With Corona I felt right at home immediately, feels like JavaScript. I’m not sleeping because the development is so addicting!” —Angelo Yazar, Unity Developer “We were able to develop our first application with Corona in just a few days! Porting “We chose Corona because we’d get new “Coming from Flash, it looked a apps from Flash to Corona is component functions out more rapidly than little too simplistic at the beginning, quite easy and substantially via Cocoa Touch or Cocos2d. Supporting all but Corona’s simplicity and ease of lowers development costs.” of the iOS devices was a lot more seamless use doesn’t limit what you can do.” – Bohumil Vosicky, for us than was the case with Cocos2d.” – Ruben Frosali, Flash Developer educational developer — Mark Sigal, eBook publisher “I explored many options for new iPhone “Many people think that mobile development is difficult because of the developers and I have to say Corona just felt right. different programming languages (Objective-C, Java, etc.) For those It was easy to pick up in a short time and powerful people, Corona is probably the best solution — it’s accessible, simple, enough to enable really cool things to be done.” powerful, and not a barrier to creativity.” – Julian Paté, web developer – Matt Pringle, designer for EA/3DO AMBASSADOR coronalabs.com
  • 79. Award-winning Technology Staff Pick coronalabs.com CONFIDENTIAL
  • 80. AMBASSADOR coronalabs.com
  • 81. Thriving Ecosystem Zwoptex Particle Candy Texture Packer Sprite Deck Corona Project Manager Corona Photoshop Fireworks iAppHost Lime TextMate Corona Remote AMBASSADOR coronalabs.com
  • 82. Corona in Print! AMBASSADOR coronalabs.com
  • 83. Corona as a career Over 1000+ studios in 75 countries around the world “In what I hope is a good omen of things to come, this December I'm on track to earn substantially more money developing Corona- based apps for clients than I will at my (pretty well-paid) day job. 2012 may just be the year I stop working for somebody else.” – Jason Schroedere, designer for EA/3DO AMBASSADOR coronalabs.com
  • 84. Is it fun? “What is so great about Corona is it is so easy to just write code and get things working. You immediately see your results on the screen. That is what was so great about Applesoft or Logo. But they were just toy graphic languages. Yours is first class.” — Dave Lazarony, Creator of ADM (Adobe’s UI Framework) AMBASSADOR coronalabs.com
  • 85. Anyone can be #1... with Corona AMBASSADOR coronalabs.com
  • 86. Just for fun... AMBASSADOR coronalabs.com
  • 87. AMBASSADOR coronalabs.com
  • 88. AMBASSADOR coronalabs.com
  • 89. Get Corona free trial www.CoronaLabs.com AMBASSADOR coronalabs.com