2013年5月31日 星期五

Flash遊戲引擎 CitrusEngine (四) 建立你的第一個遊戲-狀態與音效

一個可以吸引人的遊戲,除了有美麗的素材裝飾外,音效也是不可少的。
接下來,要為我們的遊戲加上音效。
首先我們在StarlingCitrusEngine(Main.as)裡面載入音效
//載入bgm.mp3並命名為bgm
sound.addSound("bgm", "bgm.mp3");
bgm.mp3準備拿來當背景音樂,要播放音效非常簡單。
打開你的State物件,並在initialize()裡加上
//取回遊戲引擎,也就是你剛剛的StarlingCitrusEngine實體
var citrusEngine:CitrusEngine = CitrusEngine.getInstance();
//播放bgm這個音效,0.5是音量(介於0~1之間)
citrusEngine.sound.playSound("bgm", 0.5);
輸出後馬上就可以聽到音效了。

接下來要建立一些狀態音效,比方你希望在某些狀態時才發出音效。
說到某個情況才觸發的事件,我想大家應該馬上想到Event(我們可能去偵聽某個事件..)
不過在CitrusEngine裡是用singal的方法(如果你不是很清楚的話,你可以直接想成回call的函式就行了,一般來說這種方法會比偵聽事件效能還要好)
以下我們以取得金幣的狀況作為例子。
//當金幣開始被碰撞時就觸發heroGetGold這個函式
coin.onBeginContact.add(heroGetGold);
coin是金幣的物件,我們在他的onBeginContact(開始被碰撞)的情況下,呼叫heroGetGold這個函式(singal是用add的方法加入)。
如果你希望碰撞到金幣時,可以發出音效,你可以在heroGetGold函式裡這樣做
/**
* 取得金幣時觸發
*/
private function heroGetGold(e:b2PolyAndCircleContact):void 
{
        //播放gold這個音效一次
 citrusEngine.sound.playSound("gold", 1, 0);
}
sound.playSound()第三個參數是播放次數,0只會播放一次

還有很多狀況你都可以自己設定,以下例子
hero.onJump.add(heroOnJump); //角色跳躍時觸發
hero.onGiveDamage.add(heroOnGiveDamage);  //角色攻擊時觸發
hero.onTakeDamage.add(heroOnTakeDamage);  //角色被攻擊時觸發
再來我們希望為遊戲,統計一些數值,比方常用的分數、生命值等等,建議你把這些變數統一放在AGameData物件裡。
CitrusEngine已經有幫你預留好位置了,在你的StarlingCitrusEngine加上一個遊戲資料AGameData物件。
//建立一個遊戲資料
citrusEngine.gameData = new AGameData();
AGameData物件已經有幫你建立好常用的一些變數
比方gameData.score 分數
gameData.lives 角色生命值(預設是3)
使用gameData的好處是,CitrusEngine已經有幫你定義好一些設定(比方當你的Hero物件觸碰到Enemy物件時gameData.lives會自動減一)
每當gameData有變動時,也有相對應的singal
//gameData有變話時就觸發gameDataChanged這個函式
citrusEngine.gameData.dataChanged.add(gameDataChanged);
然後你可以在你的gameDataChanged裡這樣做。
private function gameDataChanged(data:String, num:int ):void 
{
 switch (data) 
 {
  case "lives":
       //生命值變化時要作的事
  break;
  case "score":
       //分數變化時要作的事
  break;
  default:
  }
 }
}
回傳的兩個參數,第一個是變動的屬性名稱,如果變動的是生命值,就會回傳"lives"字串
第二個參數是變動後的數值,你可以再拿去應用。

以下例子,如果你想要在你的在畫面上,建立一個可以顯示分數的欄位你可以這樣做
//建立一個顯是分數的TextField物件在畫面上
add(new CitrusSprite("scoreTd", { view: new TextField(200, 50, "分數:0") ,x:80,y:0,group:2}) );
CitrusEngine中所有的顯示物件都是CitrusSprite,這樣你才可以用add的方法加入State。
然後new一個TextField物件,把它放在(200,50)的位置上,置於第3層(group=2)這樣才不會被其他物件檔到。
之後你可以在你的heroGetGold函式裡幫gameData的score加1分。
/**
 * 取得金幣
*/
private function heroGetGold(e:b2PolyAndCircleContact):void 
{
         //播放gold這個音效一次
 citrusEngine.sound.playSound("gold", 1, 0);
         //加一分
 citrusEngine.gameData.score++;
}
然後再加上分數變化後要作的事
private function gameDataChanged(data:String, num:int ):void 
{
 var _citrusSprite:CitrusSprite;
 switch (data) 
 {
  case "lives":
       //生命值變化時要作的事
  break;
  case "score":
          //分數變化時要作的事
                        _citrusSprite = getObjectByName("scoreTd") as CitrusSprite;
    TextField(_citrusSprite.view).text = "分數:" + num;
  break;
  default:
  }
 }
}
getObjectByName("scoreTd")是取回叫作scoreTd的物件
每是有變化時我們再更新他的內容
這樣子每次分數有變動時就會顯示也會改變了

Demo預覽
原始碼下載
Flash遊戲引擎 CitrusEngine (五) 建立你的第一個遊戲- LevelManager 場景控制

沒有留言: