Winformで重力のシミュレートのサンプル

重力のシミュレートをWinFormsで実装するには、物体の位置、速度、加速度(重力加速度)を管理する必要があります。以下に、シンプルな重力シミュレーションの例を示します。ここでは、ボールがウィンドウ内で自由落下する様子をシミュレートします。

簡易的な物理エンジン

物理演算を簡単にシミュレーションするためのコードを作成できます。例えば、基本的な重力や衝突検出など。

private void UpdatePhysics()
{
    // 簡易的な重力のシミュレーション
    playerVelocity.Y += gravity;
    playerPosition.Y += playerVelocity.Y;

    // 床との衝突検出
    if (playerPosition.Y > groundLevel)
    {
        playerPosition.Y = groundLevel;
        playerVelocity.Y = 0;
    }
}

実行サンプル

このプログラムは、重力とジャンプのシミュレーションを行う簡単なWindowsフォームアプリケーションです。赤いボールが画面上で上下に動き、上方向キーを押すことでジャンプが発生します。

using System;
using System.Drawing;
using System.Windows.Forms;

namespace FlowLayoutPanelSample
{
    public partial class Form1 : Form
    {
        private Timer timer;
        private float ballY;
        private float ballVelocityY;
        private const float gravity = 0.98f; // 重力加速度
        private const float groundLevel = 300.0f; // 地面のY座標
        private const float ballRadius = 20.0f; // ボールの半径
        private bool isGrounded;
        private bool isUpPressed;

        public Form1()
        {
            this.DoubleBuffered = true;
            this.Width = 800;
            this.Height = 600;
            this.Text = "Gravity Simulation with Jump";

            timer = new Timer();
            timer.Interval = 16; // 約60FPS
            timer.Tick += Timer_Tick;
            timer.Start();

            this.KeyDown += Form1_KeyDown;
            this.KeyUp += Form1_KeyUp;

            ballY = groundLevel - ballRadius; // ボールの初期位置
            ballVelocityY = 0.0f; // ボールの初期速度
            isGrounded = true;
            isUpPressed = false;
        }

        private void Timer_Tick(object sender, EventArgs e)
        {
            UpdatePhysics();
            Invalidate(); // 画面の再描画を要求
        }

        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Up)
            {
                isUpPressed = true;
            }
        }

        private void Form1_KeyUp(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Up)
            {
                isUpPressed = false;
            }
        }

        private void UpdatePhysics()
        {
            if (isUpPressed && isGrounded)
            {
                ballVelocityY = -15.0f; // ジャンプの初速度
                isGrounded = false;
            }

            // 重力の適用
            ballVelocityY += gravity;
            ballY += ballVelocityY;

            // 地面との衝突検出
            if (ballY + ballRadius > groundLevel)
            {
                ballY = groundLevel - ballRadius;
                ballVelocityY = 0;
                isGrounded = true;
            }
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            Graphics g = e.Graphics;
            g.Clear(Color.White);
            g.FillEllipse(Brushes.Red, 400 - ballRadius, ballY, ballRadius * 2, ballRadius * 2);
        }
    }
}

説明

  1. 基本設定:
    • フォームのダブルバッファリングを有効にし、ウィンドウのサイズとタイトルを設定しています。
  2. タイマーの設定:
    • Timerを使用して、約60FPSでTimer_Tickメソッドを呼び出します。このメソッドは物理計算と画面の再描画を行います。
  3. 物理計算の更新 (UpdatePhysicsメソッド):
    • ballVelocityYに重力加速度を加え、ボールの速度を更新します。
    • ballYballVelocityYを加え、ボールの位置を更新します。
    • ボールが地面に衝突したかどうかを検出し、衝突した場合はボールの位置と速度を修正します。
  4. 描画 (OnPaintメソッド):
    • 画面をクリアし、ボールを描画します。ボールの位置はballYで決定されます。

このサンプルでは、非常にシンプルな重力シミュレーションを行っています。ボールは重力によって加速され、地面に達すると止まります。より複雑なシミュレーションには、反発係数を用いた跳ね返りの計算や、複数の物体間の衝突検出などを追加することができます。