【Delphiでゲーム制作】ボールを動かす

【Delphiでゲーム制作】ボールを動かす

Delphiを利用したゲームの作成に挑戦します。ゲーム作成の経験がほとんどないので、インターネットで公開してくださっているゲーム制作の情報をつまみ食いしつつゲーム作りを進めます。

今回はウィンドウ内でボールを動かしてみようと思います。壁にぶつかると反射して反対方向に進みます。

まずは設計

ボールを動かす

ボールの動きをどのように考えるかですが、時間が経つにつれて、少しづつ座標を更新していけば動いているように見えそうです。

壁にぶつかったら反射

壁にぶつかったら反対方向に反射するというのは、ボールと壁の座標を比べて、交わったら向かってきた向きと反対の方向に座標を更新するというやり方がよさそうです。

画面作成とコーディング

コンポーネント配置

ボールにはTCircleを利用しました。画面に配置するだけで、ボールを作り出せます。時間が経つにつれてにはTTimerを使います。

TCircleとTTimerのコンポーネントをFormに配置できたら、それぞれプロパティの設定をします。まずはTCircleのサイズを適当な大きさに調整します。ここでは高さ、幅とも20としました。次にTTimerのIntervalを設定。これは20としてみました。

イベント作成

一番重要なのはTTimerOnTimerイベントです。イベントが来たら、ボールの位置を求めます。ボールの位置と壁(フォームの端)の座標を比べて、壁と交わっているようだったら、向かう方向を反転します。

OnFormResizeイベントでは壁の位置をアップデートしています。途中でウィンドウサイズを変更したときうまく動くはずです(スマートフォンなどで動作させたときに、端末の向きが変わったときでも同じイベントが動くようです)

unit MoveBallForm;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes,
  System.Variants,
  FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.Objects;

type
  TfrmMoveBall = class(TForm)
    Timer1: TTimer;
    Circle1: TCircle;
    procedure Timer1Timer(Sender: TObject);
    procedure FormResize(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { private 宣言 }
    vx, vy: Single;			// 動きの量
    xMax, xMin: Single;		// ボールが動く範囲(X軸)
    yMax, yMin: Single;		// ボールが動く範囲(Y軸)
  public
    { public 宣言 }
  end;

var
  frmMoveBall: TfrmMoveBall;

implementation

{$R *.fmx}

procedure TfrmMoveBall.FormCreate(Sender: TObject);
begin
  vx := 10;
  vy := 10;
end;

procedure TfrmMoveBall.FormResize(Sender: TObject);
begin
  // ウィンドウサイズが変わったときに
  // ボールが動く範囲をアップデートする
  xMin := 0;
  yMin := 0;
  xMax := frmMoveBall.ClientWidth - Circle1.Width;
  yMax := frmMoveBall.ClientHeight - Circle1.Width;
end;

procedure TfrmMoveBall.Timer1Timer(Sender: TObject);
var
  newX, newY: Single;
begin
  // ボールの位置を算出
  newX := Circle1.Position.X + vx;
  newY := Circle1.Position.Y + vy;

  // ボールの位置を更新
  Circle1.Position.X := newX;
  Circle1.Position.Y := newY;

  // 壁にぶつかったときにボールの移動方向を変更する
  if (newX <= xMin) then
  begin
    vx := abs(vx);
  end;
  if (xMax < newX) then
  begin
    vx := abs(vx) * -1;
  end;

  if (newY <= yMin) then
  begin
    vy := abs(vy);
  end;
  if (yMax < newY) then
  begin
    vy := abs(vy) * -1;
  end;
end;

end.

コメント

このブログの人気の投稿

【KotlinとJava】分解宣言

wxPythonでのモーダルダイアログ作成