コラム / テトリスぽいもの / 12



さて、フィールドと表示ができたところで、
落ちていくピースを定義しましょう。
やっぱり、ピースをクラス化するのが、
イメージと合うと思います。
どんなクラスか考えて見ます。
まず、x座標、y座標は必須です。
また、4*4の二次元配列も必要です。
テトリスのピースは4*4に入るようになってるっぽいので。
また、止まる→一段落ちる→止まる→一段落ちる
とするために、
止まる時間を制御するカウンタも必要です。
で、問題は、地面に当たるかどうか、なんですが、
その判定は、TMapBlocksを見ることができないと無理ですね。
ピースからTMapBlocksを見るための方法ですが、
ピースに、TMapBlocksの変数を持たせればいいのです。
さて、MapBlocksをピースが持つとはどういうことでしょうか?

gimon.png

一つしかあってはならない、フィールド情報が、
二つになってしまうのでしょうか?
そこで、一つにしようとして、
一度定義したものを捨てた場合、こうなってしまいます。

gyaku.png

全体としては動作しますが、
オブジェクト指向としては何か間違っています。
クラスというのは、インスタンスへの参照を変数に代入し、
インスタンスへアクセスしている、
という構造は覚えているでしょうか。
integer変数だったら、
「その変数のデータ領域に数値が書き込まれます」
しかし、クラス変数というのは、
「変数自体に書き込まれているデータはただの住所」
なのです。
ただの住所なので、
クラス変数を定義しただけでは、
インスタンスは使えません。
実は、
「Createはインスタンスを作り、その住所を返す関数」
です。
だから、他の関数とちがい、
hagehage:=THogehoge.Create;
と、代入文になっているのですね。
これは特殊なイメージを持った式などではなく、
「たんなる代入文だった」
という事です。
さて、クラス変数が住所メモにすぎない、ってことは、
hagehage:=THogehoge.Create;
fugafuga:=hagehage;
としたときの動作はわかるでしょうか。
「インスタンスそのものが代入されている変数は無い」
ので、
hagehageには住所が入ってるだけです。
そしたら、fugafugaにも住所をコピーするだけです。
結果、 
「同じインスタンスを二つの変数から参照できるようになる」
ってことです。
こうなるとおもしろい事が起こります。
(以下のコードは上の続き
hagehage.himitu:='本当はスク水が好きです。';
とすると、
「hagehageの住所が指しているインスタンスのhimituが書き換わります。」
でも、fugafugaの指している住所も同じです。
showmessage(fugafuga.himitu);
とすると、
「本当はスク水が好きです。」
って出ちゃうのですwwwwww
これがインスタンスの共有です。
というわけで、ピースクラスが、TMapBlocksを持っても、
こうなるだけで、
別に、「ピースが上の立場になるわけではない」ってことがわかりましたか?

sansyou.png

ま、これでピースクラスの設計はできてきました。
次回で作ってみましょう。