いよいよ、大詰めです。最後に 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;