読者です 読者をやめる 読者になる 読者になる

ActionScript3 でネームスペース使ったキーイベント監視ユーティリティ作りました

AS3 のキーイベント監視でなんかいい方法ないかなー、と考えていたら良い方法が思いついたので実装してみた、らかなり便利な気がするので公開してみます。

通常のキーイベントの監視では addEventListener(KeyboardEvent.KEY_DOWN, func) で関数を登録して switch で event.keyCode 判別して Shift が押されてるか Ctrl が押されてるかによって云々、でかなりめんどくさいです。でもこの KeyTypeListener を使うと驚き300%(当社比)の方法でキーイベントを定義できます。

// 読み込んで
import com.rails2u.utils.KeyTypeListener;
import com.rails2u.utils.key_down;
// ネームスペース利用して
use namespace key_down;

// attach して stage で key が押されたときに this が target なオブジェクトになるようにして
KeyTypeListener.attach(stage, this);

// key_down ネームスペースに関数を定義するだけ
key_down function DOWN():void {
    currentChild.y += 1;
}

key_down function UP():void {
    currentChild.y -= 1;
}

AS3 は独自のネームスペースを使い関数定義ができるためにこういうことができるので超便利です。もっといろんなキー定義の方法のサンプルは

なんかに。INSERT/DELETE/UP とか flash.ui.Keyboard で定義されてる定数は全部そのまんま定義できます。

key_down function DELETE():void {

char 一文字で書くとその呼び出しになったり

key_down function j():void {
    DOWN();
}

大文字で定義すれば Shift + j で呼び出されたり

key_down function J():void {

CTRL + j もこんな感じだったり

key_down function CTRL_j():void {

CTRL + SHIFT + j もこんな感じだったり

key_down function CTRL_J():void {

数字のキーは頭に_つければ定義できたり

key_down function _1():void {

key_down じゃなくて key_up なネームスペースで定義すれば KEY_UP イベントのとき呼び出されたり

key_up function a():void {

引数つきで関数を定義すると、第一引数には KeyboardEvent なイベントインスタンスが入ってきたり

key_down function v(event:KeyboardEvent):void {

と割となんでもできる感じです。また、before, after という名前の関数を定義すると毎回キーが押されると確実にそれが呼び出されます。

key_down function a(event:KeyboardEvent):void {
key_down function before(event:KeyboardEvent):void {
key_down function after(event:KeyboardEvent):void {

とか定義されているときに a を押せば、before, a, after の順で関数が呼ばれ、定義されてないキーを押せば before, after だけが呼び出されます。そのため特殊なキー操作をしたい時は before/after にフックすれば柔軟に対応ができると思います。

いろんなオブジェクトに attach 可能

もちろん stage 以外(InteractiveObject 継承クラスならなんでも)にも attach できるため、こんな使い方も可能です。

キーで移動できるような Sprite 継承クラスを作ります。

import flash.display.Sprite;
import com.rails2u.utils.KeyTypeListener;
import com.rails2u.utils.key_down;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
use namespace key_down;

class Ball extends Sprite
{
    private var radius:Number;
    private var color:uint;
        
    public function Ball(color:uint, radius:uint) {
        this.color = color;
        this.radius = radius;
        KeyTypeListener.attach(this);
        init();
    }
        
    public function init():void {
        graphics.beginFill(color);
        graphics.drawCircle(0,0,radius);
        graphics.endFill();
    }
            
    key_down function DOWN(e:KeyboardEvent):void {
        y += 1;
    }
        
    key_down function UP(e:KeyboardEvent):void {
        y -= 1;
    }
        
    key_down function LEFT(e:KeyboardEvent):void {
        x -= 1;
    }
        
    key_down function RIGHT(e:KeyboardEvent):void {
        x += 1;
    }
    
    // stop event
    key_down function after(e:KeyboardEvent):void {
        e.stopPropagation();
    }
}

自分自身を attach して、自分の key_down ネームスペースなメソッドにキーイベントがきたら委譲できるようにしておきます。

KeyTypeListener.attach(this);

で、メインとなる Sprite なクラスでは

public function KeyTypeListenerExample2() {
    stage.align = StageAlign.TOP_LEFT;
    KeyTypeListener.attach(stage, this);
    init();
}

key_down function after(e:KeyboardEvent):void {
    currentChild.dispatchEvent(e);
}

のように、フォーカスを持っている子供(ここではBall)にキーイベントを dispatchEvent で投げてやるとそのまま伝搬してうまく動くという仕組みです。
Flex2 な UICompornent ではこんな感じ(もっと高度ですが)で、現在フォーカスがある UICompornent に KeyboardEvent が投げられるため、Flex2 な ui クラスもこの方法で簡単に特定キーが押されたときの処理を記述することができるようになります。

というわけで

as3 namespace 便利!ちなみに namespace のキーイベントでの活用方法思いついたのが yossy さんAS3Unitで test ネームスペースをうまく活用してるのを見たからでした。他に namespace 活用しているライブラリみたことないお…。また KeyTypeListener の Test も AS3Unit で書かれてます:D。

その他ライブラリも公開

にその他汎用的に使えそうなのをまとめて公開しました。log() 関数がグローバルな領域に定義されてるので割と恐ろしいライブラリとなってます。自分便利さ優先で。でも import 文書かなくて動く関数便利なんすよ!!あとデフォルトの AS3 の toString の出力がしょぼいので ObjectInspecter はなにげに便利な。
デフォルトの Array.toString とかひどくて

var a:Array = [[1,2], [3,4]];
trace(a); // 1,2,3,4

とか表示されるのもよしなに表示してくるし、不明なオブジェクトならリフレクションで情報読んで

#<flash.display::Sprite:[object Sprite]>

みたいに表示してくれます。
他の ColorUtil とかしょぼいのでみないでください。Taka さんの ColorUtil その他いろんなクラス公開して欲しい!と書くと公開してくれる仕組みはまだありません!?

教えて!Flex Builder 2

ライブラリは Flex Builder 2 のライブラリプロジェクトで管理してるんですが、ライブラリプロジェクトだと as ファイルから swf にコンパイルできなくて test ができないという…。ライブラリプロジェクトでうまく test の as コンパイルして動かしてる人がいたらどんな方法でやってるか教えて欲しいです。