LevelManager有個levels屬性,他是一個Array,你可以把每個場景依序放進去,等到需要切換畫面時在依照序號切換不同的State。
需要切換畫面時你可以使用LevelManager.nextLevel()切換到下一個場景或是使用LevelManager.gotoLevel(_stateId)方法來切換到不同的State,當LevelManager變動時會觸發onLevelChanged這個Signal。
繼續用之前的遊戲例子來說明,我們希望角色在生命值等於0(lives==0)時切換到結束畫面。
所以我們需要製作一個結束畫面的State。
import citrus.core.starling.StarlingState; import org.osflash.signals.Signal; /** * 基本的State */ public class MyState extends StarlingState { public var lvlEnded:Signal; public function MyState() { super(); //場景結束Signal lvlEnded = new Signal(); } }先作一個空的State(MyState),裏面有一個Signal物件叫作lvlEnded,State結束前會先觸發它,往後遊戲每個場景可以直接繼承它,就會有lvlEnded這個Signal
import citrus.objects.CitrusSprite; import starling.text.TextField; import flash.utils.setTimeout; /** * 結束的畫面 */ public class EndState extends MyState { public function EndState() { super(); } override public function initialize () : void { super.initialize(); add(new CitrusSprite("endTd", { view:new TextField(500, 400, "GameOver", "", 60,0xff0000) })); } }結束畫面的EndState是繼承MyState,然後我們在畫面上加上TextField並填上GameOver。
把原來的StarlingDemoGameState也改成繼承MyState,然後我們再gameData變動時加上lives==0就觸發場景結束這個條件。
private function gameDataChanged(data:String, num:int ):void { var _citrusSprite:CitrusSprite; switch (data) { case "lives": //生命值變動 _citrusSprite = getObjectByName("livesTd") as CitrusSprite; TextField(_citrusSprite.view).text = "生命:" + num; if (num<=0) { //生命值小於0就觸發lvlEnded lvlEnded.dispatch(); } break; case "score": //分數變動 _citrusSprite = getObjectByName("scoreTd") as CitrusSprite; TextField(_citrusSprite.view).text = "分數:" + num; break; default: trace(data, num); } }StarlingDemoGameState繼承了MyState,所以也擁有lvlEnded這個Signal,我們可以用lvlEnded.dispatch();來觸發它。
在Main的init()裡,我們new一個LevelManager物件,並把StarlingDemoGameState與EndState場景放進levels陣列。
//new一個LevelManager場景控制 levelManager = new LevelManager(MyState); //切換MyState levelManager.levels = [StarlingDemoGameState,EndState]; //依序放入State levelManager.onLevelChanged.add(_onLevelChanged); levelManager.gotoLevel();new LevelManager(MyState),作一個LevelManager物件,需要填入一個State參數,因為場景都繼承MyState,所以我們可以直接用MyState。(這也是我們之前建立MyState的用意,也方便管理)。
levelManager有變動就觸發_onLevelChanged()。最後是讓遊戲一開始就起動第一個State (gotoLevel()方法預設是1)。
再來實作_onLevelChanged方法。
private function _onLevelChanged(lvl:MyState):void { state = lvl; //設成新的state lvl.lvlEnded.add(_nextState); } private function _nextState():void { levelManager.nextLevel(); }_onLevelChanged會傳入要切換的MyStat,然後把目前的state設成新的MyState。
把MyStat的lvlEnded加上_nextState()這個方法,讓場觸發結束時作levelManager.nextLevel();這個動作,切換到下一個MyState。
輸出試看看,當角色生命值變成0時,遊戲的場景就會切換。
另外,如果你希望結束畫面可以再回到StarlingDemoGameState時,你可以使用levelManager.gotoLevel(1),它可以讓你切換到第一個State。
PS.你會發現在EndState裏面使用levelManager.nextLevel(),或lvlEnded.dispatch()沒有作用,因為EndState已經是最後一個Stat了,沒有沒有nextLevel...
然後也請記得在StarlingDemoGameState.initialize()裡先把gameData的分數與生命初始化,避免下一次進去遊戲生命值就是0的情況。
Demo預覽
原始碼下載
Flash遊戲引擎 CitrusEngine (六) 建立你的第一個遊戲- 場景編輯ObjectMaker與Camera控制
沒有留言:
張貼留言