mirror of
https://github.com/photonstorm/phaser
synced 2024-12-24 20:13:35 +00:00
Fix circles collision
This commit is contained in:
parent
566df734a0
commit
24d3406b7d
1 changed files with 13 additions and 84 deletions
|
@ -1504,11 +1504,6 @@ var World = new Class({
|
||||||
GetOverlapX(body1, body2, false, bias);
|
GetOverlapX(body1, body2, false, bias);
|
||||||
GetOverlapY(body1, body2, false, bias);
|
GetOverlapY(body1, body2, false, bias);
|
||||||
|
|
||||||
var dx = body2.center.x - body1.center.x;
|
|
||||||
var dy = body2.center.y - body1.center.y;
|
|
||||||
|
|
||||||
var angleCollision = Math.atan2(dy, dx);
|
|
||||||
|
|
||||||
var overlap = 0;
|
var overlap = 0;
|
||||||
|
|
||||||
if (body1.isCircle !== body2.isCircle)
|
if (body1.isCircle !== body2.isCircle)
|
||||||
|
@ -1568,94 +1563,28 @@ var World = new Class({
|
||||||
return (overlap !== 0);
|
return (overlap !== 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transform the velocity vector to the coordinate system oriented along the direction of impact.
|
var dx = body1.position.x - body2.position.x;
|
||||||
// This is done to eliminate the vertical component of the velocity
|
var dy = body1.position.y - body2.position.y;
|
||||||
|
var d = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
|
||||||
|
var nx = (body2.position.x - body1.position.x) / d;
|
||||||
|
var ny = (body2.position.y - body1.position.y) / d;
|
||||||
|
var p = 2 * (body1.velocity.x * nx + body1.velocity.y * ny - body2.velocity.x * nx - body2.velocity.y * ny) / (body1.mass + body2.mass);
|
||||||
|
|
||||||
var b1vx = body1.velocity.x;
|
|
||||||
var b1vy = body1.velocity.y;
|
|
||||||
var b1mass = body1.mass;
|
|
||||||
|
|
||||||
var b2vx = body2.velocity.x;
|
|
||||||
var b2vy = body2.velocity.y;
|
|
||||||
var b2mass = body2.mass;
|
|
||||||
|
|
||||||
var v1 = {
|
|
||||||
x: b1vx * Math.cos(angleCollision) + b1vy * Math.sin(angleCollision),
|
|
||||||
y: b1vx * Math.sin(angleCollision) - b1vy * Math.cos(angleCollision)
|
|
||||||
};
|
|
||||||
|
|
||||||
var v2 = {
|
|
||||||
x: b2vx * Math.cos(angleCollision) + b2vy * Math.sin(angleCollision),
|
|
||||||
y: b2vx * Math.sin(angleCollision) - b2vy * Math.cos(angleCollision)
|
|
||||||
};
|
|
||||||
|
|
||||||
// We expect the new velocity after impact
|
|
||||||
var tempVel1 = ((b1mass - b2mass) * v1.x + 2 * b2mass * v2.x) / (b1mass + b2mass);
|
|
||||||
var tempVel2 = (2 * b1mass * v1.x + (b2mass - b1mass) * v2.x) / (b1mass + b2mass);
|
|
||||||
|
|
||||||
// We convert the vector to the original coordinate system and multiplied by factor of rebound
|
|
||||||
if (!body1.immovable)
|
if (!body1.immovable)
|
||||||
{
|
{
|
||||||
body1.velocity.x = (tempVel1 * Math.cos(angleCollision) - v1.y * Math.sin(angleCollision)) * body1.bounce.x;
|
body1.velocity.x = (body1.velocity.x - p * body1.mass * nx) * body1.bounce.x;
|
||||||
body1.velocity.y = (v1.y * Math.cos(angleCollision) + tempVel1 * Math.sin(angleCollision)) * body1.bounce.y;
|
body1.velocity.y = (body1.velocity.y - p * body1.mass * ny) * body1.bounce.y;
|
||||||
|
|
||||||
// Reset local var
|
|
||||||
b1vx = body1.velocity.x;
|
|
||||||
b1vy = body1.velocity.y;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!body2.immovable)
|
if (!body2.immovable)
|
||||||
{
|
{
|
||||||
body2.velocity.x = (tempVel2 * Math.cos(angleCollision) - v2.y * Math.sin(angleCollision)) * body2.bounce.x;
|
body2.velocity.x = (body2.velocity.x + p * body2.mass * nx) * body2.bounce.x;
|
||||||
body2.velocity.y = (v2.y * Math.cos(angleCollision) + tempVel2 * Math.sin(angleCollision)) * body2.bounce.y;
|
body2.velocity.y = (body2.velocity.y + p * body2.mass * ny) * body2.bounce.y;
|
||||||
|
|
||||||
// Reset local var
|
|
||||||
b2vx = body2.velocity.x;
|
|
||||||
b2vy = body2.velocity.y;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// When the collision angle is almost perpendicular to the total initial velocity vector
|
var dvx = body2.velocity.x - body1.velocity.x;
|
||||||
// (collision on a tangent) vector direction can be determined incorrectly.
|
var dvy = body2.velocity.y - body1.velocity.y;
|
||||||
// This code fixes the problem
|
var angleCollision = Math.atan2(dvy, dvx);
|
||||||
|
|
||||||
if (Math.abs(angleCollision) < Math.PI / 2)
|
|
||||||
{
|
|
||||||
if ((b1vx > 0) && !body1.immovable && (b2vx > b1vx))
|
|
||||||
{
|
|
||||||
body1.velocity.x *= -1;
|
|
||||||
}
|
|
||||||
else if ((b2vx < 0) && !body2.immovable && (b1vx < b2vx))
|
|
||||||
{
|
|
||||||
body2.velocity.x *= -1;
|
|
||||||
}
|
|
||||||
else if ((b1vy > 0) && !body1.immovable && (b2vy > b1vy))
|
|
||||||
{
|
|
||||||
body1.velocity.y *= -1;
|
|
||||||
}
|
|
||||||
else if ((b2vy < 0) && !body2.immovable && (b1vy < b2vy))
|
|
||||||
{
|
|
||||||
body2.velocity.y *= -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (Math.abs(angleCollision) > Math.PI / 2)
|
|
||||||
{
|
|
||||||
if ((b1vx < 0) && !body1.immovable && (b2vx < b1vx))
|
|
||||||
{
|
|
||||||
body1.velocity.x *= -1;
|
|
||||||
}
|
|
||||||
else if ((b2vx > 0) && !body2.immovable && (b1vx > b2vx))
|
|
||||||
{
|
|
||||||
body2.velocity.x *= -1;
|
|
||||||
}
|
|
||||||
else if ((b1vy < 0) && !body1.immovable && (b2vy < b1vy))
|
|
||||||
{
|
|
||||||
body1.velocity.y *= -1;
|
|
||||||
}
|
|
||||||
else if ((b2vy > 0) && !body2.immovable && (b1vx > b2vy))
|
|
||||||
{
|
|
||||||
body2.velocity.y *= -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var delta = this._frameTime;
|
var delta = this._frameTime;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue