2D盒实体碰撞

时间:2014-01-16 10:05:56

标签: c# collision gravity

我对碰撞的重力部分是一个严重的问题,它是基于平台的,但适用 对于我所做的一切都是关于包含重力的碰撞。

当实体击中地面时,它将不断地重新设置为不会撞击地面,不断地“真假虚假......”并且当它正在这样做时,实体的Y速度也在0.0和之间切换-0.3

如果实体在地面上,我需要它始终是真的,而不是看似反弹。

此外,如果用户手动控制实体的Y-Velocity,如果它与边界框的角碰撞,同时在角落方向具有X-Velocity,并且Y-Velocity直接朝向它(在X和Y之间反之亦然,它会卡住,吓坏了,然后决定在整个边界框中堵塞自己。

namespace StackOverFlowExample
{
    class Entity
    {
        /* ... */


        public Collision2D Col;             // The collision box for the Entity
        public bool isGrounded;             // Returns True if the Entity is on the ground
        private List<Collision2D> TestObjt; // Allows the Entity access to all of the other Collision2D instances
        public Vector2 Pos;                 // Entity's position
        public Vector2 V;                   // Entity's velocity


        // Declare the movement & collision Timer
        private Timer movementTimer = new Timer( 1 );


        private void UpdateCollision()
        {
            // Reset grounding
            this.Col.Direction = 0;
            this.isGrounded = false;

            // this.isAllowingInput = false;
            foreach ( Collision2D testObjt in this.TestObjt )
            {
                if ( this.Col.CheckCol( testObjt ) )
                    testObjt.CheckCol( this.Col, this );
            }
        }

        private void UpdatePosition()
        {
            this.Pos = Vector2.Add( this.Pos, this.V );
            this.Col.Sync( Convert.ToInt32( this.Pos.X ), Convert.ToInt32( this.Pos.Y ) );
        }

        private void UpdateGravity()
        {
            if ( this.isGrounded == false )
            {
                this.V.Y = this.V.Y + 0.3F;
            } else this.V.Y = 0;
        }

        private void movementEvent( object source, ElapsedEventArgs e )
        {
            // Call Methods
            this.UpdatePosition();

            this.UpdateCollision();

            this.UpdateGravity();
        }
    }

    class Collision2D
    {
        public Vector2 Pos1;   // Top,    Left
        public Vector2 Pos2;   // Bottom, Right

        public int Direction;  // Direction of collision

        public void Sync( int NewX, int NewY )
        {
            float W = Pos2.X - Pos1.X; // Generate Width
            float H = Pos2.Y - Pos1.Y; // Generate Height

            this.Pos1.X = NewX;
            this.Pos1.Y = NewY;

            this.Pos2.X = NewX + W;
            this.Pos2.Y = NewY + H;
        }

        // Returns true if there is a collision
        public bool CheckCol( Collision2D objt )
        {
            bool r = true;

            if ( this.Pos2.Y < objt.Pos1.Y || this.Pos1.Y > objt.Pos2.Y || this.Pos2.X < objt.Pos1.X || this.Pos1.X > objt.Pos2.X )
                r = false;

            return r;
        }

        // Collision actions on Entity
        public void CheckCol( Collision2D objt, Entity ent )
        {
            switch ( ent.Col.GetDirection( this ) )
            {
                // Ceiling Collision Actions
                case 1:
                    ent.Pos.Y = ent.Pos.Y - ent.V.Y;
                    break;

                // Floor Collision Actions
                case 2:
                    ent.Pos.Y = ent.Pos.Y - ent.V.Y;
                    ent.isGrounded = true;  // Place Entity on the ground for Gravity actions
                    break;

                // Right Wall Collision Actions
                case 3:
                    ent.Pos.X = ent.Pos.X - ent.V.X;
                    break;

                // Left Wall Collision Actions
                case 4:
                    ent.Pos.X = ent.Pos.X - ent.V.X;
                    break;
            }

            // Resync the collision bounding box for the entity
            ent.Col.Sync( Convert.ToInt32( ent.Pos.X ), Convert.ToInt32( ent.Pos.Y ) );
        }

        public int GetDirection( Collision2D objt )
        {
            int r;

            r = 0;

            if ( objt.Pos2.Y - this.Pos1.Y < this.Pos2.Y - objt.Pos1.Y &&
                objt.Pos2.Y - this.Pos1.Y < this.Pos2.X - objt.Pos1.X &&
                objt.Pos2.Y - this.Pos1.Y < objt.Pos2.X - this.Pos1.X )
                r = 1; // Up

            if ( this.Pos2.Y - objt.Pos1.Y < objt.Pos2.Y - this.Pos1.Y &&
                this.Pos2.Y - objt.Pos1.Y < this.Pos2.X - objt.Pos1.X &&
                this.Pos2.Y - objt.Pos1.Y < objt.Pos2.X - this.Pos1.X )
                r = 2; // Down

            if ( objt.Pos2.X - this.Pos1.X < this.Pos2.X - objt.Pos1.X &&
                objt.Pos2.X - this.Pos1.X < this.Pos2.Y - objt.Pos1.Y &&
                objt.Pos2.X - this.Pos1.X < objt.Pos2.Y - this.Pos1.Y )
                r = 3; // Right

            if ( this.Pos2.X - objt.Pos1.X < objt.Pos2.X - this.Pos1.X &&
                this.Pos2.X - objt.Pos1.X < this.Pos2.Y - objt.Pos1.Y &&
                this.Pos2.X - objt.Pos1.X < objt.Pos2.Y - this.Pos1.Y )
                r = 4; // Left

            return r;
        }
    }
}

0 个答案:

没有答案