예제 #1
0
        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;
            }
        }
예제 #2
0
        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;
            }
        }