2012年6月10日 星期日

[教學] Flash 遊戲製作 (燒粟米)

這個範例, 為大家簡介在Flash 製作燒粟米遊戲, 並發佈於Android 和iOS 運行. 作者以基本設定自定物件兩部分說明遊戲製作技巧:

請按 [觀看] 範例
基本設定:
  • 場景(Scene) 流程: 在Window -> Other Panels -> Scene 中, 自由加入需要的場景.
    場景流程: Logo → Intro → Game Play → Game Over
     
  • 提升顯示速度: 把圖案轉換成JPG/PNG 等格式, 或啟動Cache as Bitmap.

  • 背景音樂(Background music): 把音樂放於時間軸上. 然後設定Sync: Stream, 這樣音樂與遊戲同步播放和停止. 其他的音效同樣可以這方式加入遊戲中.

  • 利用時間軸製作粟米狀態: 關於狀態顯示, 作者喜歡多用Flash 時間軸製作, 既簡單又實用.

自定物件:
遊戲中每一個物件, 我們會編寫繼承MovieClip, 它們成為獨特的物件, 在畫面負責一項功能, 與用戶產生互動. 範例製作以下幾個物件:
  • CornCooking 物件 - 遊戲框架, 把所有自定物件連繫一起.

    當加入新粟米時, 會執行addCorn 程序,  啟動粟米的拖拉(drag) 功能:
    public function addCorn(corn:Corn):void {
      // <----- start action
      corn.drag(this.stage);
      
      // <----- add listener
      corn.addEventListener(CornEvent.START_DRAG, startDragHandler);
      corn.addEventListener(CornEvent.STOP_DRAG, stopDragHandler);
    }
    

    當粟米被按動時, 若測試重疊於Oven 上, 會加入至爐中,
    否則會由Scoreboard 決定所得分數:
    private function stopDragHandler(event:CornEvent):void {
      var corn:Corn = event.target as Corn;
      var oven:CornOven = hitOven(corn);
      if (oven != null) {
        // <----- put to a oven
        oven.corn = corn;
        
      } else if (_scoreboard != null) {
        // <----- earn a score
        _scoreboard.addScore(corn);
        
        // <----- destory the corn
        corn.destory();
      }
    }
    

    測試重疊程序, 是利用內建的hitTestObject 功能作判斷:
    private function hitOven(corn:Corn):CornOven {
      for (var i:int = 0; i < _ovens.length; i++)
        if (corn.hitTestObject(_ovens[i]))
          if (_ovens[i].corn == null) // <----- is an available oven
            return _ovens[i];
      return null;
    }
    

  • CornOven 物件 - 火爐物件, 沒有實際顯示介面. 在遊戲中提供四個位置給用戶燃燒粟米.

    當粟米加入爐中, 會把粟米顯示於爐的中心位置, 和啟動粟米的燃燒(burn) 功能:
    public function set corn(value:Corn):void {
      if (_corn != null) {
        // <----- clear last corn
        _corn.removeEventListener(CornEvent.START_DRAG, startDragHandler);
        _corn.removeEventListener(CornEvent.DESTORY, destoryHandler);
      }
      
      if(value!=null){
        // <----- cache variable
        _corn = value;
        
        // <----- add to UI
        _corn.x = 0;
        _corn.y = 0;
        this.addChild(_corn);
        
        // <----- set action
        _corn.burn();
        
        // <----- add listener
        _corn.addEventListener(CornEvent.START_DRAG, startDragHandler);
        _corn.addEventListener(CornEvent.DESTORY, destoryHandler);
      }
    }
    

  • Corn 物件 - 粟米物件, 提供不同狀態顯示 .

    拖拉(drag) 功能是發動用戶的Mouse Down 與Mouse Up 的功能:
    public function drag(stage:Stage):void {
     // <----- cache variable
     _stage = stage;
     
     // <----- start to drag
     mouseDownHandler(null);
    }
    

    燃燒(burn) 功能是播放粟米在時間軸上的狀態:
    public function burn():void {
      if (this.currentFrame < this.totalFrames)
        this.play();
    }
    

  • CornScoreboard 物件 - 計分板, 處理粟米所得的分數, 和顯示總分數於螢幕右上方.

    提供addScore 程序, 當傳入一個粟米(Corn), 判斷將會得到的分數:
    public function addScore(corn:Corn):int {
      // <----- define variable
      var value:int = 0;
      
      // <----- earn a score from a corn
      switch(corn.status) {
        case Corn.STATUS_RAW:
          value = -10;
        break;
        case Corn.STATUS_BEGINNING:
          value = -5;
        break;
        case Corn.STATUS_MIDDLE:
          value = -1;
        break;
        case Corn.STATUS_GOOD:
          value = +10;
        break;
        case Corn.STATUS_FIRE:
          value = -10;
        break;
      }
      
      // <----- change the score
      _score += value;
      
      // <----- adjust value
      if (_score < 0)
        _score = 0;
      
      // <----- cache variable
      _lastScore = _score;
      
      // <----- set UI
      applyScore();
      
      // <----- dispatch event
      var e:CornEvent = new CornEvent(CornEvent.SCORING);
      e.value = value;
      this.dispatchEvent(e);
      
      // <----- return the value
      return value;
    }
    

  • CornScoring 物件 - 粟米得分效果.

    當加入得分效果, 呼叫applyScore 來判斷顯示的顏色:
    private function applyScore():void {
      if (_textField != null) {
        _textField.textColor = _score>0?0x009900:0x990000;
        _textField.text = (_score>0?"+":"")+_score.toString();
      }
    }
    

  • CornTimer 物件 - 計時物件.

    檢查時間軸是否完結, 然後發動GAME_OVER 事件給場景作改變:
    private function enterFrameHandler(event:Event):void {
      if (this.currentFrame == this.totalFrames) {
        // <----- stop UI
        this.stop();
        
        // <----- remove listener
        this.removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
        
        // <----- dispatch event
        this.dispatchEvent(new CornEvent(CornEvent.GAME_OVER));
      }
    }
我們除燒粟米外, 加入更多圖案和關卡, 變成一個好玩的燒烤遊戲喔.
大家可以 [下載] 範例試試看.

3 則留言:

Ding 翁 提到...
作者已經移除這則留言。
Turtler 提到...

在Library 選擇Corn1Mc, 在Symbol Properties 內定義Class 名稱.
這樣就可以new 這個物件.

Ding 翁 提到...
作者已經移除這則留言。