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



左回転はZ 右回転はXにしましょう。
まずキーカウンタを定義します。
   TPiece = Class(TObject)
   private
   public
       (略)

       k_left,k_right:integer;
       k_z,k_x:integer;

       procedure Init(_x,_y,dm:Integer;mb:TMapBlocks);

       (略)
   end;
んで、
押してたら+1 離されたら0 の処理をつけます。
procedure TPiece.Main;
begin

   if GetKeyState(VK_LEFT)<0 then k_left:=k_left+1 else k_left:=0;
   if GetKeyState(VK_RIGHT)<0 then k_right:=k_right+1 else k_right:=0;

   if GetKeyState(Ord('Z'))<0 then k_z:=k_z+1 else k_z:=0;
   if GetKeyState(Ord('X'))<0 then k_x:=k_x+1 else k_x:=0;

   (略)
end;
この前作った、左と右の処理と同じです。
ただ、GetKeyStateに渡す引数の値が、
VK_○○ ではありませんね。
実は、
「A-Zのキーのキーコードは、
 A-ZのASCIIコードと同じ」
だそうで、
VK_○○ を使う代わりに、
自分で文字からアスキーコードを抜き出さなければならないそうです。
そこでOrd関数を使うわけで、
Ord関数は、文字を与えればその文字のアスキーコードを返してくれます。
これで、
GetKeyStateに文字コードを渡して入力をチェック
0未満なら押されている→カウンタ加算→そうでなければカウンタリセット
の処理が無事作れます。
さて、実際に回転を実行する部分ですが、
回転ボタンは押しっぱなしで回り続けられてもちょっと困ります。
というわけで、回転の実行は、
ボタンが押された瞬間 にしましょう。
押された瞬間はキーカウンタが1です。
次のように編集します。
procedure TPiece.Main;
begin
   if GetKeyState(VK_LEFT)<0 then k_left:=k_left+1 else k_left:=0;
   if GetKeyState(VK_RIGHT)<0 then k_right:=k_right+1 else k_right:=0;
   if GetKeyState(Ord('Z'))<0 then k_z:=k_z+1 else k_z:=0;
   if GetKeyState(Ord('X'))<0 then k_x:=k_x+1 else k_x:=0;

   if (k_left mod 5)=1 then begin
       if not isHit(-1,0) then x:=x-1;
   end;
   if (k_right mod 5)=1 then begin
       if not isHit(1,0) then x:=x+1;
   end;

   if k_z=1 then begin
       SpinLeft;
       if isHit(0,0) then SpinRight;
   end;
   if k_x=1 then begin
       SpinRight;
       if isHit(0,0) then SpinLeft;
   end;

   (略)

end;
追加されてるのは、

   if k_z=1 then begin
       SpinLeft;
       if isHit(0,0) then SpinRight;
   end;
   if k_x=1 then begin
       SpinRight;
       if isHit(0,0) then SpinLeft;
   end;
という部分ですね。
   if k_z=1 then begin
       SpinLeft;
       if isHit(0,0) then SpinRight;
   end;
だけに注目してみます。
k_zが1なら、(つまり、Zキーを押された瞬間なら
SpinLeftを実行。 左に回転するわけです。
そこでもし、当たっているなら、右に回転する。
と書いてあります。
isHitは、移動量を引数に与えて、当たるかどうか調べる関数ですから、
0,0を渡せば、今の状態で壁に当たっているか
となります。
もし当たっていたら、
逆回転させれば元に戻る→回転しなかったことになる。
という事です。
実行してみましょう。
だいぶ自由につんでいけるようになったはずです。

img1.png

きたーっ!!!!(消えないけど