[AS3] キーボードのキー操作を扱うふたつの手法 [Edit]

キーの押し下げ操作は、InteractiveObject.keyDownイベント(定数KeyboardEvent.KEY_DOWN)で扱います。リスナー関数が引数に受取るイベントオブジェクト(KeyboardEvent.keyCodeプロパティ)から押したキーのコードがわかりますので、その整数値に応じて処理を振分けます。

定石といえるのは、キーコードの整数値を条件判断で切り分けることです。もっとも、キーコードはすべて値がユニークですので、配列との相性がよいです。処理したいキーコードのインデックスに、必要な情報を納めると、条件判定が要らなくなります。

01 キーコードを条件判定で振分ける

このたびのお題として、タイムラインに配置したMovieClipインスタンス(my_mc)を、キーボードの矢印キーで上下左右に動かしてみます(図001)。まず定石は、リスナー関数の引数からキーコードを調べて、switchステートメントでキーコードに応じた処理を書くことでしょう。

図001■ タイムラインに配置したMovieClipインスタンスを矢印キーで上下左右に動かす
AS3_OptimizingPerformance_01_02_008.png

以下のフレームアクション(スクリプト001)は、タイムラインに置いたインスタンス(my_mc)をキーボードの矢印キーで上下左右に1ピクセルずつ動かします(スクリプトの処理について詳しくは、gihyo.jp「ActionScript 3.0で始めるオブジェクト指向スクリプティング」第14回「キー操作とif以外の条件判定」をお読みください)。

スクリプト001■キーコードを条件判定して処理する
stage.addEventListener(KeyboardEvent.KEY_DOWN, use_switch);
function use_switch(eventObject:KeyboardEvent):void {
	switch (eventObject.keyCode) {
		case (Keyboard.LEFT) :
			my_mc.x -=  1;
			break;
		case (Keyboard.RIGHT) :
			my_mc.x +=  1;
			break;
		case (Keyboard.UP) :
			my_mc.y -=  1;
			break;
		case (Keyboard.DOWN) :
			my_mc.y +=  1;
			break;
	}
}

02 キーコードをインデックスとして配列に処理を与える

キーコードはすべて値がユニークですので、配列との相性がよいです。処理したいキーコードのインデックスに、必要な情報を納めると、条件判定が要らなくなります。今回のお題で必要な情報は、操作するプロパティと設定する値です。そこで、このふたつを子の配列に入れて、親配列のキーコードのイ ンデックスに納めます。

この考え方で矢印キーによる処理を行うのが、以下のフレームアクション(スクリプト002)です。配列の上下左右の矢印キーのキーコードとなるインデックスに、操作したいプロパティ(DisplayObject.xDisplayObject.y)の文字列と設定値を入れ子の配列にして、親配列(operations_array)のエレメントに納めています。後は、リスナー関数でキーコードを調べて、親配列(operations_array)から操作情報のエレメントを取出し、配列アクセスでインスタンス(my_mc)のプロパティに値を設定します。

スクリプト002■キーコードをインデックスにした配列エレメントで操作する
var operations_array:Array = [];
operations_array[Keyboard.LEFT] = ["x",-1];
operations_array[Keyboard.RIGHT] = ["x",1];
operations_array[Keyboard.UP] = ["y",-1];
operations_array[Keyboard.DOWN] = ["y",1];
stage.addEventListener(KeyboardEvent.KEY_DOWN, useArray);
function useArray(eventObject:KeyboardEvent):void {
	var operation_array:Array = operations_array[eventObject.keyCode];
	if (operation_array) {
		var property_str:String = operation_array[0];
		var pixels:Number = operation_array[1];
		my_mc[property_str] +=  pixels;
	}
}

キーコードが上下左右の矢印キーでなければ、親配列にエレメントがありません。前掲スクリプト002のif条件で、その判定を行っています(スクリプトの処理について詳しくは、gihyo.jp「ActionScript 3.0で始めるオブジェクト指向スクリプティング」第15回「配列を使ったキーコードとプロパティの扱い」をお読みください)。

スクリプト002は、操作の情報を配列にまとめていますので扱いやすく、仕組みさえ変わらなければ操作対象のキーとプロパティを増やすのも簡単です。定石どおりキーコードをswitchステーメントで振分ける前掲スクリプト001は、スクリプト002と比べて処理が最適化されます。

wonderflに上げたサンプルでは、ふたつのスクリプトで速度は2倍近くの開きがあるようです。もっとも、キー操作を1秒間に何百回も処理することは、あまり考えられません。すると、最適化で劣ることはわかったうえで、扱いやすさから配列による処理を選ぶこともあり得るでしょう。

Evaluating key codes with switch statement vs an array - wonderfl build flash online

[追記2011/02/14] 続編として「キーボードのキー操作をVectorオブジェクトで扱う」を書きました。併せてご参照ください。

コメント

この記事にコメントを書く

記事に対するテクニカルな質問はご遠慮ください(利用規約)。

その他の記事