ブロックが落ちてくるようになったので、 それを動かす部分を作りましょう。
動かす部分にはキー入力のチェックが必要です。 具体的な方法は後で説明するとして、 キー入力情報では、 「押しているか、押していないか」しかわかりません。 しかし、ゲームの処理では、 「押した直後」や、「一定時間押し続けたら」 といった判定をしたいことがあります。 例えば移動なら、 右を押していたら毎フレーム右に移動だと、 瞬きする間に瞬間移動してしまいます。 ん?瞬きする間の移動を瞬間移動っていうのか。 頭痛で頭が痛い。馬から落馬して落ちた。 さて、そこで、 俺オススメの手法が、 「押されたらキーカウンタを+1、
離されたらキーカウンタを0」
という処理を、毎フレームとおすことです。 そうするとこうなります。
キーカウンタが0なら離している キーカウンタが1なら押した直後 キーカウンタが2以上なら押し続けていて、カウンタ値が押し続けた長さ
と、必要な情報が扱いやすい数値体系でわかります。
この、キーカウンタ処理を一括して行うクラスがあると、 いっそう整理されるのですが、 今回は単純に実装しましょう。
TPieceに変数を追加します。
public (略) death:Boolean; k_left,k_right:integer; procedure Init(_x,_y,dm:Integer;mb:TMapBlocks); (略) end;
k_left 左キーのキーカウンタです。 k_ ってのは keyの って意味です。
k_right 右に同じ。つか左に同じ。
で、初期化関数で初期化します。 initの実装部を編集です。
procedure TPiece.Init(_x,_y,dm:Integer;mb:TMapBlocks); begin x:=_x; y:=_y; d_counter:=0; d_max:=dm; MapBlocks:=mb; death:=False; k_left:=0; k_right:=0; end;
そして、mainにキーカウント処理を追加します。
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; d_counter:=d_counter+1; //1増える if d_counter=d_max then begin d_counter:=0; //maxになったら即リセット end; (略) end;
追加されたのは2行です。
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 else 文ですね。 条件は、GetKeyState(VK_LEFT)<0です。 GetKeyState関数は、与えられた仮想キーコードが、 押されていたら負の数を返し、押されていなければ0以上の数を返します。 この場合は、GKS<0 なので、押されていたら真になる式ですね。 仮想キーコードとはなんでしょうか。 まぁ、キーの番号です。 仮想ってのは、実際のハードウェアではなく、 Windows経由でアクセスするため、仮想キーに抽象化されてる ってことなんですが、 まぁ、キーの番号です。(2回目
もし、押されていたら、カウンタを1増やし、 ( x:=x+1 は 1増える式ってのは大丈夫ですよね。 離されていたら、一気に0です。
では、次回で移動させましょう。