# Delphi で書いた「軟着陸ゲーム」をちょっとだけビジュアル化する --- tags: Delphi programming Pascal ポケコン objectpascal created_at: 2022-12-19 updated_at: 2022-12-19 --- # はじめに 昨日の [Delphi で「軟着陸ゲーム」の Windows アプリケーションを作る](./580631cdf3f12ef46664.md) という記事ですが、いかんせん地味すぎるので、ちょっとビジュアル化してみたいと思います。 # ビジュアル化? とはいえ、普通にロケットを描画したら地味プログラムが台無しとなります。見た目何が何だかわからないようにビジュアル化します。 ## フォーム フォームに TScrollBar を貼り付けます。 ![image.png](./images/0852a768-d6b0-8589-ea4e-8cdb9c708a46.png) スクロールバーのプロパティの値は次の通りです。 | プロパティ | 値 | |:---|:---| | Align | alRight | | Kind | sbVertical | | Name | ScrollBar1 | フォームの OnShow イベントの最後に一行追記します。 ```pas: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 を指定できるようにします。 ```pas: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 のクリックイベントハンドラ内の呼び出しも変更します。 ```pas: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 メソッド内ルーチン) に、ロケットの初期位置と現在位置を設定するメソッドを追加します。 ```pas: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} ``` ロケットの位置を通知するコードを書きます。 ```pas: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](./images/09ffe8c7-c324-ffbb-1f32-38cf277bc954.png) 放っておくと高度がみるみる下がります。 ![image.png](./images/bbd4f1c8-bf21-40f2-464c-0f0249b50757.png) あぁ、激突してしまいました (>_<) ![image.png](./images/c0410d50-5c5f-f0cc-11db-cefd4373b655.png) ...とまぁこんな感じで、**「見た目何やってんのかワカンナイゲーム」を維持したままビジュアル化**できました (w # おわりに ちょっとした改造でしたが、多少は遊びやすくなったのではないでしょうか?