2015年4月9日 星期四

[Corona SDK] How to change scene using Composer?

In general, there will have many menus with different purposes in our APP, such as setting menu, game screen, instruction menu, and so on.
We can configure one menu with one "xx.lua", and then use Composer to change the menu (or scene).

The Template of Scene
In each scene file, there will have 4 basic functions:
local composer = require( "composer" )
local scene = composer.newScene()

---------------------------------------------------------------------------------

function scene:create( event )
 local sceneGroup = self.view

 -- Called when the scene's view does not exist.
 -- 
 -- INSERT code here to initialize the scene
 -- e.g. add display objects to 'sceneGroup', add touch listeners, etc.
end

function scene:show( event )
 local sceneGroup = self.view
 local phase = event.phase
 
 if phase == "will" then
  -- Called when the scene is still off screen and is about to move on screen
 elseif phase == "did" then
  -- Called when the scene is now on screen
  -- 
  -- INSERT code here to make the scene come alive
  -- e.g. start timers, begin animation, play audio, etc.
 end 
end

function scene:hide( event )
 local sceneGroup = self.view
 local phase = event.phase
 
 if event.phase == "will" then
  -- Called when the scene is on screen and is about to move off screen
  --
  -- INSERT code here to pause the scene
  -- e.g. stop timers, stop animation, unload sounds, etc.)
 elseif phase == "did" then
  -- Called when the scene is now off screen
 end 
end


function scene:destroy( event )
 local sceneGroup = self.view
 
 -- Called prior to the removal of scene's "view" (sceneGroup)
 -- 
 -- INSERT code here to cleanup the scene
 -- e.g. remove display objects, remove touch listeners, save state, etc.
end

---------------------------------------------------------------------------------

-- Listener setup
scene:addEventListener( "create", scene )
scene:addEventListener( "show", scene )
scene:addEventListener( "hide", scene )
scene:addEventListener( "destroy", scene )

---------------------------------------------------------------------------------

return scene
create() is the first function being called when we change to this scene.
We can add display objects such as button or text here, and their related event functions.
show() is the next function being executed where we can add action here, such as playing sound.
hide() will be executed when we are leaving the scene.
destroy() is called if this scene is removed.

main.lua
We can also add display objects in main.lua.
Those objects added here will appear on all scenes.
We can take them as global objects.
-- hide device status bar
display.setStatusBar( display.HiddenStatusBar )

-- require controller module
local composer = require "composer"

local widget = require "widget"

local function runTab1(event )
 composer.gotoScene( "scene1", "fade", 400 )
end

local function runTab2(event )
 composer.gotoScene( "scene2", "fade", 400 )
end

local widget = require( "widget" )

 -- Create buttons table for the tabBar
 local tabButtons = 
 {
  {
   label = "tab1",
   id = "tab1",
   size = 40,
   onPress = runTab1, 
   selected = true
  },
  {
   label = "tab2",
   id = "tab2",
   size = 40,
    onPress = runTab2
  }
 }

 -- Create tabBar at bottom of the screen
 local tabBar = widget.newTabBar
 {
  buttons = tabButtons
 }
 tabBar.y = display.contentHeight - (tabBar.height/2) 
 print(display.contentHeight)
 runTab1()
We add a tabbar here.
No matter in which scene, we can change scene using this tabbar.
composer.gotoScene( "scene1", "fade", 400 ) mean that we want to change to "scene1".
There will have one file named "scene1.lua" for it.

scene1.lua
local composer = require( "composer" )
local scene1 = composer.newScene()
local widget = require "widget"
---------------------------------------------------------------------------------
-- BEGINNING OF YOUR IMPLEMENTATION
---------------------------------------------------------------------------------

-- Function to handle button events
local function handleButtonEvent( event )

    if ( "ended" == event.phase ) then
        composer.gotoScene( "scene2", "fade", 400 )
    end
end

-- Called when the scene's view does not exist:
function scene1:create( event )
 local sceneGroup = self.view
 text1 = display.newText( "Scene 1", 0, 0, native.systemFontBold, 24 )
 text1:setFillColor( 255 )
 text1.x, text1.y = display.contentWidth * 0.5, 50
 sceneGroup:insert( text1 )
 -- Create the widget
 local button1 = widget.newButton
 {
     left = 100,
     top = 320,
     id = "button1",
     label = "Goto Scene 2",
     onEvent = handleButtonEvent
 } 
 sceneGroup:insert( button1 )
 print( "\n1: create event")
end

function scene1:show( event ) 
 local phase = event.phase 
 if "did" == phase then 
  print( "1: show event, phase did" )   
  composer.removeScene( "scene2" ) 
 end 
end

function scene1:hide( event ) 
 local phase = event.phase 
 if "will" == phase then 
  print( "1: hide event, phase will" ) 
 end 
end

function scene1:destroy( event )
 print( "1: destroying scene 1's view" )
end

---------------------------------------------------------------------------------

-- Listener setup
scene1:addEventListener( "create", scene1 )
scene1:addEventListener( "show", scene1 )
scene1:addEventListener( "hide", scene1 )
scene1:addEventListener( "destroy", scene1 )

---------------------------------------------------------------------------------

return scene1
In scene1, we add a button. We can change to scene2 by this button, except for using tabbar.

scene2.lua
local composer = require( "composer" )
local scene2 = composer.newScene()
local widget = require "widget"

-- Function to handle button events
local function handleButtonEvent( event )

    if ( "ended" == event.phase ) then        
        composer.gotoScene( "scene1", "fade", 400 )
    end
end

function scene2:create( event )
 local sceneGroup = self.view
 text1 = display.newText( "Scene 2", 0, 0, native.systemFontBold, 24 )
 text1:setFillColor( 255 )
 text1.x, text1.y = display.contentWidth * 0.5, 50
 sceneGroup:insert( text1 )
 local button1 = widget.newButton
 {
     left = 100,
     top = 320,
     id = "button1",
     label = "Goto Scene 1",
     onEvent = handleButtonEvent
 } 
 sceneGroup:insert( button1 ) 
 print( "\n2: create event" )
end

function scene2:show( event ) 
 local phase = event.phase 
 if "did" == phase then 
  print( "2: show event, phase did" )
  composer.removeScene( "scene1" ) 
 end
 
end

function scene2:hide( event ) 
 local phase = event.phase
 if "will" == phase then 
  print( "2: hide event, phase will" )
 end
end

function scene2:destroy( event ) 
 print( "2: destroying scene 2's view" )
end

---------------------------------------------------------------------------------

-- Listener setup
scene2:addEventListener( "create", scene2 )
scene2:addEventListener( "show", scene2 )
scene2:addEventListener( "hide", scene2 )
scene2:addEventListener( "destroy", scene2 )

---------------------------------------------------------------------------------

return scene2
scene2 is similar with scene1.
When we call composer.gotoScene( "scene2", "fade", 400 ) in scene1:show() function,
the functions being called will be:
scene1:hide() => scene2:create() => scene2:show()
In scene2:show(), we run composer.removeScene( "scene1" ), the function scene1:destroy() will be called then.

沒有留言:

張貼留言