トップ 差分 一覧 ソース 検索 ヘルプ PDF RSS ログイン

キーボードイベント_Flex

キーボードイベント

「KeyTest.as」というファイルを以下のように記述するとします。これは、矢印キーによりティーポットを移動させる例です。

import flash.events.*;
import flash.ui.*;

を先頭にて記載しておく必要があります。

package {
   import flash.display.*;
   import flash.text.*;
   import flash.utils.*;
   import flash.events.*;
   import flash.ui.*;              // Keyboard.LEFTなど

   public class KeyTest extends Sprite {
       private var m_Text:TextField;
       private var m_child:Sprite;             ///< ビットマップを貼り付けるスプライト

       private var m_posX:int, m_posY:int;     ///< キャラクタ位置
       
       private var m_teapot:Sprite;            ///< 画像用のスプライト

       // 画像リソース
       [Embed(source='teapot.png')]
       private var TeapotImage:Class;
       
       private var m_teapotImage:Bitmap;
       
       private var m_KeyFlag:int;              ///< キープッシュの情報

       public function KeyTest() {

           // 子のスプライトを作成
           m_child = new Sprite();

           // スプライト内をクリア(スプライトのサイズ固定用)
           m_child.graphics.clear();
           m_child.graphics.beginFill(0xe0ffe0);
           m_child.graphics.drawRect(0, 0, 300, 300);
           m_child.graphics.endFill();

           // キーイベントの追加
           this.stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
           this.stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);

           // テキストフィールドの作成
           m_Text = new TextField();
           m_Text.x = 8;
           m_Text.y = 8;
           m_Text.autoSize = "left";
           m_Text.textColor = 0x000000;
           m_Text.text = "";
           m_Text.selectable = false;
           m_child.addChild(m_Text);

           addChild(m_child);

           // teapot.pngの割り当て
           m_teapotImage = new TeapotImage();
           
           // 新しいスプライトにm_teapotImageを追加
           m_teapot = new Sprite();
           m_teapot.addChild(m_teapotImage);

           // ティーポットのスプライトをm_childの子として追加
           m_child.addChild(m_teapot);
           
           // キャラクタの位置
           m_posX = 50;
           m_posY = 50;
           
           // イメージの位置を変更
           m_teapot.x = m_posX;
           m_teapot.y = m_posY;
           
           m_KeyFlag = 0;
           
           // タイマーの追加
           var timer:Timer = new Timer(50, 0);     // 50 msごと
           timer.addEventListener(TimerEvent.TIMER, onTimer);
           timer.start();
       }
       
       /**
        * タイマーイベント
        */
       private function onTimer(evt:TimerEvent):void {
           
           if(m_KeyFlag & 0x0001) {
               if(m_posX > 0) m_posX -= 8;
           }
           if(m_KeyFlag & 0x0002) {
               if(m_posX < 300 - 48) m_posX += 8;
           }
           if(m_KeyFlag & 0x0004) {
               if(m_posY > 0) m_posY -= 8;
           }
           if(m_KeyFlag & 0x0008) {
               if(m_posY < 300 - 48) m_posY += 8;
           }
           
           // イメージの位置を変更
           m_teapot.x = m_posX;
           m_teapot.y = m_posY;
       }

       /**
        * キーダウンイベント
        */
       private function onKeyDown(event:KeyboardEvent):void {
           m_Text.text = "keyDown : keyCode = " + String(event.keyCode);
           
           if(event.keyCode == Keyboard.LEFT) {        // ←
               m_KeyFlag |= 0x0001;
           }
           if(event.keyCode == Keyboard.RIGHT) {       // →
               m_KeyFlag |= 0x0002;
           }
           if(event.keyCode == Keyboard.UP) {          // ↑
               m_KeyFlag |= 0x0004;
           }
           if(event.keyCode == Keyboard.DOWN) {        // ↓
               m_KeyFlag |= 0x0008;
           }
           
           if(event.keyCode == String("X").charCodeAt(0)) {
               m_Text.text = "keyDown : [X]";
           }
       }

       /**
        * キーアップイベント
        */
       private function onKeyUp(event:KeyboardEvent):void {
           m_Text.text = "keyUp : keyCode = " + String(event.keyCode);

           if(event.keyCode == Keyboard.LEFT) {        // ←
               m_KeyFlag &= ~0x0001;
           }
           if(event.keyCode == Keyboard.RIGHT) {       // →
               m_KeyFlag &= ~0x0002;
           }
           if(event.keyCode == Keyboard.UP) {          // ↑
               m_KeyFlag &= ~0x0004;
           }
           if(event.keyCode == Keyboard.DOWN) {        // ↓
               m_KeyFlag &= ~0x0008;
           }
       }
   }
}

実行すると以下のようになります。矢印キーにてティーポットが移動します。

キーボードイベントの登録

this.stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
this.stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);

にして、this(rootに相当)のstageにてキーボードイベントを登録します。「this.stage」にてaddEventListenerで登録することで、実行時のswfのどこにフォーカスがあってもキーボードイベントを取得することができるようになります。

this.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
this.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);

のように登録した場合は、マウスダウン時に

this.stage.focus = this;

とフォーカスのStageを明示する必要があります。また、この場合はマウスダウン時に対象Spriteに黄色い枠が出ることになり不恰好になってしまいます。

「KeyboardEvent.KEY_DOWN」にて、キーダウン時に第二引数の関数を呼びます。

「KeyboardEvent.KEY_UP」にて、キーアップ時に第二引数の関数を呼びます。

キーボードイベントの受け取り

private function onKeyDown(event:KeyboardEvent):void {
}
private function onKeyUp(event:KeyboardEvent):void {
}

のような書式にてキーボードイベントを受け取ります(privateじゃなくてもいいですが)。第一引数に「KeyboardEvent」型のクラスを指定します。

キーコードの取得

var code:int = event.keyCode;

にてキーコードが入ります。今回使用しているような矢印キーは「Keyboard.LEFT」「Keyboard.RIGHT」「Keyboard.UP」「Keyboard.DOWN」となっています。

その他の特殊キーコードは以下の表のとおり。

キーコード対応キー
Keyboard.LEFT[←]キー
Keyboard.RIGHT[→]キー
Keyboard.UP[↑]キー
Keyboard.DOWN[↓]キー
Keyboard.BACKSPACE[BackSpace]キー
Keyboard.DELETEKEY[Delete]キー
Keyboard.ENTER[Enter]キー
Keyboard.ESCAPE[Esc]キー
Keyboard.HOME[Home]キー
Keyboard.END[End]キー
Keyboard.PGDN[PageDown]キー
Keyboard.PGUP[PageUp]キー
Keyboard.SPACE[Space]キー
Keyboard.TAB[Tab]キー
Keyboard.SHIFT[Shift]キー

これ以外のアルファベットや数値は、

if(event.keyCode == String("X").charCodeAt(0)) {
}

のようにして判断できます("X"の部分をアルファベットや数値に置き換える)。

なお、ゲームのキャラが移動する場合など、キーの「同時押し」の認識が必要ですが、実際のキーイベントは同時押しでもわずかな時間差があると見て、

Down '←'
Down '↓'
Up   '←'
Up   '↓'

みたいなイベントが呼ばれた状態になります。この場合は、キャラは左下に移動させます。

ですので、上記ソースのようにキーボードイベントはキーボードのプッシュ・ポップ状態だけをフラグに持ってすぐに抜ける、移動処理はタイマーイベントでそのキーフラグを見て行う、といった分けた処理で行うほうがわかりやすいです。

Future's Laboratory 技術格納庫 2004-2013 Yutaka Yoshisaka.