Game Development Reference
In-Depth Information
// Impulse 1 = -Delta * [ DX, DY ].
// Impulse 2 = Delta * [ DX, DY ].
var DX = Cars[j].X - Cars[i].X;
var DY = Cars[j].Y - Cars[i].Y;
var Delta = (DX * (Cars[i].VX - Cars[j].VX)
+ DY * (Cars[i].VY - Cars[j].VY)) / (DX * DX + DY * DY);
// If they're proceeding away from the collision,
// (r_j - r_i) . (v_i - v_j) <= 0,
// then we already dealt with the collision. This is similar to the
// consideration we made for collisions at the wall.
if (Delta <= 0) continue;
Impulses.push([i, j, Delta * DX, Delta * DY]);
}
}
}
This is the meat of the game's physics. Every collision, even with walls, gives rise to an impulse that will
change the cars' velocities. Now, applying the impulses is very straightforward, as shown in Listing 9-4.
Listing 9-4. Continuation of RunGameFrame
// Apply impulses.
for (var i = 0; i < Impulses.length; i++)
{
// Wall collisions specify null for one of the car indices, because there is no
// second car involved. Therefore we are careful not to refer to an index which
// doesn't belong to the Cars array.
if (Impulses[i][0] in Cars)
{
Cars[Impulses[i][0]].VX -= Impulses[i][2];
Cars[Impulses[i][0]].VY -= Impulses[i][3];
}
if (Impulses[i][1] in Cars)
{
Cars[Impulses[i][1]].VX += Impulses[i][2];
Cars[Impulses[i][1]].VY += Impulses[i][3];
}
}
Finally, we can't let things get too crazy, so we enforce the speed limit mentioned earlier. We also throw in
friction for good measure, as shown in Listing 9-5.
Listing 9-5. Continuation of RunGameFrame
// Enforce speed limit and apply friction.
for (var i = 0; i < Cars.length; i++)
{
// Scale down the car's speed if it's breaking the speed limit.
var Speed = Math.sqrt(Cars[i].VX * Cars[i].VX + Cars[i].VY * Cars[i].VY);
if (Speed >= GP.MaxSpeed)
{
 
Search WWH ::




Custom Search