2Dアクション・テンプレート:入力の対応(仮想化)
=仮想入力クラス=
まずは、キーボードの入力やジョイスティックの入力を抽象化したものを用意する。
今回の2Dアクションで使うのは「左右移動」と「ジャンプ」だけなので、それらが「押されているか」をチェックできるようにしておけばいい。
コードは以下の通り。
//IInput.as package{ public class IInput{ //i_Buttonとして指定するもの(enum欲しい) static public const BUTTON_L:int = 0; static public const BUTTON_R:int = 1; static public const BUTTON_JUMP:int = 2; static public const BUTTON_NUM:int = 3; //i_Buttonが現在押されているか public function IsPress(i_Button:int):Boolean{ //継承されてなければ、常にfalseを返す return false; } //毎フレーム呼んで、必要なら情報の更新を行う public function Update():void{ } } }
「BUTTON_〜」のところで、「左右移動」や「ジャンプ」などのボタンの種類を設定。
あとは、「押されているか(IsPress)」と「毎フレームの更新(Update)」を用意しておいて、キーボード入力クラスなどの方で実際の処理を作ってもらう。
=キーボード入力クラス=
次に、上の「仮想入力クラス(IInput)」を継承して、「キーボード入力クラス」を作成する。
コードは以下の通り。
//CInput_Keyboard.as package{ import flash.display.Stage; //Input import flash.ui.Keyboard; import flash.events.KeyboardEvent; public class CInput_Keyboard extends IInput{ //キーボードの入力を記憶しておく private var m_Input:Array;//Boolean[BUTTON_NUM] //初期化 public function CInput_Keyboard(i_Stage:Stage):void{ //キーボードの入力をOnKeyDownなどで受け取る { i_Stage.addEventListener(KeyboardEvent.KEY_DOWN, OnKeyDown); i_Stage.addEventListener(KeyboardEvent.KEY_UP, OnKeyUp); } //記憶を初期化 { m_Input = new Array(BUTTON_NUM); for(var i:int = 0; i < m_Input.length; i+=1){ m_Input[i] = false; } } } //キーが押されたら、対応する部分をtrueにする private function OnKeyDown(event:KeyboardEvent):void{ switch(event.keyCode){ case Keyboard.LEFT: m_Input[BUTTON_L] = true; break; case Keyboard.RIGHT: m_Input[BUTTON_R] = true; break; case Keyboard.UP: m_Input[BUTTON_JUMP] = true; break; case Keyboard.SPACE: m_Input[BUTTON_JUMP] = true; break; } } private function OnKeyUp(event:KeyboardEvent):void{ switch(event.keyCode){ case Keyboard.LEFT: m_Input[BUTTON_L] = false; break; case Keyboard.RIGHT: m_Input[BUTTON_R] = false; break; case Keyboard.UP: m_Input[BUTTON_JUMP] = false; break; case Keyboard.SPACE: m_Input[BUTTON_JUMP] = false break; } //「上とスペースを同時押し」→「片方だけ離す」でジャンプがオフになることに注意 } //i_Buttonが現在押されているか override public function IsPress(i_Button:int):Boolean{ return m_Input[i_Button]; } // //毎フレーム呼んで、必要なら情報の更新を行う // override public function Update():void{ // } } }
やっていることは、「キーボードの入力があったら、m_Inputに記憶しておいて、"押されているかチェック"ではそのm_Input」を返す、ということだけ。
初期化時に「入力をOnKeyDownで受け取る」などの処理を追加して、m_Inputを「まだ何も押されていない」という状態にリセット。あとは「ボタンが押された(OnKeyDown)時に、m_Inputをtrueにする」という処理と「ボタンが離された(OnKeyUp)時に、m_Inputをfalseにする」という処理を追加して、IInputから継承した「IsPress」を「m_Inputを返す」という処理に変更した。
=実行確認=
以上のクラスを使い、画像を動かして実行確認を行う。
まずは入力クラスを用意する。
//Input private var m_Input:IInput;
というメンバを追加し、Initにて
{//Init Input m_Input = new CInput_Keyboard(stage); }
という風に初期化する。
あとは毎回Updateを呼びつつ、IsPressでボタンが押されたかどうかをチェックすればいい。
まずは「毎フレームUpdateという関数を呼んでもらう」ための処理を追加する。
//update import flash.events.Event;
でイベントをインポートして、Initにて
//毎フレームUpdateを呼ぶ { addEventListener("enterFrame", function(event:Event):void { Update(); }); }
という処理を追加して、Updateを毎回呼ぶようにする。
あとはそのUpdateにて、以下のようにして画像を動かせばいい。
//!毎フレーム更新のために呼ばれる関数 private function Update():void{ //入力の更新 m_Input.Update(); //入力に応じた画像の移動 if(m_Input.IsPress(IInput.BUTTON_L)){ m_TestImage.x -= 1; } if(m_Input.IsPress(IInput.BUTTON_R)){ m_TestImage.x += 1; } if(m_Input.IsPress(IInput.BUTTON_JUMP)){ m_TestImage.y -= 1; } }
ちなみに、m_TestImageには、前回ImageManager.LoadImage_Player()で作った画像が入っているものとする。
以上で、入力の実行確認までできた。来週はようやく物理エンジンに入る。ただ、バージョンが以前とは異なるので、2日に1回くらいの更新頻度になるかもしれない。
一応、現在のデータをActionTemplate1.zipにまとめておいた。(画像はhttp://forever.sakura.ne.jp/index.htmlのものを、抜き色を独自に作って使わせてもらっている)