2011年4月20日 星期三

Corona SDK -- 切換場景 director之使用

一般在設計遊戲上,一定會需要切換遊戲場景。
例如:開始選單Menu、關卡選單、遊戲場景...等等。

在Corona SDK原始API裡頭,不沒有直接對應場景切換的API,所需要使用的是我之前介紹過的Group的使用,透過將每一個場景的元素丟進同一個Group裡面,在利用Group整體切換,達到這樣的目的。
範例如下:

        local ui = require("ui")
        --########## Button 1 ##########
        --按下Button1時,把scrnHighScores場景換成scrnPlay場景
        local function button1Handler( event )
                transition.to( scrnHighScores,{time=500,transition=easing.inOutQuad,alpha=0} )
                transition.to( scrnPlay,{time=500,x=0,transition=easing.inOutQuad, alpha=1} )
        end

        local button1 = ui.newButton{
        default = "buttonRed.png",
         over = "buttonRedOver.png",
        x=60,
         y=360,
        onEvent = button1Handler,
         emboss = true
        }
        button1:scale(0.4,0.4)
        --########## Button 2 ##########
        --按下Button2時,把scrnPlay場景換成scrnHighScores場景
        local function button2Handler( event )
                transition.to( scrnPlay,{time=500,alpha=0} )
                transition.to( scrnHighScores,{time=500,x=0, alpha=1} )
        end
        local button2 = ui.newButton{
     default = "clear_on.png",
      over = "clear_off.png",
     x=260,
       y=360,
     onEvent = button2Handler,
     emboss = true
        }
        button2:scale(0.4,0.4)
        --###########################################################
        --第一個場景scrnHighScores,設定為一個Group
        --用來顯示遊戲分數,初始為看不見 (alpha=0)
        scrnHighScores = display.newGroup()
        scrnHighScores.x = display.contentWidth*-1
        scrnHighScores.alpha=0
        
        --第二個場景scrnPlay,設定為一個Group

        --用來玩遊戲之畫面,初始為看的見 (alpha default值為1)
        scrnPlay = display.newGroup()
        
        --scrnPlay場景的背景圖片,以及文字
        --設定好後,將之insert到scrnPlay這個Group裡頭,之後就可以一起控制
        Plbg=display.newImage("a.png",0,0,320,480)
        PlayText = display.newText("Play Game Here",50,50,native.systemFontBold,24)
        PlayText:setTextColor(255,255,255)
        scrnPlay:insert(Plbg)
        scrnPlay:insert(PlayText)
        scrnPlay:insert(button2)
        
        --scrnHighScores場景的背景圖片,以及文字
        --設定好後,將之insert到scrnHighScores這個Group裡頭,之後就可以一起控制
        hsbg=display.newImage("bg.png",0,0,320,480)
        hsText = display.newText("High Score Here",50,50,native.systemFontBold,24)
        hsText:setTextColor(255,255,255)
        scrnHighScores:insert(hsbg)
        scrnHighScores:insert(hsText)
        scrnHighScores:insert(button1)



這個範例裡頭利用兩個按鈕(buton1 以及button2),來控制場景的切換。
此範例參考網路上資訊之SWITICHING SCREENS
若有不了解,可以參考此段影片,不過是英文的,若有問題可以跟我聯絡。

=========================    這是分隔線    =========================
上述的方法雖然可行,但是不好使用,尤其一個完整的遊戲,場景一定相當多,這時候單純採用Group的方式,將會使得程式複雜化,之後也不好管理,不好維護。

因此,Rauber Labs撰寫出director這個class,可以相當方便來控管你要的場景。
這邊是corona SDK官網上的使用說明,在這網頁上可以抓到director的範例程式
另外這邊是Rauber Labs自行錄製的教學影片
在Corona SDK上也有一款範例遊戲Ghosts vs. Monsters,就是採用Corona SDK搭配director class撰寫出類似Angry Bird的遊戲。這個範例遊戲寫的很好,使用了很多開發遊戲上很需要的API,例如:director、ui、Physics、OpenFeint等等。


介紹了這麼多,來看看director該怎麼使用吧。
1. 首先,在你的main.lua程式裡頭,要require director class:
        director = require("director")
2. 要新增一個Group來擺放director要的場景
        local mainGroup = display.newGroup()
3. 把director輸入到Group裡面
        mainGroup:insert(director.directorView)
4. 切換到下一個場景
        director:changeScene("screen1")


一切就是這麼的簡單。
整個範例程式如下:

        director = require("director")
        local mainGroup = display.newGroup()
        local function main()
                -- Add the group from director class
                mainGroup:insert(director.directorView)
                -- Change scene without effects
                director:changeScene("screen1")
                -- Return
                return true
        end
---------------------------------------------------------------
-- Begin
---------------------------------------------------------------
        main()


那每一個場景,應該怎麼建立呢?
每一個場景模式都採用module的方式建立,建立方式如下:
1. 建立module
        module(..., package.seeall)
2. 建立此場景所需元素,放置在一個localGroup裡頭
3. 一定要把localGroup return
4. 切換下一個場景,並且可以帶入切換的動畫方式
        director:changeScene("screen2","moveFromRight")
注意:下一個場景的module檔案名稱必須是"screen2.lua"


切換場景方式有以下幾種:
"moveFromRight"    "overFromRight"    "moveFromLeft"            "overFromLeft"
"moveFromTop"      "overFromTop"       "moveFromBottom"      "overFromBottom" 
"crossfade"             "fade"                     "flip"                             "downFlip"


5. 最後要切換場景的時候,最好把前一個場景localGroup內的成員,給清除掉,比較不佔記憶體。而且,若有開啟相關Timer、addEventListerner也最好關掉,尤其是Runtime的EventListener一定要關掉,不然會出現嚴重錯誤。因此一般會建議設定一個Clear()的function,在切換的時候,把相關的清除掉。程式如下:

        local function clear_all()
                -- timer.cancel( timer_name)
                Level_num:removeEventListener("touch",gotomenu)
                Runtime:removeEventListener( "tap", double_touch )
                Runtime:removeEventListener("touch", PlotLine)
                -- REMOVE everything in other groups
                for i = localGroup.numChildren,1,-1 do
                 local child = localGroup[i]
                 child.parent:remove( child )
                 child = nil
                end
        end





這樣就可以輕鬆把每一個場景給模組化建立好,並且好管理,場景又可重複使用。

1 則留言:

  1. 感謝您詳細的說明,解答了在下的疑惑啊!!
    這兩天就來試試看! 再次感恩~ Thank you!

    回覆刪除