時系列に説明ができません(それが一番いいが、思い出せない)
ので、上から順にいきます。
tetris.js
var CANVAS_H = 600, CANVAS_W = 300;
var COLS = 10, ROWS = 20;
var RECT_W = 4; //blockShape配列で、テトリスブロックのx座標要素幅
var CUBEUNIT_LENGTH = CANVAS_H / ROWS ; // 30px
var INIT_BACKCOLOR = ' white ';
SHAPESの一列め(最初の4つの要素に0を入れてます)
tetris16版というのに合わせた回転にしました。
var SHAPES = [
[0,0,0,0,
1,1,1,1],
[0,0,0,0,
1,1,1,0,
1],
[0,0,0,0,
1,1,1,0,
0,0,1],
[0,0,0,0,
0,1,1,0,
0,1,1],
[0,0,0,0,
1,1,0,0,
0,1,1,0],
[0,0,0,0,
0,1,1,0,
1,1],
[0,0,0,0,
1,1,1,0,
0,1]
];
var COLOR = ['red', 'orange', 'blue', 'yellow', 'green', 'purple', 'cyan'
];
var TETRIS_BLOCK = [];
(function () {
for ( var i = 0; i < SHAPES.length; i++) {
TETRIS_BLOCK [i]= {
blockShape : SHAPES[i],
blockColor : COLOR[i],
};
}
})();
即時関数
即時関数(function(){ ... })()の別の書き方いろいろ
これは必須学習項目です。
テトリスブロックは、色と形をもっている。ってことで、TETRIS_BLOCKとして組み立てています。
var Board = [];
( function () {
for ( var i = -3; i < 13; i++) {
Board [i] = [];
}
})();
Board[ i ][ j ] が 0 ならブロックなし、 1 ならあり
var BoardWithColor;
(function () {
BoardWithColor = [];
for (var i = -3; i < COLS + 3; i++) {
BoardWithColor [ i ] = [];
for (var j = -1; j <ROWS + 3; j++) {
BoardWithColor [ i ] [ j ] = [];
Object.defineProperty ( BoardWithColor [ i ] [ j ], 'Board' , {
get () { return Board [this.i] [this.j]; },
set (value) { Board [this.i] [this.j] = value; },
});
BoardWithColor [ i ] [ j ].i = i;
BoardWithColor [ i ] [ j ].j = j;
}
}
})();
ここは3日間悩んだところです。ちょい学習量が多いので、読む速度を落としてください。
BoardWithColorを組み立てています。
BoardWithColor と Board[ i ][ j ]
Board[ i ][ j ]に、色情報を加えたものがそれです。
BoardWithColor[ i ][ j ].Board としたら、 Board[ i ][ j ] が取り出せる。そうしたかったんです。
これが難問難問。
BoardWithColor[ i ][ j ].Board()
最後が関数になっています。これなら簡単に分かります。だけど、Board[ i ][ j ] ですよ。なんでおなじ物を参照するのに向こうは関数なしでこっちは関数ありなんだと。ダサイ。ってかなにか術があるはず。
答えは、getterとsetter
以下の二通りがある。
・var obj = {
// プロパティの読み出し用
get propertyName() { /* 関数本体 / },
// プロパティの設定用
set propertyName(v) { / 関数本体 */ }
}
・Object.defineProperty メソッド
今見ると、独習javascript」にもひっそりのってる。けど、使いどころとしての書き方が欠けてるからひっかからない。
プロパティの参照で、関数を実行できるようになっている。つまり
BoardWithColor[ i ][ j ].Board() を
BoardWithColor[ i ][ j ].Board こう書ける
ようになったんです。
(つまり、関数とは、参照することであり。逆もそう。同じことだったんですね。そう思っても問題ないですね)
2つ目の山にいきます。
読む速度を落としてください。
Object.defineProperty ( BoardWithColor [ i ] [ j ], 'Board' , {
get () { return Board [this.i] [this.j]; },
set (value) { Board [this.i] [this.j] = value; },
});
最初はこう書いてました。
Object.defineProperty ( BoardWithColor [ i ] [ j ], 'Board' , {
get () { return Board [i] [j]; },
set (value) { Board [i] [j] = value; },
});
なぜ下でダメか。それは、Board [i] [j]が評価(実行)されるのは、
続く