ブロックくずしゲームを作る
その4 ゲームオーバーの設定
その3で,ラケットでボールをはじき返すようにしましたが,今回はボールが下に落ちたときに「ゲームオーバー」になるようにします。
また,今までの設定で,マウスクリックでスタートするようにしましたが,これでは,マウスクリックでスタートしキーボードで操作することになり,面倒ですので,スペースキーでもスタートできるようにしてみたいと思います。
ボールを下ではじき返さないようにする
これには,今までのプログラムを書きかえる必要があります。Timer1Timerイベントハンドラの中の一行を書きかえます。
procedure TForm1.Timer1Timer(Sender: TObject);
begin
with image1.Canvas do begin
//ボールがあった部分を黒く塗る
brush.Color:=clblack;
fillrect(rect(ballx,bally,ballx+balls,bally+balls));
end;
//ボールの新しい座標を求める
if (ballx<=0) or (ballx>=image1.Width-balls) then bx:=-bx;
ballx:=ballx+bx;
if (bally<=0) or (bally>=image1.Height-ballsize) then by:=-by;//←これ
bally:=bally+by;
//ボールがラケットに当たったか調べる
if bally>=raky-balls then
begin
if (ballx>=rakx) and (ballx<=rakx+rakw) then by:=-by;
end;
//bx,by進んだ位置にボールを描く
with image1.Canvas do
begin
brush.Color:=clwhite;
fillrect(rect(ballx,bally,ballx+ballsa,bally+balls));
end;
//ラケットを動かす
if keyd<>0 then
begin
with image1.Canvas do begin
brush.Color:=clblack;
fillrect(rect(rakx,raky,rakx+rakw,raky+10));
rakx:=rakx+keyd;
brush.Color:=clwhite;
fillrect(rect(rakx,raky,rakx+rakw,raky+10));
end;
end;
end;
上の赤字の部分を書きかえます。
if (bally<=0) or (bally>=image1.Height-ballsize) then by:=-by;
↓
if bally<=0 then by:=-by;
これで,下に行ったとき跳ね返ることはなくなります。しかしタイマーは動いたままなので,タイマーを止めて,「ゲームオーバー」の文字を表示させます。プログラムを書く場所はTimer1Timerイベントハンドラの中です。
//ゲームオーバー
if bally>=500 then //もしボールのY座標が500以上になったら
begin
timer1.Enabled:=false; //タイマーを止める
with image1.Canvas do //Image1.Cavasに対して
begin
font.Color:=clred; //文字色を赤にする
font.Size:=30; //文字の大きさを30ピクセルにする
textout((image1.width-textwidth('Gama Over')) div 2,200,'Game Over'); //「Game Over」の文字を描く
end;
end;
textout((image1.width-textlength('Gama Over')) div 2,200,'Game Over');について解説します。これは
X座標が(image1.width-textlength('Gama Over')) div 2
Y座標が200
の場所に’Game Over’の文字を書くという意味です。
X座標が複雑ですが,これはイメージの幅から文字の長さを引いて全体を2で割るという意味ですが,こうすることで文字をイメージの中央に描くことができます。このように記述することでフォームの幅を変えたときでも,常に中央に表示されます。
ここまでで,ボールが下に落ちると,’Gme Over’の文字がフォームに表示されます。
このとき,タイマーも止まっているので,ラケットも動かすことができなくなります。
ここまでのコードを,掲載してみます。
procedure TForm1.Timer1Timer(Sender: TObject);
begin
with image1.Canvas do begin
//ボールがあった部分を黒く塗る
brush.Color:=clblack;
fillrect(rect(ballx,bally,ballx+balls,bally+balls));
end;
//ボールの新しい座標を求める
if (ballx<=0) or (ballx>=image1.Width-balls) then bx:=-bx;
ballx:=ballx+bx;
if bally<=0 then by:=-by; //←これは今でのものを書きかえます
bally:=bally+by;
//ボールがラケットに当たったか調べる
if bally>=raky-balls then
begin
if (ballx>=rakx) and (ballx<=rakx+rakw) then by:=-by;
end;
//ゲームオーバー
if bally>=500 then
begin
timer1.Enabled:=false;
with image1.Canvas do begin
font.Color:=clred;
font.Size:=30;
textout((image1.width-textwidth('Gama Over')) div 2,200,'Game Over');
end;
end;
//bx,by進んだ位置にボールを描く
with image1.Canvas do
begin
brush.Color:=clwhite;
fillrect(rect(ballx,bally,ballx+ballsa,bally+balls));
end;
//ラケットを動かす
if keyd<>0 then
begin
with image1.Canvas do begin
brush.Color:=clblack;
fillrect(rect(rakx,raky,rakx+rakw,raky+10));
rakx:=rakx+keyd;
brush.Color:=clwhite;
fillrect(rect(rakx,raky,rakx+rakw,raky+10));
end;
end;
end;
スペースキーでゲームスタートさせる
今度は,スペースキーでゲームがスタートできるようにします。
これは,カーソルキーと同じように,FormKeyDownイベントハンドラに記述します。
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if key=VK_right then keyd:=4;
if key=VK_left then keyd:=-4;
if key=VK_space then
begin //beginからendの間のものは,Image1Clicで書いたものと同じです
ballx:=200;
bally:=300;
bx:=3;
by:=-6;
balls:=6;
timer1.Enabled:=true;
end;
end;
これで,ボールが下に落ちるとゲームオーバーの文字が表示されてゲームも中断します。
今回記述した,プログラムを実行してみると新たな問題に気づきます。それはゲームオーバーの後,またゲームスタートすると’Game Over’の文字が表示されたままボールが動き始めます。そのため,’Game Over’の文字のあたりを黒く塗りつぶす必要があります。
塗りつぶす範囲は適当でかまいません。縦方向は文字を書いたところからラケットが表示されてあるところまでにします。つまり200から450にします。横方向は端から端までにします。
procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if key=VK_right then keyd:=4;
if key=VK_left then keyd:=-4;
if key=VK_space then
begin
ballx:=200;
bally:=300;
bx:=3;
by:=-6;
balls:=6;
with image1.Canvas do
begin
brush.Color:=clBlack;
fillrect(rect(0,200,image1.width,450));
end;
timer1.Enabled:=true;
end;
end;
次回は,ブロックを表示させてみます。