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



TPieceにメイン手続きを追加します。
それと、死亡フラグを追加します。(これは忘れてました
   TPiece = Class(TObject)
   private
   public
       x,y:integer;
       d_counter,d_max:integer;
       shape:Array[0..3,0..3] of Boolean;
       MapBlocks:TMapBlocks;
       death:Boolean;
       procedure Draw;
       function isHit(vx,vy:integer):Boolean;
       procedure CopySelfToMapBlocks;

       procedure Main;
   end;
deathフラグがTrueなら、次のフレームまでに死滅します。
ここの処理はだいぶ後で書きます。
Main手続きが、TPieceのメインループ1フレームでの処理を、
一括して行います。
んじゃぁ実装部
procedure TPiece.Main;
begin

   d_counter:=d_counter+1;         //1増える
   if d_counter=d_max then begin
       d_counter:=0;               //maxになったら即リセット
   end;

   if d_counter=0 then begin       //リセットされている、つまり、maxまでカウントしたとき
       //下に降りられるかチェック
       if isHit(0,1) then begin
           //どうみても当たります。
           CopySelfToMapBlocks;
           death:=True;//自殺
           Exit;   //もう何もかも終わりだ
       end else begin
           //どうみても当たりません。
           y:=y+1;//降りる
       end;
   end;

   Draw;//私を見て!
 
end;
3つに別れています。
一番上のグループ
   d_counter:=d_counter+1;         //1増える
   if d_counter=d_max then begin
       d_counter:=0;               //maxになったら即リセット
   end;
d_counterを1増やします。
もし、d_maxと等しくなったら、0にします。
結果、メインループを通るたびに、
0,1,2,3,...0,1,2,3...0,1,.....
と、何度も数え続けます。悲しい。
   if d_counter=0 then begin       //リセットされている、つまり、maxまでカウントしたとき
       //下に降りられるかチェック
       if isHit(0,1) then begin
           //どうみても当たります。
           CopySelfToMapBlocks;
           death:=True;//自殺
           Exit;   //もう何もかも終わりだ
       end else begin
           //どうみても当たりません。
           y:=y+1;//降りる
       end;
   end;
if d_counter=0 なので、
数えてるカウンタが0になったときに実行される部分です。
0というのは、d_maxになったときでもあります。(成ると同時に0にされるため
       //下に降りられるかチェック
       if isHit(0,1) then begin
           //どうみても当たります。
           CopySelfToMapBlocks;
           death:=True;//自殺
           Exit;   //もう何もかも終わりだ
       end else begin
           //どうみても当たりません。
           y:=y+1;//降りる
       end;
if else end; 構文です。
条件は、isHit(0,1)ですから、
isHit関数はさっき作ったとおり、その値分移動したら、
ブロックに接触するか、を返すので、
0,1 つまり、下に1マス移動したら当たるかを調べています。
当たる場合は
           //どうみても当たります。
           CopySelfToMapBlocks;
           death:=True;//自殺
           Exit;   //もう何もかも終わりだ
自分自身をフィールドにコピーします。
そのあと、death:=True; で自殺しています。
この、Mainを呼び出す、メインルーチン側で、
deathがTrueになってたら、インスタンスを解放するようにします。
死んだことになってるので、
他の部分を実行しないように、さっさとExitです。
当たらない場合は、
           //どうみても当たりません。
           y:=y+1;//降りる
y座標を1加算、つまり、1マス降りるだけです。
3つめの部分は、
死んでないフレームなら必ず来ます。
   Draw;//私を見て!
まぁ、描画するだけです。
次回、呼び出してみましょう。