ActionScript 3.0で始めるオブジェクト指向スクリプティング

第15回 配列を使ったキーコードとプロパティの扱い

この記事を読むのに必要な時間:およそ 4 分

配列アクセス演算子でプロパティを操作する

上下の矢印キーの操作も処理に加えようとしたとき,困ったことに気づく。その場合,操作するインスタンスのプロパティを,切替えなければならないということだ。つまり,たとえばつぎのステートメントで,プロパティxyに替える必要がある。

x += 1;

しかし,プロパティをそのまま変数に入れて,処理することはできない。たとえば,つぎのようなスクリプトを書いても,Number型の変数(myProperty)にプロパティxの数値が代入され,その値に1が加算されるだけだ。xプロパティが操作されることにはならない。

var myProperty:Number = x;
myProperty += 1;

そこで,配列アクセス演算子[ ] のもうひとつの使い方を学習しよう。配列アクセス演算子[ ] は,配列つまりArrayインスタンスだけでなく,他のインスタンスのプロパティにアクセスするために使うこともできる。

たとえば,フレームアクションで,タイムラインに配置されたインスタンスmy_mcの水平座標を10ピクセル右に動かすには,今まではつぎのようにステートメントを記述した。

my_mc.x += 10;

この同じ処理は,配列アクセス演算子を使って,つぎのように書替えることができる。

my_mc["x"] += 10;

配列アクセス演算子[ ] を用いたステートメントのポイントは,プロパティを文字列で記述するということだ。したがって,その文字列は変数で指定することもできる。

var myProperty:String = "x";
my_mc[myProperty] += 10;

これが可能であれば,文字列のプロパティ名を変更することにより,操作するインスタンスのプロパティは変えられる。しかし,ここでひとつ注意しなければならない。つぎのステートメントは,エラーになってしまうということだ図2⁠。

["x"] += 10;

図2 ターゲットなしに配列アクセス演算子[ ] を使うと配列の作成になる

図2 ターゲットなしに配列アクセス演算子[ ] を使うと配列の作成になる

なぜなら,上のステートメントの左辺は,インスタンスのxプロパティにアクセスしているのではない。文字列"x"をエレメントとしてもつ配列をつくってしまっているのだ。Arrayインスタンスそのものに,直接数値を加算することはできない。だから,エラーになる

配列アクセス演算子[ ] は,ドット演算子.と基本的に同じ役目だ。ドット.の左には,必ずプロパティの持ち主(ターゲット)となるべきインスタンスを指定しなければならない。スクリプトを記述しているインスタンス自身がターゲットであれば,thisキーワードを指定する。

this["x"] = 10;

残る小さな問題は,プロパティの文字列を配列(keys_array)にどうやって指定するかだ。キーコードをインデックスにして,プロパティの文字列に加えて移動方向を示す数値(±1)も納めなければならない。つまり,ひとつのインデックスにふたつの値を指定する必要がある。しかし,この点は実は本稿の最初に答えが出ている。

複数の値をひとつにしたければ,Arrayインスタンスを使えばよかった。つまり,配列エレメントとして配列を指定すればよいのだ。配列は,何重にでも入れ子にすることができる。そこで,上下左右の矢印キーのキーコードに対して,つぎのように配列をエレメントとして代入することにしよう。

var keys_array:Array = new Array();
keys_array[Keyboard.LEFT] = ["x", -1];
keys_array[Keyboard.RIGHT] = ["x", 1];
keys_array[Keyboard.UP] = ["y", -1];
keys_array[Keyboard.DOWN] = ["y", 1];

入れ子の配列の中のエレメントを取得するには,一旦エレメントの配列を取出し,改めてそのインデックスを指定すればよい※3⁠。たとえば,上記配列から左矢印キーのキーコードのインデックスに納めたプロパティの文字列と方向の数値を調べるには,つぎのようなステートメントを記述する。

var key_array:Array = keys_array[Keyboard.LEFT];
trace(key_array[0], key_array[1]);   // 出力: x -1

これで,上下左右の矢印キーの操作を,配列で処理する準備は整った。スクリプトは以下のとおりだスクリプト2⁠。なお今度は,配列を格納した変数(key_array)if条件に指定されている。この場合,変数に配列が入っていればtrue入っていなければfalseと評価される※4⁠。

スクリプト2 操作するプロパティを配列のキーコードのインデックスに定める

// MovieClip: キー操作で動かすインスタンス
var nMove:int = 1;
var nShiftMove:int = 10;
var keys_array:Array = new Array();

keys_array[Keyboard.LEFT] = ["x", -1];
keys_array[Keyboard.RIGHT] = ["x", 1];
keys_array[Keyboard.UP] = ["y", -1];
keys_array[Keyboard.DOWN] = ["y", 1];
stage.addEventListener(KeyboardEvent.KEY_DOWN, xKeyDown);
function xKeyDown(eventObject:KeyboardEvent):void {
  var nKeyCode:int = eventObject.keyCode;
  var bShiftKey:Boolean = eventObject.shiftKey;
  xMove(nKeyCode, bShiftKey);

}
function xMove(nKeyCode:int, bShiftKey:Boolean):void {
  var key_array:Array = keys_array[nKeyCode];
  if (key_array) {
    this[key_array[0]] += key_array[1]*xGetPixels(bShiftKey);
  }
}

function xGetPixels(bShiftKey:Boolean):int {
  var nPixels:int = bShiftKey ? nShiftMove : nMove;
  return nPixels;
}

[ムービープレビュー]で試すと,前回作成したスクリプト2と動作は変わらない。しかし,関数xMove()が,きわめてすっきりとした記述になったことを確認してほしい。次回は,またお題を変えて,疑似3D風のアニメーションを作成する予定だ。

※3)

入れ子になった配列の中のエレメントは,入れ子の配列を別の変数に取出さなくても,配列アクセス演算子[ ] をふたつ続けて指定して調べることもできる。

trace(keys_array[Keyboard.LEFT][0], keys_array[Keyboard.LEFT][1]);   // 出力: x -1
※4)
Arrayなどのクラスで型指定された変数にundefinedを代入すると,値がないことを示すnullという値に変わる。if条件として指定された値が,クラスのインスタンスだったらtruenullfalseと評価される。

今回解説した次のサンプルファイルがダウンロードできます。

著者プロフィール

野中文雄(のなかふみお)

ソフトウェアトレーナー,テクニカルライター,オーサリングエンジニア。上智大学法学部卒,慶応義塾大学大学院経営管理研究科修士課程修了(MBA)。独立系パソコン販売会社で,総務・人事,企画,外資系企業担当営業などに携わる。その後,マルチメディアコンテンツ制作会社に転職。ソフトウェアトレーニング,コンテンツ制作などの業務を担当する。2001年11月に独立。Web制作者に向けた情報発信プロジェクトF-siteにも参加する。株式会社ロクナナ取締役(非常勤)。

URLhttp://www.FumioNonaka.com/

著書