Nov 192010

This is what I hope will be a fairly easy to follow tutorial for those of you who need some help learning how to use “scenes” or “screens” in your apps.

*Full credit for the director file goes to Ricardo Rauber – I could never have come up with this, I only want to help others learn how to use it.

Download the project file here.

(Keep in mind that if you are planning on compiling this for your device you’ll need to add an Icon.png and Default.png image to the folder.)

Alright, let’s get started!

Step One: In your project file (this is a NEW project, not the one you downloaded above) you will want to copy across four files, these are build.settings, config.lua, director.lua and main.lua.

Step Two: Create the first scene/screen that people will see when they open up your app, in my case I always call this “menu.lua”. Don’t worry about adding anything to it yet, just make the file.

Step Three: Open the main.lua file that you copied into your project in step one and look for this line;

local function main()
-- Adds main function

-- Adds the group from director

-- Change the scene, no effects

return true

Here you are going to replace “menu” with the name of your initial screen, for example if you have called your file home.lua you will change “menu” to “home” – note, we do not include “.lua” here.

Step Four: Open the file you created before, menu or home or what have you, and insert the following code (this should be the only text in the file at this stage):

module(..., package.seeall)

function new()
local localGroup = display.newGroup()
return localGroup

Step Five: Write your code here as you normally would, inserting images and arranging them, with one additional step now present; for every image, you must add this line;

local redbutton = display.newImage ("redbutton.png")
redbutton.x = 160
redbutton.y = 100

This is very important, if you forget to add this line to any image, including your background, the project will not function as intended. If you can see it, you add the line. Every time.

Step Six: Now you’ve got your initial screen/scene setup, you will want to add a button which will go to a new one; that’s the point of using director, right? Right.

First, we need a file to change to – for me, I created red.lua.

In every file you create you will use the code above that you pasted into your menu.lua or home.lua file, placing your code in between the red lines and using the line of code discussed for every single image.

Step Seven: To demonstrate how to change from your menu.lua or home.lua to red.lua I will create a function for one of my buttons, as used in the example. In this case my button is redbutton and when it is touched I want to change to the scene I’ve created called red.lua

local function pressRed (event)
if event.phase == "ended" then
director:changeScene ("red")

Now, when you press your button it will change from your initial screen/scene to red.lua

And that’s it!

By looking at the example you will see it in action if you don’t want to create a simple project yourself to test with; provided you always put each files code in between the red lines and remember to add every image to your localGroup then it will function beautifully and be one of the most useful things you ever learn.

From time to time when your code has errors, terminal may indicate that some of these are in director.lua – this is not the case. If you read through the errors you will note at least one is in your own file; once this is remedied the errors supposedly relating to director.lua will disappear; so do not be alarmed.

If you have questions, ask me. I’m committed to helping others learn Corona as I learn myself :)

Be sure to add me on Facebook and follow me on Twitter if you have it; although I’m currently posting in the Corona forums when I update the site I don’t intend to do so forever. Plus, Facebook is an easy way to quickly reach me if you need a hand!

Stay tuned, I hope to post an OpenFeint example soon as requested by a couple of you.

Peach Pellen :)

Like this post? Subscribe to the monthly newsletter!


  141 Responses to “How To Use Scenes/Screens In Corona”

  1. settings.lua
    local lang_table = {
    {image = display.newImage(“en.png”), x = 600, y = 400, lang = “1033″, i = 1},
    {image = display.newImage(“fr.png”), x = 600, y = 400, lang = “fr”, i = 2},
    {image = display.newImage(“dk.png”), x = 600, y = 400, lang = “dk”, i = 3},
    {image = display.newImage(“ge.png”), x = 600, y = 400, lang = “ge”, i = 4} }

    local function changelanguage (event)
    if event.phase == “ended” then
    lang_table[].image.isVisible = false
    if == 4 then
    lang_table[1].image.isVisible = true
    _G.value =
    lang_table[].image.isVisible = true
    _G.value = lang_table[].lang
    return true

    for i = 1,#lang_table do
    local img_display = lang_table[i].image
    img_display.x = lang_table[i].x
    img_display.y = lang_table[i].y
    img_display.i = lang_table[i].i
    img_display.lang = lang_table[i].lang

    if _G.value ~= lang_table[i].lang then
    img_display.isVisible = false

    img_display:addEventListener(“touch”, changelanguage)

    When I touch the image,changelanguage function is being invoked.In that function there is
    but this is not working.Basically,what I want is that whenever there is touch event to the image I want the same lua file to be called.But this is not happening.Then What I did was changed the function “changelanguage” to

    _G.t =1
    local function changelanguage (event)
    if event.phase == “ended” then
    lang_table[].image.isVisible = false
    if == 7 then
    lang_table[1].image.isVisible = true
    _G.value =
    lang_table[].image.isVisible = true
    _G.value = lang_table[].lang
    if _G.t ==1 then
    _G.t = _G.t+1
    elseif _G.t ==2 then
    return true

    Now, it is working.But I dont know why is this happening.Can anyone suggest me why is this happening.Cant I use the same director:changeScene(“settings”) to change the scene again and again on touch event.

  2. Hey Alex,

    I actually replied to your forum thread on this; it’s because you have not removed the Runtime listener. I gave you the code to remove it specifically in the forum :)

  3. Hi there again :)

    I’ve been working on this menu for switching between scenes using the director class and I’m having a problem with the switching. I’m also using some of the sample code to create my moving background.

    When I run my program the menu animates and works ok but when I click game I get the error “lua:183: attempt to perform arithmetic on field ‘x’

    This is the code I’m using:

    module(…, package.seeall)

    function new()
    local localGroup = display.newGroup()

    _W = display.contentWidth
    _H = display.contentHeight

    – The sky image as background
    local sky = display.newImage( “Images/skyBG.png” )
    localGroup:insert (sky)

    local logo = display.newImage (“Images/logoImage.png”)
    logo.x = _W/2
    logo.y = 50
    logo.xScale = 0.6
    logo.yScale = 0.7

    local playButton = display.newImage (“Images/playButton.png”)
    playButton.x = _W/2
    playButton.y = 130
    playButton.xScale = 0.6
    playButton.yScale = 0.6

    local instButton = display.newImage (“Images/instructionsButton.png”)
    instButton.x = _W/2
    instButton.y = 180
    instButton.xScale = 0.6
    instButton.yScale = 0.6

    local quitButton = display.newImage (“Images/exitButton.png”)
    quitButton.x = _W/2
    quitButton.y = 230
    quitButton.xScale = 0.6
    quitButton.yScale = 0.6

    – Code required for a moving background
    require “sprite”
    display.setStatusBar( display.HiddenStatusBar )

    local baseline = 280

    – Series of cloud images

    local tree = {}
    tree[1] = display.newImage( “Images/cloud1.png” )
    tree[1].xScale = 1; tree[1].yScale = 1
    tree[1]:setReferencePoint( display.BottomCenterReferencePoint )
    tree[1].x = 20; tree[1].y = 180
    tree[1].dx = 0.2

    tree[2] = display.newImage( “Images/cloud2.png” )
    tree[2].xScale = 0.6; tree[2].yScale = 0.6
    tree[2]:setReferencePoint( display.BottomCenterReferencePoint )
    tree[2].x = 450; tree[2].y = 125
    tree[2].dx = 0.2

    tree[3] = display.newImage( “Images/cloud3.png” )
    tree[3].xScale = 0.6; tree[3].yScale = 0.8
    tree[3]:setReferencePoint( display.BottomCenterReferencePoint )
    tree[3].x = 600; tree[3].y = baseline
    tree[3].dx = 0.3

    tree[4] = display.newImage( “Images/cloud4.png” )
    tree[4].xScale = 0.7; tree[4].yScale = 0.7
    tree[4]:setReferencePoint( display.BottomCenterReferencePoint )
    tree[4].x = 230; tree[4].y = 220
    tree[4].dx = 0.4

    tree[5] = display.newImage( “Images/cloud5.png” )
    tree[5].xScale = 0.8; tree[5].yScale = 0.8
    tree[5]:setReferencePoint( display.BottomCenterReferencePoint )
    tree[5].x = 300; tree[5].y = 120
    tree[5].dx = 0.3

    tree[6] = display.newImage( “Images/cloud6.png” )
    tree[6].xScale = 0.8; tree[5].yScale = 0.8
    tree[6]:setReferencePoint( display.BottomCenterReferencePoint )
    tree[6].x = 320; tree[6].y = 300
    tree[6].dx = 0.3

    tree[7] = display.newImage( “Images/cloud7.png” )
    tree[7].xScale = 0.8; tree[7].yScale = 0.8
    tree[7]:setReferencePoint( display.BottomCenterReferencePoint )
    tree[7].x = 580; tree[7].y = baseline
    tree[7].dx = 0.5

    for i=1,#tree do

    local bar1 = display.newImage( “Images/baseLine.png” )
    bar1:setReferencePoint( display.CenterLeftReferencePoint )
    bar1.x = 0
    bar1.alpha = 0
    bar1.y = baseline – 0.1

    local bar2 = display.newImage( “Images/baseLine.png” )
    bar2:setReferencePoint( display.CenterLeftReferencePoint )
    bar2.x = 480
    bar2.alpha = 0
    bar2.y = baseline – 0.1

    local function playButtonEvent (event)
    if event.phase == “ended” then
    director:changeScene (“game”)

    playButton:addEventListener (“touch”, playButtonEvent)

    local function instButtonEvent (event)
    if event.phase == “ended” then
    director:changeScene (“instructions”)


    instButton:addEventListener (“touch”, instButtonEvent)

    local function quitButtonEvent (event)
    if event.phase == “ended” then
    director:changeScene (“exit”)

    quitButton:addEventListener (“touch”, quitButtonEvent)

    local tPrevious = system.getTimer()
    local function move(event)
    local tDelta = event.time – tPrevious
    tPrevious = event.time

    local xOffset = ( 0.1 * tDelta )

    bar1.x = bar1.x – xOffset
    bar2.x = bar2.x – xOffset

    if (bar1.x + bar1.contentWidth) < 0 then
    bar1:translate( 480 * 2, 0)
    if (bar2.x + bar2.contentWidth) < 0 then
    bar2:translate( 480 * 2, 0)

    local i
    for i = 1, #tree, 1 do
    tree[i].x = tree[i].x – tree[i].dx * tDelta * 0.05
    if (tree[i].x + tree[i].contentWidth) < 0 then
    tree[i]:translate( 480 + tree[i].contentWidth * 2, 0 )

    Runtime:addEventListener( "enterFrame", move )

    return localGroup

    I think this is something to do with the timer to move everything and it not ending when the scene is switched however I'm a but puzzled on where to end it and what code I use?

    Sorry for the long post and thanks for any help!

  4. Hey Alex,

    I do – it’s on my contact/hire page: (as you can see it’s an image not a link as I want to stay off spam lists ;))

    That said I’m generally very busy so while I do my best you may actually get a faster reply posting in the Ansca/Corona forum. (Which I also answer several times a day.)

  5. Hi Peach,

    Do you have an email address I would be able to contact you on at all? I’m having some issues with images clearing when switching scenes and I’ve tried many different ways of grouping them but I seem to be getting some strange results and was wondering if you would be able to lend some advise?

    Thanks a lot


  6. Hey Daniel,

    At present no I don’t believe so but it’s something we’re hoping will be available very soon.

  7. Hi!…I can get a scene transition like going from page in a book?

  8. The class will be going a lot better once the Corona Level Editor breaks out of Alpha testing and gets to us. Any insider info on when that might be? ;-p

  9. Hi Peach,
    Do you prefer director to storyboard? I switched not long ago.
    Mike Kelly

    • That’s a tough question but I suppose right now the answer is yes, I do prefer Director. That is namely because I’m set in my ways and have been using Director for over a year and also in part because I haven’t had any spare time to really get familiar with Storyboard. (The last two months for some reason have just been so busy; I keep meaning to email you to ask how your class is going but every time I start to write I get a phone call or someone grabs me on Skype >.< ‘) You get a chance please do write me and let me know :)

  10. Hi Peach, Just a rather basic question here about using Director.
    You state that every image has to be added to localGroup. Can I assume that you can have sub-groups that are added to localGroup, and the the images only have to be added to the relevant sub-group?
    (I think that makes sense).


  11. Exactly – I’m very pleased to hear you have this working. Good job! :)

  12. That makes perfect sense! Thanks PP! :D

    Not only must remove listener, but all the timers which have looping-called-functions which spans more than 30seconds must be removed too. My codes work perfectly.

    Thanks again.

  13. No worries.

    Splash screen is what Default.png is – it shows when your app is loading at the start :)

    You would indeed do that – make the Default.png the screen size and name it Default.png.

    Make the icon 57×57 and name it Icon.png and then put both into the project folder.

    What you make the icon look like is up to you, it’s your icon :)

  14. Hi Peach,

    I’m a fan of you & your tutorials :)
    I’ve tried to use these codes in my game but there’s a problem. Let me explain:

    I have a game with a character on stage, setflag of its existence.
    local Player1Exist = false

    Inside the game I will spawn it for the first time, and setting the Player1Exist = true.

    If the player1 fall off the into the water in the game, I will use player1.removeSelf() to remove it, set Player1Exist = false again. And after 10seconds, player1 will re-spawn.

    I have a joystick controlling the player movement. It’s a simple joystick which I found from Ansca Mobile forum. During runtime, if Player1Exist = true, then I will set the joystick to be able to control player1 movement (I applied Player1:applyForce method for motion control). During Player1Exist = false, I will have to remove the functions of the joystick. (If not, error will comes out if I touch the joystick when the player1 is not on the stage).

    After playing for 30seconds, the game will calculate the player’s point. If point < 100, then it will jump to youLose.lua, else, it will jump to youWin.lua.

    I used your tutorial here and set all these codes into singlePlayer.lua and simulated it.
    Everything goes fine until 30seconds reached, it jumped to the correct scene. But there's error popping out indicating that the player1:applyForce is a nil value.

    I used Runtime onEnterFrame in the singlePLayer.lua to keep detecting the player1's existence, continuously removing and adding the joystick function to the player1.

    I notice that when the scene jumped to youLose.lua or youWin.lua, the singlePlayer.lua's onEnterFrame function is still running.

    Pls help to make it stop running when the scene has already changed.

    • Hey Shao, thank you for the kind words.

      For your problem you need to remove the Runtime listener, like so;

      Runtime:removeEventListener("enterFrame", functionName)

      That assumes it is on enterFrame – but just the same way you added it, your remove it in the line above director:changeScene()

      Does this make sense? :)

  15. Thanks for your help. I use photoshop elements to create my own backgrounds and icon. So would I just make a background in the dimensions of the ipod and name it Default.png and the same for the icon. If so what would I make the icon button look like? Also what is a Splash Screen? Thanks for your help again.

  16. OH I understand, haha, sorry!

    You make Default.png and Icon.png. They’re YOUR Icon and YOUR Splash screen :) Then just drop them in the folder and they will work.

    What program do you normally use to make images in? You would use that. Default.png should be the size of your screen (iPhone is 320 wide x 480 high) and the icon should be 57×57, assuming it is an iPhone app.

    Make sense? :)

  17. All i am doing is using the Corona software to view my work and I am going around to websites self teaching myself to code. I use TextWrangler to code.
    And I don’t know where to find the Default.png image and Icon.png to drop them into my folder. Because in your Project File Example its not in the folder to drop over into my project. Do I need to make them? If so how?

  18. At the top of the page? Where are you looking for them? You just drop them into a folder like you do when moving anything else on your computer.

    Are you using any third party software?

  19. Exactly, but where can I find the two .pngs to drop them into my folder. I can’t find them in the project that you provided to download at the top of the page. Do you know where I can find the files to drag them into my project?

  20. Hi Peach,
    Thanks for the great walkthroughs. One quick question though I can’t figure out how to add an Icon.png and Default.png image to my projects folder. Any help will be greatly appreciated. Thanks.

    • Hey Sammy, you just drop the Default.png image and Icon.png image into your project folder; is that what you’re asking?

  21. hi peach, I got your email and replied. thank you for your concern. :)

 Leave a Reply



You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Notify me of followup comments via e-mail. You can also subscribe without commenting.