いよいよ、大詰めです。最後に TBaseMog, THole クラスのインスタンス生成の役目を持たせるクラス TGameManager クラスの作成をします。この TGameManager クラスは、主に以下の役目を負います。
Unit2 に以下のコードをタイプしてください。
unit Unit2; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls; const MAX_HOLES = 5; // モグラが出現する穴は全部で 5 つあります。 type ...................................................... TGameManager = class(TObject) private fHoles: array[0..MAX_HOLES-1] of THole; fNormalMog: TBaseMog; fYellowMog: TBaseMog; fGameTime: Integer; // 制限時間 fGameScore: Integer; // 獲得したスコア public constructor Create; destructor Destroy; override; // ハンマーがモグラに当たったかどうか procedure CheckMogState(X, Y: Integer); procedure GameLoop; // メインループ procedure GameOver; procedure GameInit; // ゲームの初期化 procedure DecGameTime; function GetKindOfMog: TBaseMog; procedure UpdateGameScore; procedure UpdateGameTime; // 叩かれていないモグラを表示 procedure ShowLiveMog(HoleNumber: Integer; Mog: TBaseMog); // 叩かれたモグラを表示 procedure ShowDeadMog(HoleNumber: Integer; Mog: TBaseMog); end; .................................................. { TGameManager } procedure TGameManager.CheckMogState(X, Y: Integer); var i: Integer; begin for i := 0 to MAX_HOLES-1 do if (fHoles[i].IsDead = false) and fHoles[i].HoleIsFull then // モグラが叩かれたかどうかの判定 if (X > fHoles[i].HolePos.X) and (X < fHoles[i].HolePos.X+fHoles[i].Mogura.LiveBmp.Width) and (Y > fHoles[i].HolePos.Y) and (Y < fHoles[i].HolePos.Y+fHoles[i].Mogura.LiveBmp.Height) then begin fHoles[i].IsDead := true; // モグラが叩かれました。 ShowDeadMog(i, fHoles[i].Mogura); // 叩かれた絵を表示 // 得点の追加 Inc(fGameScore, fHoles[i].Mogura.Score); end; end; constructor TGameManager.Create; begin // 穴の位置を設定 fHoles[0] := THole.Create(Point(10, 10)); fHoles[1] := THole.Create(Point(200, 10)); fHoles[2] := THole.Create(Point(100, 100)); fHoles[3] := THole.Create(Point(10, 200)); fHoles[4] := THole.Create(Point(200, 200)); // 普通のモグラの生成 fNormalMog := TBaseMog.Create(1000, 800, 'Mog1', 'Mog2', 300); // 黄色いモグラの生成 fYellowMog := TBaseMog.Create(500, 500, 'Mog3', 'Mog4', 700); GameInit; // ゲームの初期化 end; procedure TGameManager.DecGameTime; begin Dec(fGameTime, 100); // 制限時間を減らします。 // 制限時間がゼロになるとゲームオーバー if fGameTime = 0 then GameOver; UpdateGameTime; // 制限時間の更新 end; destructor TGameManager.Destroy; var i: Integer; begin for i := 0 to MAX_HOLES-1 do fHoles[i].Free; fNormalMog.Free; fYellowMog.Free; inherited; end; procedure TGameManager.GameInit; begin fGameTime := 30000; // 制限時間 (ms) fGameScore := 0; Form1.Canvas.FillRect(Form1.ClientRect); Form1.Timer1.Enabled := true; end; procedure TGameManager.GameLoop; var HoleNum: Integer; i: Integer; begin HoleNum := Random(17); if (HoleNum < 5) then if not fHoles[HoleNum].HoleIsFull then ShowLiveMog(HoleNum, GetKindOfMog); // モグラを表示します for i := 0 to MAX_HOLES-1 do fHoles[i].DecLimitTime; // 表示時間を減らします DecGameTime; // 制限時間を減らします。 UpdateGameScore; // スコアの表示 end; procedure TGameManager.GameOver; begin Form1.Timer1.Enabled := false; Form1.Canvas.FillRect(Rect(0, 0, 300, 300)); Form1.Canvas.TextOut(100, 100, 'Game Over'); end; function TGameManager.GetKindOfMog: TBaseMog; begin // 制限時間が 5〜10秒の時だけ黄色モグラを出現させる if (fGameTime < 10000) and (fGameTime > 5000) then Result := fYellowMog else Result := fNormalMog; end; procedure TGameManager.ShowDeadMog(HoleNumber: Integer; Mog: TBaseMog); begin with fHoles[HoleNumber] do begin LimitTime := Mog.DeadTime; Form1.Canvas.Draw(HolePos.X, HolePos.Y, Mog.DeadBmp); end; end; procedure TGameManager.ShowLiveMog(HoleNumber: Integer; Mog: TBaseMog); begin with fHoles[HoleNumber] do begin Existence := true; LimitTime := Mog.LiveTime; Mogura := Mog; Form1.Canvas.Draw(HolePos.X, HolePos.Y, Mog.LiveBmp); end; end; procedure TGameManager.UpdateGameScore; begin Form1.Canvas.TextOut(300, 80, Format('Score: %d', [fGameScore])); end; procedure TGameManager.UpdateGameTime; begin Form1.Canvas.TextOut(300, 30, Format('GameTime: %.3d', [fGameTime div 100])); end;