キー入力のレベル、トリガ、リピートを取得
ActionScriptでゲームを作りたいんですよ。
9割がお蔵入りなんて話もありますが、まあ気にしないでいきます。
とりあえず入力まわりから攻めようということで、キー情報のレベル、トリガ、リピートを取得するクラスを作ってみました。
KeyboardEvent.KEY_DOWNはキーを押した瞬間だけ発生するイベントかと思いきや、そうでもないんですね。
Windows自体のオートキーリピートのせいで、押しっぱなしにしてると毎フレームKEY_DOWNが発生してしまいます。
仕方ないので押してる時間をカウントすることで対処してみました。どっちみちリピートでもカウントすることになりますしね。
というわけでサンプルはこちら。カーソルキーの上下を押して挙動の違いを確認してみてください。
ソースを見たい方は続きをどうぞ。
9割がお蔵入りなんて話もありますが、まあ気にしないでいきます。
とりあえず入力まわりから攻めようということで、キー情報のレベル、トリガ、リピートを取得するクラスを作ってみました。
KeyboardEvent.KEY_DOWNはキーを押した瞬間だけ発生するイベントかと思いきや、そうでもないんですね。
Windows自体のオートキーリピートのせいで、押しっぱなしにしてると毎フレームKEY_DOWNが発生してしまいます。
仕方ないので押してる時間をカウントすることで対処してみました。どっちみちリピートでもカウントすることになりますしね。
というわけでサンプルはこちら。カーソルキーの上下を押して挙動の違いを確認してみてください。
ソースを見たい方は続きをどうぞ。
Flege.as
package { import flash.display.*; import flash.events.*; import flash.text.*; import com.txt_nifty.sketch.flege.*; [SWF(width="320", height="240", backgroundColor="0xffffff", frameRate="60")] public class Flege extends Sprite { public var m_pad:GPad; public var m_textArr:Array; //! コンストラクタ public function Flege() { m_pad = new GPad; this.stage.addEventListener(KeyboardEvent.KEY_DOWN, function(e:KeyboardEvent):void { m_pad.onKeyDown(e); } ); this.stage.addEventListener(KeyboardEvent.KEY_UP, function(e:KeyboardEvent):void { m_pad.onKeyUp(e); } ); this.addEventListener(Event.ENTER_FRAME, update); m_textArr = new Array(3); for(var i:int = 0; i < 3; i++) { m_textArr[i] = new TextField; m_textArr[i].x = 100 * i; addChild(m_textArr[i]); } m_textArr[0].text = "Level"; m_textArr[1].text = "Trigger"; m_textArr[2].text = "Repeat"; } //! 毎フレームの処理 protected function update(event:Event):void { var padL:uint = m_pad.getL(); var padT:uint = m_pad.getT(); var padR:uint = m_pad.getR(); var d:int = 16; if (padL & GPad.UP) m_textArr[0].y -= d; if (padL & GPad.DOWN) m_textArr[0].y += d; if (padT & GPad.UP) m_textArr[1].y -= d; if (padT & GPad.DOWN) m_textArr[1].y += d; if (padR & GPad.UP) m_textArr[2].y -= d; if (padR & GPad.DOWN) m_textArr[2].y += d; for(var i:int = 0; i < 3; i++) { if (m_textArr[i].y < 0) m_textArr[i].y = d * 10; if (m_textArr[i].y > d * 10) m_textArr[i].y = 0; } m_pad.update(); } } }
GPad.as
package com.txt_nifty.sketch.flege { import flash.events.KeyboardEvent; import flash.ui.Keyboard; //! キー入力 public class GPad { public static const UP:uint = 0x0001; public static const DOWN:uint = 0x0002; public static const LEFT:uint = 0x0004; public static const RIGHT:uint = 0x0008; public static const A:uint = 0x0010; public static const B:uint = 0x0020; public static const START:uint = 0x0040; public static const SELECT:uint = 0x0080; protected static const MAX_KEYS:uint = 16; //!< キーの最大数 protected static const DELAY:uint = 30; //!< オートリピートまでの時間(2以上) protected static const INTERVAL:uint = 3; //!< オートリピートの間隔 protected var m_retL:uint; //!< 外部用レベル値 protected var m_retT:uint; //!< 外部用トリガ値 protected var m_retR:uint; //!< 外部用リピート値 protected var m_padL:uint; //!< 内部用レベル値 protected var m_cntArr:Vector.; //!< キーを押し続けている時間 //! コンストラクタ public function GPad():void { m_cntArr = new Vector. (MAX_KEYS); clear(); } //! 状態のクリア public function clear():void { m_padL = 0; for(var i:int = MAX_KEYS-1; i >= 0; i--) { m_cntArr[i] = 0; } } //! アップデート public function update():void { m_retL = m_padL; m_retT = 0; m_retR = 0; for(var i:int = MAX_KEYS-1; i >= 0; i--) { var bit:uint = 1 << i; if (m_retL & bit) m_cntArr[i]++; else m_cntArr[i] = 0; if (m_cntArr[i] > DELAY + INTERVAL) m_cntArr[i] = DELAY; if (m_cntArr[i] == 1) { m_retT |= bit; m_retR |= bit; } else if (m_cntArr[i] == DELAY) { m_retR |= bit; } } } //! キーダウンイベントの処理 public function onKeyDown(e:KeyboardEvent):void { var pad:uint; switch(e.keyCode) { case Keyboard.UP: case Keyboard.NUMPAD_8: pad = UP; break; case Keyboard.DOWN: case Keyboard.NUMPAD_2: pad = DOWN; break; case Keyboard.LEFT: case Keyboard.NUMPAD_4: pad = LEFT; break; case Keyboard.RIGHT: case Keyboard.NUMPAD_6: pad = RIGHT; break; case 90: // 'Z' case Keyboard.BACKSPACE: case Keyboard.ESCAPE: pad = B; break; case Keyboard.SPACE: case 88: // 'X' pad = A; break; case Keyboard.CONTROL: pad = SELECT; break; case Keyboard.ENTER: case Keyboard.NUMPAD_ENTER: pad = START; break; } m_padL |= pad; } //! キーアップイベントの処理 public function onKeyUp(e:KeyboardEvent):void { var pad:uint; switch(e.keyCode) { case Keyboard.UP: case Keyboard.NUMPAD_8: pad |= UP; break; case Keyboard.DOWN: case Keyboard.NUMPAD_2: pad |= DOWN; break; case Keyboard.LEFT: case Keyboard.NUMPAD_4: pad |= LEFT; break; case Keyboard.RIGHT: case Keyboard.NUMPAD_6: pad |= RIGHT; break; case 90: // 'Z' case Keyboard.BACKSPACE: case Keyboard.ESCAPE: pad |= B; break; case Keyboard.SPACE: case 88: // 'X' pad |= A; break; case Keyboard.CONTROL: pad |= SELECT; break; case Keyboard.ENTER: case Keyboard.NUMPAD_ENTER: pad |= START; break; } m_padL &= ~pad; } //! レベル取得 public function getL():uint { return m_retL; } //! トリガ取得 public function getT():uint { return m_retT; } //! リピート取得 public function getR():uint { return m_retR; } } }
« FlMML - エクスプレッション | トップページ | 美味いフランス料理は美味い »
「ActionScript 3.0」カテゴリの記事
- FlMML - リングモジュレーターとSync(2009.07.26)
- FlMML - ファミコンDPCM(2009.05.16)
- キー入力のレベル、トリガ、リピートを取得(2009.05.06)
- FlMML - エクスプレッション(2009.05.03)
- FlMML - 引数つきマクロ(2009.04.12)
この記事へのコメントは終了しました。
コメント