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

第15回←教材はこれ!

  • 配列のお勉強。
  • 配列もDateクラス同様new演算子を使って生成する。
  • でも普通は代入とともにいっきに以下の記述で生成。これがよく見る形かな。

var my_array:Array = ["日曜日"]; ←インデックス0に「日曜日」が納まった

  • 配列のインデックス番号に何を入れるかの指定は以下のように。

var my_array:Array = new Array();
my_array[0] = "日曜日";
my_array[1] = "月曜日";
my_array[2] = "火曜日";
my_array[3] = "水曜日";
my_array[4] = "木曜日";
my_array[5] = "金曜日";
my_array[6] = "土曜日";
trace(my_array[new Date().day]); ←出力用

  • 配列は別に0番から格納する必要はなく何番から入れ始めても良い。しかもそれにより無駄なメモリ消費もない。
  • そんなわけで前回のキーコード*1をそのままインデックスにするわけですね。

Array = new Array();
keys_array[Keyboard.LEFT] = -1;←方向を決めるための符号となる
keys_array[Keyboard.RIGHT] = 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 nPixels:Number = keys_array[nKeyCode];
  if (nPixels) {
    x += nPixels*xGetPixels(bShiftKey);
  }
}
function xGetPixels(bShiftKey:Boolean):int {
  var nPixels:int = bShiftKey ? nShiftMove : nMove;
  return nPixels;
}

  • なるほど!これは説明聞かないといきなりこの数列見ても何の処理か分からなかったかも。
  • そんでこの場合は左右の矢印キーのみの処理。
  • ほかのキーが押されると未定義の配列の中身が指定される。

インデックスに指定したエレメントが存在しなければ,未定義を意味するundefinedという値が配列から返される。しかし,Number型で指定した変数(nPixels)にundefinedを代入すると,数値演算の対象にならないことを示すNaNという値に変わる。したがって,変数値が数値かNaN*2かを判定する必要がある。

  • そんなわけでよくみると関数xMove内のif文が「if (nPixels)」となってます!これ大事じゃね?!

ifステートメントは,変数の値そのものを評価して,trueまたはfalseと判定する。そして,Number型の値は,NaNと0以外はtrueと評価される。

  • 「0」でもfalseになるのね。
  • なんで左右方向のみの移動なのかなと思ってたら、配列使うとif・swicth文のときと違ってyプロパティいじりにくいのね。
  • そしていきなりこんな記述が。

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

  • お、なんか分かるような分からんような。
  • アクセス演算子が超便利に使えるってこと??

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

my_mc.x += 10;

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

my_mc["x"] += 10;

  • ようはインスタンスのプロパティが連想配列に格納されてるってイメージですね。
  • それにしても野中先生は初心者がミスしやすい考えをよく知ってる。自身の失敗の経験か指導者としての経験か。とにかくためになる。

しかし,ここでひとつ注意しなければならない。つぎのステートメントは,エラーになってしまうということだ。

["x"] += 10;

なぜなら,上のステートメントの左辺は,インスタンスのxプロパティにアクセスしているのではない。文字列"x"をエレメントとしてもつ配列をつくってしまっているのだ。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];

  • 二次元配列かな。なるほど。プロパティは文字列なので「"」で囲むと。
  • そんなわけで最終的にはこうなる。

// 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;
}

  • はいここで「this[ keys_array[0] ]」ですね。知らないと記述に困るよね。
  • つーわけで今回一番の鱗ドロピング・フロム・ジ・アイズは以下。

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

  • 先生!今回も勉強になりました!!!!

*1:整数で互いに重複しないので好都合!!!

*2:何の略か忘れてたんで調べたら「Not a Number」でした★