私は詳細な回答をするつもりでしたが、この投稿に対する受け入れられた回答は、私が言おうとしていたことをほぼ要約しています. これは、最初に基本的な衝突検出を試みたときに遭遇する一般的な問題です。この問題の解決策は想像以上に複雑で、本質的には衝突点でのオブジェクトの位置を計算することです。
編集: 2 つのオブジェクトが衝突した時刻を正確に把握するには、次のようにします: (未テスト)
onCollide(obj1, obj2)
{
t = 0; //parametric value to store when objects first collided
// calculate when the obj1's left side collides with obj2's right side
// parametric equation is obj1.left + obj1.vel.x * t = obj2.right + obj2.vel.x * t
// solving for t: t = (obj1.left - obj2.right) / (obj2.vel.x - obj1.vel.x)
// we take the minimum because that is when the first sides collided
t = math.min(t, (obj1.left - obj2.right) / (obj2.vel.x - obj1.vel.x))
t = math.min(t, (obj1.right - obj2.left) / (obj2.vel.x - obj1.vel.x))// repeat for other sides
t = math.min(t, (obj1.top - obj2.bottom) / (obj2.vel.y - obj1.vel.y))
t = math.min(t, (obj1.bottom - obj2.top) / (obj2.vel.y - obj1.vel.y))
}
この時間を使用して、必要に応じてシミュレーション全体を巻き戻すことができます。または、これら 2 つのオブジェクトの状態を確認することもできます。min 関数を使用する代わりに、if ステートメントを使用して、どちらの側が最初に衝突したかを追跡できます。この計算は、そのタイム ステップで衝突する可能性のある複数のオブジェクトを追跡しないことに注意してください。ただし、通常、これは有効な近似値です。また、2 つのオブジェクトが一方の次元では同じ速度で移動し、他方の次元では移動していない場合は、0 で割らないようにする必要があることに注意してください。