2011年9月11日 星期日

[教學] Flash 遊戲製作 (進階編)

以Adobe Flash 製作遊戲, 只要懂得幾個重點, 每個人都能編寫遊戲.
現在為大家介紹, 如何編寫簡單射擊遊戲, 我們會分兩部分說明 (基礎編 及 進階編).
  • 基礎編 - 為大家講解AS3(Action Script 3.0) 基本用法, 構成遊戲的基本元素, 用戶與遊戲之間溝通方法.
  • 進階編 - 把所有遊戲元素物件化, 建構整個遊戲, 最後發佈至iOS 運作.
了解AS3(Action Script 3.0) 基本用法後, 製作一個簡單遊戲, 只要動動腦筋便可完成.
但要有效維護, 減少錯誤發生, 便需要一個完善結構.

Adobe Flash 提供一個既簡單, 又直接方法, 實踐物件導向 (Object-oriented) 功效. 每一個物件可繼承MovieClip, 便可編寫成一個個獨特的物件, 在畫面出現, 彼此產生互動.

在Flash Library 中, 選擇一個合適物件, 然後設定Base Class, 把自行編寫的物件作連結, 這個物件便有著新的獨特功能.

我們可以想像畫面中, 出現的每一個元素, 把它們視為一個物件.
每一個物件有著它們特性(屬性Property 與方法Method), 然後把每個物件都串聯在一起.
現在為大家介紹, 以射擊遊戲作一個簡單說明.

範例功能:
  1. 開始畫面
  2. 遊戲畫面
      - 按下螢幕時, 移動玩家位置
      - 測試玩家是否被擊中
  3. 完結畫面




範例類別說明:
SimpleGame
  功能: 主管整個遊戲流程
  屬性: 擁有一個飛行空間(FlyingArea) 和一個分數版(Scoreboard)
  方法: 可跳至遊戲畫面和完結畫面

FlyingArea
  功能: 提供一個空間, 給所有飛行物件移動, 測試物件之間是否重疊碰撞
  屬性: 擁有多個飛行物件(FlyingObject) 和一個玩家物件(Plane)
  方法: 提供增加和破壞飛行物件

Scoreboard
  功能: 顯示和計算分數
  屬性: 擁有一個分數變數
  方法: 提供重新設定和增加分數

FlyingObject
  功能: 作為所有飛行物件的基礎物件, 所有繼承者都有著它的功能
  屬性: 擁有慣性(inertia) 和加速度(acceleration)
  方法: 提供設定慣性值和加速度方法

Bullet
  功能: 繼承飛行物件

Plane
  功能: 作為玩家和電腦的父係物件
  屬性: 是否自動發炮(autoFire) 和炮彈重射緩衝期(bulletBuffer)
  方法: 提供發射炮彈方法

PlanePlayer
  功能: 由玩家控制的飛行物件

PlaneComputer
  功能: 由電腦控制的飛行物件


範例說明:
當遊戲開始, FlyingArea 會產生一個ENTER_FRAME 事件, 在每一次更新, 會執行以下四個工作:
  • 清除已經離開畫面的飛行物件 (clearObjects)
    private function clearObjects():void {
      for (var i:int = 0; i < _objects.length; i++)
        if (!_availableArea.contains(_objects[i].x, _objects[i].y))
          destoryFlyingObject(i--);
    }
  • 測試飛行物件之間是否重疊碰撞 (hitTestObjects)
    private function hitTestObjects():void {
      // <----- hit test for bullet
      for (var i:int = 0; i < _objects.length; i++)
        for (var j:int = 0; j < _objects.length; j++)
          if(_objects[i]!=null && _objects[j]!=null)
          if (i!=j && _objects[i].hitTestObject(_objects[j]))
            if (_objects[i] is Bullet && _objects[j] is PlaneComputer) {
              destoryFlyingObject(i--);
              destoryFlyingObject(j--);
            }
      
      // <----- hit test for player
      for (var k:int = 0; k < _objects.length; k++)
        if(_objects[k]!=null && _player!=null)
          if (_objects[k].hitTestObject(_player))
            if (_objects[k] is PlaneComputer) {
              destoryFlyingObject(k--);
              _player.destory();
            }
    }
    
  • 按照特定時間產生電腦物件 (createComputer)
    private function createComputer():void {
      var object:FlyingObject;
      if (_currFrame % LAUNCH_COM1 == 0) {
        object = new (getDefinitionByName("PlaneComputer1") as Class)();
        object.x = 0;
        object.y = this.stage.stageHeight / 5 * 1;
        addFlyingObject(object);
      }else if (_currFrame % LAUNCH_COM2 == 0) {
        object = new (getDefinitionByName("PlaneComputer1") as Class)();
        object.x = 0;
        object.y = this.stage.stageHeight / 5 * 2;
        addFlyingObject(object);
      }else if (_currFrame % LAUNCH_COM3 == 0) {
        object = new (getDefinitionByName("PlaneComputer1") as Class)();
        object.x = 0;
        object.y = this.stage.stageHeight / 5 * 3;
        addFlyingObject(object);
      }else if (_currFrame % LAUNCH_COM4 == 0) {
        object = new (getDefinitionByName("PlaneComputer2") as Class)();
        object.x = this.stage.stageWidth;
        object.y = 0;
        addFlyingObject(object);
      }else if (_currFrame % LAUNCH_COM5 == 0) {
        object = new (getDefinitionByName("PlaneComputer3") as Class)();
        object.x = 0;
        object.y = this.stage.stageHeight/5*(Math.floor(Math.random()*4)+1);
        addFlyingObject(object);
      }
    }
    
  • 更新所有飛行物件的位置 (refreshObjects)
    private function refreshObjects():void {
      for (var i:int = 0; i < _objects.length; i++)
        _objects[i].refresh();
      _player.refresh();
    }
當有物件被移除時, FlyingArea 會發動事件給SimpleGame 處理.
如果被移除的物件為電腦, 便會增加分數. 但被移除的物件為玩家, 便會執行遊戲完結.
public function removeHandler(event:FlyingEvent):void {
  if (event.data is PlaneComputer)
    _scoreboard.addScore();
  else if(event.data is PlanePlayer)
    gameover();
}

大家可以 [下載], 然後一齊看看, 動手製作簡單遊戲玩玩.

沒有留言: