2015年4月9日 星期四

[Corona SDK] 如何利用Composer來切換場景

我們的程式通常會有幾個不同功能的畫面,
例如,設定相關畫面..遊戲畫面..說明畫面等等,
我們可以把同一個畫面相關程式放在同一個"xx.lua"檔裡,
然後利用Composer來切換不同的畫面(場景Scene),

The Template of Scene
每個Scene檔裡,都會有4個基本的function
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()是切換到此場景時先被呼叫的地方,我們可以這裡加入button等場景需要的物件以及相對應的function,
show()是場景要開始真正運作的進入點,我們在這裡加入需要的執行動作,例如播放音樂等等,
hide()是場景要被切換時會呼叫,也就是要離開場景時,
destroy()是場景被remove時會呼叫

main.lua
我們也可以在main.lua裡加入display相關物件,
在這裡加入的物件,不管如何切換場景,它們都會出現在畫面上,
可以視它們為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()
在這裡我們加入一個tabbar,
不管在那個場景,我們都可以這個tabbar切換場景,
composer.gotoScene( "scene1", "fade", 400 )表示要切到"scene1", 它需要有一個對應的"scene1.lua"

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

local image, text1, text2, text3, memTimer

-- 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 scene: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 scene:show( event ) 
 local phase = event.phase 
 if "did" == phase then 
  print( "1: show event, phase did" )   
  composer.removeScene( "scene2" ) 
 end 
end

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

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

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

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

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

return scene
在scene1裡我們加入了一個button,除了用原本的tabbar, 我們也可以利這個button來切換到scene2

scene2.lua
local composer = require( "composer" )
local scene = composer.newScene()
local widget = require "widget"
local image, text1, text2, text3, memTimer
-- Function to handle button events
local function handleButtonEvent( event )

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

function scene: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 scene:show( event ) 
 local phase = event.phase 
 if "did" == phase then 
  print( "2: show event, phase did" )
  composer.removeScene( "scene1" ) 
 end
 
end

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

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

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

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

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

return scene
scene2和scene1類似,
當我們呼叫composer.gotoScene( "scene2", "fade", 400 )時,
scene1的hide()會先被呼叫,
然後是scene2的create(),再來是scene2的show()
在scene2的show()裡面我們執行composer.removeScene( "scene1" )
此時scene1的destroy()會被呼叫

3 則留言:

  1. 謝謝,此教學很有幫助!

    有些延伸問題想請教如果切換scene的時候,想要讓下方的tabbar的狀態也隨著要怎麼做呢?

    回覆刪除
  2. 您好,
    以上的範例中,tabBar是在main.lua裡create,
    如果您希望在切換scene時tabBar也跟著變,
    那建議tabBar改成在各自的scene裡去create

    回覆刪除