ゲームを作るとき取得できると便利かもしれないキー入力状況情報パターン
まえがき
キーボードを使うゲームは、当然キー入力の状況を受け取らないといけません。
どのキーが押されているか、押されていないか等。
Aキーが押されているか、押されていないかだけでなく、
もうちょっといろんなパターンでのキー入力状況を簡単に取得できるようにしておくと、
いちいちaddEventLisならなくて良いので便利です。
パターン1 - 押されているか、押されていないか
一番スタンダードなキー入力の情報です。
Aキーを押しているならtrue、押されていないならfalseを取得できます。
package { import flash.display.Sprite; import flash.events.KeyboardEvent; import flash.ui.Keyboard; /** * キー状態 */ public class KeyState extends Sprite { private var _aKey:Boolean; // Aキー /** Aキー */ public function get aKey():Boolean { return _aKey; } /** * コンストラクタ */ public function KeyState() { _aKey = false; addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown); addEventListener(KeyboardEvent.KEY_UP, onKeyUp); } /** * キーダウンイベント処理 * * @param event イベント */ private function onKeyDown(event:KeyboardEvent):void { switch (event.keyCode) { case 90: _aKey = true; break; default: break; } } /** * キーアップイベント処理 * * @param event イベント */ private function onKeyUp(event:KeyboardEvent):void { switch (event.keyCode) { case 90: _aKey = false; break; default: break; } } } }
パターン2 - KEY_DOWNイベントっぽく
メニューをキーボードで操作して、項目を選択するような場合、
パターン1だと目的の項目へ選択カーソルをやるのに苦労します。
例えば↓キーを押した場合、わずかに長押ししただけでカーソルは下へガーっと行きすぎてしまったり。
通常こういう場合はKEY_DOWNイベントをaddEventLisなるものですが、
いちいちイベントイベントするのが面倒なので、
変数を参照するだけでこのキー入力状況を取得できるようにしようと思います。
package { import flash.display.Sprite; import flash.events.KeyboardEvent; import flash.ui.Keyboard; /** * キー状態 */ public class KeyState extends Sprite { private var _sysAKey:Boolean; // システム用Aキー /** システム用Aキー */ public function get sysAKey():Boolean { return _sysAKey; } /** * コンストラクタ */ public function KeyState() { _sysAKey = false; addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown); addEventListener(KeyboardEvent.KEY_UP, onKeyUp); } /** * システム用キー初期化 * 全体処理の最後で実行する */ public function initSystemKey():void { _sysAKey = false; } /** * キーダウンイベント処理 * * @param event イベント */ private function onKeyDown(event:KeyboardEvent):void { switch (event.keyCode) { case 90: _sysAKey = true; break; default: break; } } /** * キーアップイベント処理 * * @param event イベント */ private function onKeyUp(event:KeyboardEvent):void { switch (event.keyCode) { case 90: _sysAKey = false; break; default: break; } } } }
initSystemKeyメソッドを処理の最後に呼び出すようにすれば、
ほぼKEY_DOWNイベントっぽいキー入力状況を取得できます。
private var _keyState:KeyState; // キー状態 /** * エンターフレームイベント処理 * * @param event イベント */ private function onEnterFrame(event:Event):void { exec(); // メインの処理 _keyState.initSystemKey(); // 処理の最後に実行 }
パターン1との違いは以下のような感じ。
パターン1 パターン2 キー状況 true true ←Aキー押す(以下押しっぱなし) true false true false true false true false true true true true false false ←Aキー離す false false false false false false false false false false
厳密にキー入力状況を取得したい場合は当然KEY_DOWNイベントを使うしかないですが、
そうでない場合は楽じゃないかと。
パターン3 - キー押しっぱなし状況
Aキーを2フレーム以上押しっぱなしにしている場合true、そうでない場合falseを取得します。
どこで使うかというと、例えばアクションゲームの場合。
ジャンプを↑キーでする場合、押しっぱなしの判定をしなければ↑キーを押しっぱなしにすることで、
地上に降りるたびに自動的にジャンプしてしまいます。
その場その場で「↑キーを離さなかったならジャンプしない」という処理を入れるのは、結構しんどいです。(相当しんどい)
ジャンプだけでなく、攻撃動作しかり、使いどころはたくさんあります。
以下のソースのKeyStateクラスはパターン1のものです。
以下のクラスはキー入力の状況ではなく、ゲーム内の各物体が持っている操作用のキー情報です。
Aキーを押したとき、KeyStateクラスを介してこのクラス内の攻撃キー変数にtrue,falseを設定することで、
その物体の攻撃キーを押した場合のふるまい等をさせます。
package { /** * オブジェクトのキー状態 */ public class ObjectKeyState { private var _attackKey:Boolean; // 攻撃キー private var _attackKeyKeepFlg:Boolean; // 攻撃キー押しっぱなしならtrue /** 攻撃キー */ public function get attackKey():Boolean { return _attackKey; } /** 攻撃キー押しっぱなしフラグ */ public function get attackKeyKeepFlg():Boolean { return _attackKeyKeepFlg; } /** * コンストラクタ */ public function ObjectKeyState() { _attackKey = false; _attackKeyKeepFlg = false; } /** * キー状態設定 * * @param keyState キー状況 */ public function setKeyState(keyState:KeyState):void { // 押しっぱなし状態判定 if (_attackKey && keyState.attackKey) { _attackKeyKeepFlg = true; } else { _attackKeyKeepFlg = false; } // キー状態設定 _attackKey = keyState.attackKey; } } }
例えば攻撃キーを押した場合攻撃するという処理をする場合
private var _state:ObjectKeyState; private function exec():void { if (_state.attackKey && !_state.attackKeyKeepFlg) { // 攻撃処理 } }
とすることで、攻撃キー押しっぱなしの場合攻撃処理が実行されないようにできます。
あとがき
これでいちいちイベントイベントさせなくても、
とりあえず全部ENTER_FRAMEの処理内で解決できそうですね!