Ejemplo n.º 1
0
        //Note: This code is inspired by:
        //URL: https://gamedevelopment.tutsplus.com/tutorials/how-to-create-a-custom-2d-physics-engine-the-basics-and-impulse-resolution--gamedev-6331
        //SAT Collision response is good, you will possess the vector to push the two objects from each other
        void Collider2D.CollisionResponse(Rigidbody2D YourRigidBody, Collider2D collider, float DeltaTime, ref List <GameObjectComponent> CDs, Vector2 CollisionPos, bool ResetVelocity)
        {
            if (collider is CircleCollider)
            {
                Rectangle      ThisCollider     = GetDynamicCollider();
                CircleCollider IncomingCollider = collider as CircleCollider;

                /////////////////////////This code is heavily inspired by "OneLoneCoder" the youtuber///////////////////////

                gameObject.Transform.Position = CollisionPos;
                // Statically resolve the collision
                gameObject.Transform.Position -= Vector2.Normalize(vRayToNearest) * fOverlap;

                if (IncomingCollider.gameObject.Transform.Position.Y + IncomingCollider.Center.Y > ThisCollider.Top && IncomingCollider.gameObject.Transform.Position.Y + IncomingCollider.Center.Y < ThisCollider.Bottom)
                {
                    YourRigidBody.Velocity.X = 0;
                }
                if (IncomingCollider.gameObject.Transform.Position.X + IncomingCollider.Center.X > ThisCollider.Left && IncomingCollider.gameObject.Transform.Position.X + IncomingCollider.Center.X < ThisCollider.Right)
                {
                    YourRigidBody.Velocity.Y = 0;
                }
            }
            else
            {
                Rectangle DC1 = GetDynamicCollider();
                Rectangle DC2 = (collider as BoxCollider2D).GetDynamicCollider();

                float DistanceBetweenCollidersX = YourRigidBody.Velocity.X > 0 ? Math.Abs(DC1.Right - DC2.Left) : Math.Abs(DC1.Left - DC2.Right);
                float DistanceBetweenCollidersY = YourRigidBody.Velocity.Y > 0 ? Math.Abs(DC1.Bottom - DC2.Top) : Math.Abs(DC1.Top - DC2.Bottom);

                float TimeBetweenCollidersX = YourRigidBody.Velocity.X != 0 ? Math.Abs(DistanceBetweenCollidersX / YourRigidBody.Velocity.X) : 0;
                float TimeBetweenCollidersY = YourRigidBody.Velocity.Y != 0 ? Math.Abs(DistanceBetweenCollidersY / YourRigidBody.Velocity.Y) : 0;

                float ShortestTime;
                var   OldPos = YourRigidBody.gameObject.Transform.Position;

                if (YourRigidBody.Velocity.X != 0 && YourRigidBody.Velocity.Y == 0)
                {
                    // Colliison on X-axis only
                    ShortestTime = TimeBetweenCollidersX;
                    YourRigidBody.gameObject.Transform.MoveX(ShortestTime * YourRigidBody.Velocity.X);
                    YourRigidBody.Velocity.X = ResetVelocity ? 0 : YourRigidBody.Velocity.X;
                }
                else if (YourRigidBody.Velocity.X == 0 && YourRigidBody.Velocity.Y != 0)
                {
                    // Colliison on Y-axis only
                    ShortestTime = TimeBetweenCollidersY;
                    YourRigidBody.gameObject.Transform.MoveY(ShortestTime * YourRigidBody.Velocity.Y);
                    YourRigidBody.Velocity.Y = ResetVelocity ? 0 : YourRigidBody.Velocity.Y;
                }
                else
                {
                    // Colliison on both axis
                    ShortestTime = Math.Min(TimeBetweenCollidersX, TimeBetweenCollidersY);
                    YourRigidBody.gameObject.Transform.Move(ShortestTime * YourRigidBody.Velocity.X, ShortestTime * YourRigidBody.Velocity.Y);
                    //YourRigidBody.Velocity = ResetVelocity? Vector2.Zero : YourRigidBody.Velocity;

                    if (SlideCollision)
                    {
                        if (ShortestTime == TimeBetweenCollidersX)
                        {
                            YourRigidBody.gameObject.Transform.Position.X = OldPos.X;
                            YourRigidBody.Velocity.X = ResetVelocity ? 0 : YourRigidBody.Velocity.X;

                            if (!collider.CollisionDetection(this, false))
                            {
                                YourRigidBody.gameObject.Transform.Position.Y = CollisionPos.Y;
                            }
                        }

                        if (ShortestTime == TimeBetweenCollidersY)
                        {
                            YourRigidBody.gameObject.Transform.Position.Y = OldPos.Y;
                            YourRigidBody.Velocity.Y = ResetVelocity ? 0 : YourRigidBody.Velocity.Y;

                            if (!collider.CollisionDetection(this, false))
                            {
                                YourRigidBody.gameObject.Transform.Position.X = CollisionPos.X;
                            }
                        }
                    }
                    else
                    {
                        YourRigidBody.Velocity = ResetVelocity ? Vector2.Zero : YourRigidBody.Velocity;
                    }
                }

                foreach (Collider2D CD in CDs)
                {
                    if (!gameObject.Name.Equals((CD as GameObjectComponent).gameObject.Name) && !CD.IsTrigger() && CD.CollisionDetection(this, false))
                    {
                        YourRigidBody.gameObject.Transform.Position = OldPos;
                        YourRigidBody.Velocity = Vector2.Zero;
                        break;
                    }
                }
            }
        }