ゲーム物理とジャンプの放物線(二次関数の運動学)
「なぜマリオは気持ちよく跳べるのか?」重力加速度と二次関数で創る2Dアクションの物理
- 1
- ゲーム物理とジャンプの放物線(二次関数の運動学)の本質的な定義と直感的ビジュアルをシミュレーターで体験できる。
- 2
- 公式や証明の背景にある数学的意味と、厳密な導出ステップを解説。
- 3
- 実社会における工学応用(2Dアクションゲーム・プラットフォーマー物理更新エンジン)のTypeScript実装コードを収録。
なぜこれを学ぶのか? — 現実社会とテクノロジーでの価値
なぜ生まれたのか?
ガリレオ・ガリレイが発見した落体の法則とニュートン力学を、ゲームやアニメーションの「心地よいジャンプ」として画面上に具現化するために生まれた。
身につく武器・思考力
二次関数の頂点や平方完成が、ゲーム開発のステージ設計(穴の飛び越え判定や足場の高さ)に直結する快感を体感できる。
実社会・ITでの活躍現場
- •スーパーマリオなど2D/3Dアクションゲームのキャラクター物理更新ループ
- •Angry Birdsなど弾道投射物理パズルゲームの軌道予測線表示
- •UIマイクロインタラクション(通知バナーのポップやカードの弾むアニメーション)
- •スポーツ分析(バスケットボールのシュートや野球の打球角度・飛距離予測)
Layer 1 — 直感・シミュレーター
ジャンプ初速()、重力加速度()、前進スピード()のスライダーを動かして「ジャンプ!」ボタンを押そう。キャラクターが崖の穴を飛び越えてゴール旗に届くかチャレンジできます。二次関数 のグラフとジャンプの軌跡が完全に一致することを体感してみましょう。
Layer 2 — 定義・受験・証明
定義
地表付近で鉛直上向きに初速 で投射された物体の時刻 における高さ は、下向きの重力加速度 を受けることで二次関数として表される:
水平方向の速度 が一定(等速直線運動)である場合、 より を代入すると、軌跡は の二次関数(放物線)となる:
最高点到達時刻は 、最高点の高さは 、着地までの全滞空時間は である。
公式・数理モデル
証明・導出
ニュートンの運動方程式と微積分による導出: 鉛直方向の運動方程式は:
時刻 について積分すると、速度 が得られる:
初期条件 より 。したがって 。 さらに について積分すると変位 が得られる:
初期条件 より 。したがって:
頂点(最高点)では垂直速度がゼロ()となるため、。これを代入すると頂点の座標(最大高度)が導出される。
押さえておきたいポイント
- 2Dアクションゲームのすべてのジャンプ挙動は二次関数の放物線運動そのもの
- 「フワフワしたジャンプ」か「キビキビしたジャンプ」かは、初速 と重力 の比率で完璧にコントロールできる
- ゲーム開発ではフレームごとに `vy += gravity; y += vy;` と足し算(オイラー法)するだけで自動的に二次関数軌道を描く
- 中学・高校で習う二次関数の平方完成や頂点の座標が、ゲームのステージ設計(穴の幅や足場の高さ)に直結している
本トピックの内容・数理モデルは、文部科学省学習指導要領(算数・数学・情報)および国際標準カリキュラムに準拠し、エンジニアリング現場の実装事例と照らし合わせてMath World Lab編集部により検証・作成されています。
Layer 3 — 工学応用・現場実装
2Dアクションゲーム・プラットフォーマー物理更新エンジン
UnityやGodot、HTML5 Canvasゲームで用いられるフレームレート非依存のジャンプ・重力演算ループ。
1// 2Dアクションキャラクターの物理更新クラス2export class JumpPhysicsController {3 x: number = 0;4 y: number = 0;5 vx: number = 0;6 vy: number = 0;7 isGrounded: boolean = true;89 // ゲームデザイナーが直感的に決めるパラメータ10 jumpHeight: number = 120; // 最大ジャンプ高さ (px)11 timeToJumpApex: number = 0.4; // 最高点に達するまでの時間 (秒)1213 // 数学的に導出される物理定数14 gravity: number;15 initialJumpVelocity: number;1617 constructor(jumpHeight: number = 120, timeToApex: number = 0.4) {18 this.jumpHeight = jumpHeight;19 this.timeToJumpApex = timeToApex;20 // 重力: g = 2h / t^221 this.gravity = (2 * this.jumpHeight) / Math.pow(this.timeToJumpApex, 2);22 // 初速: v0 = 2h / t23 this.initialJumpVelocity = (2 * this.jumpHeight) / this.timeToJumpApex;24 }2526 jump() {27 if (this.isGrounded) {28 this.vy = -this.initialJumpVelocity; // 上向き(Canvas座標系はY下向き)29 this.isGrounded = false;30 }31 }3233 update(dt: number) {34 if (!this.isGrounded) {35 this.vy += this.gravity * dt; // 速度の更新36 this.y += this.vy * dt; // 位置の更新 (二次関数軌道)3738 // 地面判定 (地面Y=0とする)39 if (this.y >= 0) {40 this.y = 0;41 this.vy = 0;42 this.isGrounded = true;43 }44 }45 }46}
次に学ぶならコレ!おすすめトピック
この単元と深い繋がりを持つ、あわせて学ぶと理解が深まるおすすめ単元