11-8 インベーダーを用意する場所

最初から4機のインベーダー (と1機のボスインベーダー) が画面に登場し「インベーダー生成」ボタンでインベーダーが増える、という今までのプログラムを、時間が経つと次々とインベーダーが勝手に現れる代わりに最初は何も現れないプログラムに変えましょう。(ただし、ボスインベーダーは最初から登場するままにします。)

【練習問題】

まずは、時間の経過とともにインベーダーが勝手に現れるようにします。control ユニットの TimerMainTimer に、次のように書き加えましょう。

// タイマーが時間を刻むごとに
procedure TFormControl.TimerMainTimer(Sender: TObject);
var
  i: Integer;
begin
  for i := 0 to Length(Invaders) do
    begin
      Invaders[i].Move; // インベーダーを動かす
    end;
  InvaderBoss.RandomMove; // ボスインベーダーを動かす
  Bullet1.Move; // 弾を動かす
  ButtonGenerateClick(Sender); // インベーダーを生成する
end;

書き加えたら実行してみましょう。…インベーダーが増えるには増えますが、これでは増え過ぎですね。各インベーダーが1歩進む毎に1機生成されているのですから、多すぎるのも当然のことです。各インベーダーが1歩進むと2%の確率で新しいインベーダーが生成されるように (即ち各インベーダーが100歩進む毎に2機の割合で新しいインベーダーが生成されるように) しましょう。プログラムを下のように変更してください。

// タイマーが時間を刻むごとに
procedure TFormControl.TimerMainTimer(Sender: TObject);
var
  i: Integer;
begin
  for i := 0 to Length(Invaders) - 1 do
    begin
      Invaders[i].Move; // インベーダーを動かす
    end;
  InvaderBoss.RandomMove; // ボスインベーダーを動かす
  Bullet1.Move; // 弾を動かす
  if (Random(100) < 2) // 2%の確率で
    then
      begin
        ButtonGenerateClick(Sender); // インベーダーを生成する
      end
  ;
end;

これで、ポツポツといった感じでインベーダーが勝手に現れるようになりました。

次に、最初から登場する4機のインベーダーを消します。最初の4機のインベーダーを作り出しているプロジェクトファイルの該当部分 (以下の下線部) を削除します。

var
  i: Integer;
begin
  Application.Initialize;
  Application.CreateForm(TFormControl, FormControl);
  Application.CreateForm(TFormDisplay, FormDisplay);
  SetLength(Invaders, 4); // 「インベーダーは4機」と宣言
  for i :=0 to 3 do
    begin
      Invaders[i] := TInvader.Create;
    end;
  Bullet1 := TBullet.Create;
  InvaderBoss := TInvaderBoss.Create;
  Application.Run;
end.

また、「操作盤」フォームの「開始」ボタンを押したときのイベントハンドラで不要になった部分 (以下の下線部) も削除します。

// 「開始」ボタン
procedure TFormControl.ButtonStartClick(Sender: TObject);
var
  i: Integer;
begin
  Randomize; // 乱数の初期化
  for i := 0 to 3 do
    begin
      Invaders[i].Construct; // インベーダーを出現させる
    end;
  InvaderBoss.Construct; // ボスインベーダーを出現させる
  TimerMain.Enabled := True; // タイマー開始
end;

実行してみましょう。インベーダーがポツポツと出現するようになりましたか?

【練習問題】

ここまでで、インベーダーはポツポツ出現するようになりましたが、やはり4機くらいは最初から出現している方がいいかも知れません。

最初からインベーダーが4機出現するように、プログラムを改変します。この節でここまで行ってきた変更を全部元に戻してもいいのですが、せっかく「インベーダー生成」ボタンがあるのですから、簡単な修正で済ませましょう。

「開始」ボタンのイベントハンドラを次のように修正してください。

// 「開始」ボタン
procedure TFormControl.ButtonStartClick(Sender: TObject);
begin
  Randomize; // 乱数の初期化
  ButtonGenerateClick(Sender); // インベーダーを生成する
  ButtonGenerateClick(Sender); // インベーダーを生成する
  ButtonGenerateClick(Sender); // インベーダーを生成する
  ButtonGenerateClick(Sender); // インベーダーを生成する
  InvaderBoss.Construct; // ボスインベーダーを出現させる
  TimerMain.Enabled := True; // タイマー開始
end;

これで元通り最初は4機のインベーダーが出現するようになりました。このことから分かるように、オブジェクト (ここではインベーダーのこと) を用意する場所は、プロジェクトファイル (この場合は invader_game.dpr) でなくともよく、プログラマが適切な場所でオブジェクトを用意して構いません。

【基礎課題 11-10】

この【練習問題】で追加した部分を、for 文を使う形に書き改め、最初は6機出現するように変更してください。

ここまでのプログラムをダウンロード(D)