private void DistributeCollision() { if (!DoPhysics) { return; } switch (LeCollisionType) { case CollisionType.Circle_Circle: DistX = Body1._position.x - Body2._position.x; DistY = Body1._position.y - Body2._position.y; dist = FixedMath.Sqrt((DistX * DistX + DistY * DistY) >> FixedMath.SHIFT_AMOUNT); if (dist == 0) { //If objects are on the same position, give them push in random direction const long randomMax = FixedMath.One / 32; Body1._position.x += LSUtility.GetRandomLong(randomMax) - randomMax / 2; Body1._position.y += LSUtility.GetRandomLong(randomMax) - randomMax / 2; Body1.PositionChanged = true; Body2._position.x += LSUtility.GetRandomLong(randomMax) - randomMax / 2; Body2._position.y += LSUtility.GetRandomLong(randomMax) - randomMax / 2; Body2.PositionChanged = true; return; } depth = (Body1.Radius + Body2.Radius - dist); if (depth <= 0) { return; } DistX = (DistX * depth / dist); DistY = (DistY * depth / dist); //Resolving collision if (Body1.Immovable || (Body2.Immovable == false && Body1.Priority > Body2.Priority)) { DistX *= -1; DistY *= -1; DistributeCircle_CirclePriority(Body1, Body2); } else if (Body2.Immovable || Body2.Priority > Body1.Priority) { DistributeCircle_CirclePriority(Body2, Body1); } else { DistX /= 2; DistY /= 2; DistributeCircle(Body1); DistX *= -1; DistY *= -1; DistributeCircle(Body2); } break; case CollisionType.Circle_AABox: if (Body1.Shape == ColliderType.AABox) { DistributeCircle_Box(Body1, Body2); } else { DistributeCircle_Box(Body2, Body1); } break; case CollisionType.Circle_Polygon: if (Body1.Shape == ColliderType.Circle) { this.DistributeCircle_Poly(Body1, Body2); } else { this.DistributeCircle_Poly(Body2, Body1); } break; } }
private void DistributeCollision() { if (!DoPhysics) { return; } switch (LeCollisionType) { case CollisionType.Circle_Circle: DistX = Body1._position.x - Body2._position.x; DistY = Body1._position.y - Body2._position.y; dist = FixedMath.Sqrt((DistX * DistX + DistY * DistY) >> FixedMath.SHIFT_AMOUNT); if (dist == 0) { //If objects are on the same position, give them push in random direction const long randomMax = FixedMath.One / 32; Body1._position.x += LSUtility.GetRandomLong(randomMax) - randomMax / 2; Body1._position.y += LSUtility.GetRandomLong(randomMax) - randomMax / 2; Body1.PositionChanged = true; Body2._position.x += LSUtility.GetRandomLong(randomMax) - randomMax / 2; Body2._position.y += LSUtility.GetRandomLong(randomMax) - randomMax / 2; Body2.PositionChanged = true; return; } depth = (Body1.Radius + Body2.Radius - dist); if (depth <= 0) { return; } DistX = (DistX * depth / dist) / 2L; DistY = (DistY * depth / dist) / 2L; //Switch, used to be const bool applyVelocity = false; //Resolving collision //TODO: Less copy-paste code if (Body1.Immovable || (Body2.Immovable == false && Body1.Priority > Body2.Priority)) { DistX *= -1; DistY *= -1; if (Body1.Immovable || Body2.ImmovableCollisionDirection.EqualsZero()) { Body2._position.x += DistX; Body2._position.y += DistY; Body2.PositionChanged = true; Body2.ImmovableCollisionDirection = new Vector2d(DistX, DistY); if (applyVelocity) { Body2._velocity.x += DistX; Body2._velocity.y += DistY; Body2.VelocityChanged = true; } } else { //Only move if there isn't an immovable object in that direction if (Body2.ImmovableCollisionDirection.x.Sign() != DistX.Sign()) { Body1._position.x += DistX; } if (Body2.ImmovableCollisionDirection.y.Sign() != DistY.Sign()) { Body1._position.y += DistY; } } } else if (Body2.Immovable || Body2.Priority > Body1.Priority) { if (Body2.Immovable || Body1.ImmovableCollisionDirection.EqualsZero()) { Body2.ImmovableCollisionDirection = new Vector2d(DistX, DistY); Body1._position.x += DistX; Body1._position.y += DistY; Body1.PositionChanged = true; if (applyVelocity) { Body1._velocity.x += DistX; Body1._velocity.y += DistY; Body1.VelocityChanged = true; } } else { //Only move if there isn't an immovable object in that direction if (Body1.ImmovableCollisionDirection.x.Sign() != DistX.Sign()) { Body2._position.x += DistX; } if (Body1.ImmovableCollisionDirection.y.Sign() != DistY.Sign()) { Body2._position.y += DistY; } } } else { DistX /= 2; DistY /= 2; Body1._position.x += DistX; Body1._position.y += DistY; Body2._position.x -= DistX; Body2._position.y -= DistY; Body1.PositionChanged = true; Body2.PositionChanged = true; if (applyVelocity) { DistX /= 8; DistY /= 8; Body1._velocity.x += DistX; Body1._velocity.y += DistY; Body1.VelocityChanged = true; Body2._velocity.x -= DistX; Body2._velocity.y -= DistY; Body2.VelocityChanged = true; } } break; case CollisionType.Circle_AABox: if (Body1.Shape == ColliderType.AABox) { DistributeCircle_Box(Body1, Body2); } else { DistributeCircle_Box(Body2, Body1); } break; case CollisionType.Circle_Polygon: if (Body1.Shape == ColliderType.Circle) { this.DistributeCircle_Poly(Body1, Body2); } else { this.DistributeCircle_Poly(Body2, Body1); } break; } }