マリオのジャンプ実装法とVerlet積分
(追記)JavaScriptで実装してみました
昔、何かの雑誌*1でマリオのジャンプの実装法を見た覚えがあって、あの放物線運動は、
マリオの速度ベクトルを保存しておいて座標を計算するんじゃなくて、
マリオの前回の座標を保存しておいて座標を計算しているんだそうです。
y_temp = Mario.y; Mario.y += (Mario.y - Mario.y_prev) + F; Mario.y_prev = y_temp;
Fはその瞬間の力で、ジャンプの瞬間はF=10にして、空中ではF=-1にします。
するとこんな放物線になります。
[0,10,19, 27, 34, 40, 45, 49, 52, 54, 55, 55, 54, 52, 49, 45, 40, 34, 27, 19, 10, 0]
加減算しか使わないので、非常に高速にできたと。
これがVerlet積分に似ているなと思ったのが今日の本題。
次に、オイラー法を作ったつもりが実はシンプレクティックになっているで有名な Verletを使ってみた。見た目オイラー法なので実装はすっごい楽である。
(中略)
Verletはプログラム楽だわ、エネルギー保存するわ、計算時間半分だわで RK(ルンゲ=クッタ)いいとこ無しという感じである。
引用元
Cowboy Programming » Blob Physicsにある話なんですが、
Verletだと座標だけで話が完結するので、壁にめりこんじゃいけないといった制約条件の記述がすごく楽。
普通だと、速度から未来の座標を計算するわけですが、そこで壁にめりこまないように"速度を調整する"のは、面倒なんです。
マリオもジャンプすれば壁に当たるので、このテクニックを使ってたんじゃないかな。