3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

DelphiAdvent Calendar 2022

Day 19

Delphi で書いた「軟着陸ゲーム」をちょっとだけビジュアル化する

Last updated at Posted at 2022-12-18

はじめに

昨日の Delphi で「軟着陸ゲーム」の Windows アプリケーションを作る という記事ですが、いかんせん地味すぎるので、ちょっとビジュアル化してみたいと思います。

ビジュアル化?

とはいえ、普通にロケットを描画したら地味プログラムが台無しとなります。見た目何が何だかわからないようにビジュアル化します。

フォーム

フォームに TScrollBar を貼り付けます。
image.png
スクロールバーのプロパティの値は次の通りです。

プロパティ
Align alRight
Kind sbVertical
Name ScrollBar1

フォームの OnShow イベントの最後に一行追記します。

frmuGameMain.pas
procedure TfrmGameMain.FormShow(Sender: TObject);
begin
  OnShow        := nil;
  edDisp.Top    := 16;
  edDisp.Left   := 16;
  ClientWidth   := edDisp.Left  + edDisp.Width    + 16;
  btnStart.Top  := edDisp.Top   + edDisp.Height   + 16;
  btnStart.Left := edDisp.Width - btnStart.Width  + 16;
  ClientHeight  := btnStart.Top + btnStart.Height + 16;
  edDisp.Text   := '';

  ClientWidth := ClientWidth + ScrollBar1.Width; // 追加
end;

縦にしたスクロールバーのツマミの位置をロケットの高度に見立てようという作戦です。フォームは見切れないようにスクロールバーの分だけ幅を広げます。

ゲームスレッド

スクロールバーにアクセスできるように、フィールドに TScrollbar を追加し、コンストラクタで TScrollbar を指定できるようにします。

frmuGameMain.pas
type
  TGameThread = class(TThread)
  private
    { Private 宣言 }
    FEdit: TEdit;
    FScrollBar: TScrollBar; // 追加
  protected
    { Protected 宣言 }
    procedure Execute; override;
  public
    { public 宣言 }
    constructor Create(Edit: TEdit; ScrollBar: TScrollBar); // 変更
  end;

constructor TGameThread.Create(Edit: TEdit; ScrollBar: TScrollBar); // 変更
begin
  inherited Create(False);
  FEdit := Edit;
  FScrollBar := ScrollBar; // 追加
end;

ゲームロジック

ゲームスレッドのコンストラクタを変更したので、btnStart のクリックイベントハンドラ内の呼び出しも変更します。

frmuGameMain.pas
procedure TfrmGameMain.btnStartClick(Sender: TObject);
begin
  btnStart.Enabled := False;
  edDisp.ReadOnly := True;
  edDisp.Color := $0080B090;
  edDisp.Font.Color := $00303020;
  Buf := edDisp.Text;
  GT := TGameThread.Create(edDisp, ScrollBar1); // 変更
  GT.OnTerminate := GameEnd;
  GT.FreeOnTerminate := True;
end;

内部ルーチン (ゲームスレッドの Execute メソッド内ルーチン) に、ロケットの初期位置と現在位置を設定するメソッドを追加します。

frmuGameMain.pas
  ...
  procedure Input(var v: Double); overload;
  var
    value: string;
  begin
    Input('', v);
  end; { INPUT #4 }
  procedure InitRocket(n: Integer);
  begin
    Synchronize(
      procedure
      begin
        FScrollBar.Max := n;
        FScrollBar.Position := 0;
      end
    );
  end; { InitRocket }
  procedure MoveRocket(n: Integer);
  begin
    Synchronize(
      procedure
      begin
        FScrollBar.Position := FScrollBar.Max - n;
      end
    );
  end; { MoveRocket }
{$ENDREGION}

ロケットの位置を通知するコードを書きます。

frmuGameMain.pas
   10:Wait(50); Clear; Using; S:=-50; A:=0; D_ := '';
      Beep(3); Print(' *** START ***');
      Restore;
      Read(B_); Read(W); Read(B_); Read(F); Read(B_); Read(H);
      InitRocket(Trunc(H)); // 追加
      Wait(W);
   70:Print_Using('####', [H, S, F, C]);
      MoveRocket(Trunc(H)); // 追加
      if Terminated then Exit;

遊んでみよう

右側にスクロールバーがありますよね?これがロケットの高度を示しています。
image.png
放っておくと高度がみるみる下がります。
image.png
あぁ、激突してしまいました (>_<)
image.png
...とまぁこんな感じで、「見た目何やってんのかワカンナイゲーム」を維持したままビジュアル化できました (w

おわりに

ちょっとした改造でしたが、多少は遊びやすくなったのではないでしょうか?

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?