MovieClipインスタンスを矢印キーで上下左右に動かす例のご紹介です(図001)。ただし、少しひねりを加えて、キーを押し続けたときに入力が繰返される速さではなく、フレームレートで進むようにします。
図001■MovieClipインスタンスを矢印キーで上下左右に動かす

お題はFLASH-japanの「fpsに同期したmcの移動」で上がったものです。もっとも、この回答ではつくりを単純にするために、乱暴なスクリプトになっています。そこを少し整えて、簡単な説明を加えます。
まず、キー入力の基本的な扱いについては、gihyo.jp連載「ActionScript 3.0で始めるオブジェクト指向スクリプティング」第13回「キーボードによる操作」をお読みください。InteractiveObject.keyDownイベント(定数KeyboardEvent.KEY_DOWN)のリスナー関数が受取るKeyboardEventオブジェクトのKeyboardEvent.keyCodeプロパティで押されたキーのコードがわかります。そこでキーの振分けをどうするかが第1の課題です。
第2の課題は、矢印キーを押し続けたときの扱いです。InteractiveObject.keyDownイベントは、押している間繰返し生じます。しかし、初めに押したときフレームレートのアニメーションを開始し、キーを放したら止めるようにします。そのためには、繰返されるイベントは除けなければなりません(前掲FLASH-japanの回答ではこの処理を省いています)。
ふたつ目の課題から先にかたづけましょう。以下のスクリプトのように、初めのInteractiveObject.keyDownイベントで押したキーのコードを変数(nPressedKey)にとります。続くイベントではそのコードが変わらないかぎり、中身の処理は端折ります。InteractiveObject.keyUpイベント(定数KeyboardEvent.KEY_UP)が起きたら、変数は初期化します。
var nPressedKey:uint = 0;
stage.addEventListener(KeyboardEvent.KEY_DOWN, xKeyDown);
stage.addEventListener(KeyboardEvent.KEY_UP, xKeyUp);
function xKeyDown(eventObject:KeyboardEvent):void {
var nKeyCode:uint = eventObject.keyCode;
if (nKeyCode != nPressedKey) {
nPressedKey = nKeyCode;
// 中身の処理
trace(nKeyCode); // 確認用
}
}
function xKeyUp(eventObject:KeyboardEvent):void {
nPressedKey = 0;
}
初めの課題の押されたキーによる振分けは、条件判定によるのが定石でしょう。ここではswitch-caseステートメントを使うと、スクリプトが見やすくなります。もちろん、ifステートメントでも差支えありません。switch-caseステートメントにより矢印キーの操作を切り分けるスクリプトについては、前出「ActionScript 3.0で始めるオブジェクト指向スクリプティング」第14回「キー操作とif以外の条件判定」で詳しく解説しています。このやり方にしたがって整えたのが、つぎのスクリプト001です。矢印キーで動かすMovieClipシンボルのフレームアクションとして加えます。
スクリプト001■矢印キーの操作をswitch-caseステートメントで切り分ける// MovieClip: 矢印キーで動かすMovieClipシンボル
var nMove:Number = 0;
var nPressedKey:uint = 0;
stage.addEventListener(KeyboardEvent.KEY_DOWN, xKeyDown);
stage.addEventListener(KeyboardEvent.KEY_UP, xKeyUp);
function xKeyDown(eventObject:KeyboardEvent):void {
var nKeyCode:uint = eventObject.keyCode;
if (nKeyCode != nPressedKey) {
xRemoveAllEventListeners();
switch (nKeyCode) {
case Keyboard.LEFT :
nPressedKey = nKeyCode;
nMove = -1;
addEventListener(Event.ENTER_FRAME, xMoveX);
break;
case Keyboard.RIGHT :
nPressedKey = nKeyCode;
nMove = 1;
addEventListener(Event.ENTER_FRAME, xMoveX);
break;
case Keyboard.UP :
nPressedKey = nKeyCode;
nMove = -1;
addEventListener(Event.ENTER_FRAME, xMoveY);
break;
case Keyboard.DOWN :
nPressedKey = nKeyCode;
nMove = 1;
addEventListener(Event.ENTER_FRAME, xMoveY);
break;
}
}
}
function xKeyUp(eventObject:KeyboardEvent):void {
nPressedKey = 0;
xRemoveAllEventListeners();
}
function xMoveX(eventObject:Event):void {
x += nMove;
}
function xMoveY(eventObject:Event):void {
y += nMove;
}
function xRemoveAllEventListeners():void {
removeEventListener(Event.ENTER_FRAME, xMoveX);
removeEventListener(Event.ENTER_FRAME, xMoveY);
}
[ムービープレビュー]を確かめると、上下左右の矢印キーをおしたとき、その方向にインスタンスがフレームレートで移動します。なお、EventDispatcher.removeEventListener()メソッドを呼出したとき(関数xRemoveAllEventListeners())、第2引数に渡したリスナーがイベントに登録されていなくてもとくに問題は生じません。
キーコードは正の整数で一意に定められています。重複しない整数はインデックスとして使うことができ、配列ととても相性がよいです。配列の基本的な扱い方とキーコードへの適用について、前出「ActionScript 3.0で始めるオブジェクト指向スクリプティング」第15回「配列を使ったキーコードとプロパティの扱い」で詳しく解説しました。このやり方で整えたのがつぎのスクリプト002です。
スクリプト002■矢印キーのコードを配列により切り分ける// MovieClip: 矢印キーで動かすMovieClipシンボル
var nMove:Number = 0;
var nPressedKey:uint = 0;
var moveFunction:Function;
var movements:Array = [];
movements[Keyboard.LEFT] = [-1, xMoveX];
movements[Keyboard.RIGHT] = [1, xMoveX];
movements[Keyboard.UP] = [-1, xMoveY];
movements[Keyboard.DOWN] = [1, xMoveY];
stage.addEventListener(KeyboardEvent.KEY_DOWN, xKeyDown);
stage.addEventListener(KeyboardEvent.KEY_UP, xKeyUp);
function xKeyDown(eventObject:KeyboardEvent):void {
var nKeyCode:uint = eventObject.keyCode;
if (nKeyCode != nPressedKey) {
xRemoveAllEventListeners();
var movement:Array = movements[eventObject.keyCode];
if (movement) {
nPressedKey = nKeyCode;
nMove = movement[0];
moveFunction = movement[1];
addEventListener(Event.ENTER_FRAME, moveFunction);
}
}
}
function xKeyUp(eventObject:KeyboardEvent):void {
nPressedKey = 0;
xRemoveAllEventListeners();
}
function xMoveX(eventObject:Event):void {
x += nMove;
}
function xMoveY(eventObject:Event):void {
y += nMove;
}
function xRemoveAllEventListeners():void {
removeEventListener(Event.ENTER_FRAME, xMoveX);
removeEventListener(Event.ENTER_FRAME, xMoveY);
}
前出「配列を使ったキーコードとプロパティの扱い」で示したスクリプトと大きく異なるのは、配列にプロパティの文字列ではなく、関数(xMoveX()またはxMoveY())の参照を納めたことです。プロパティを直接いじるより、関数で扱う方が安全で応用範囲も広がります[*1]。さらに、配列をVectorオブジェクトに置換えると、扱いがより速くなります。詳しくは「キーボードのキー操作をVectorオブジェクトで扱う」をお読みください。
[*1] さらに汎用性を高めた考え方としては、FumioNonaka.com「条件分岐をポリモーフィズムに置換える」をご参照ください。