示例#1
0
 // chuyển từ Box sang Broadphase dùng để khoanh vùng đối tượng
 public Box BoxToBroadPhase(Box b)
 {
     return(SweptAABB.GetBroadPhaseBox(b));
 }
示例#2
0
        public DirectCollision CheckCollision(CAnimationObject _Object)
        {
            #region . Thuật toán sweptAABB cũ
            //float DisMinX, DisMaxX;
            //float DisMinY, DisMaxY;

            //Vector2 tempVelocity;
            //tempVelocity = new Vector2(m_Velocity.X - _Object.Velocity.X, m_Velocity.Y - _Object.Velocity.Y);
            //if (tempVelocity.X > 0.0f)
            //{
            //    DisMinX = _Object.Position.X - (Position.X + m_Sprite.FrameWidht);
            //    DisMaxX = (_Object.Position.X + _Object.Sprite.FrameWidht) - (Position.X);
            //}
            //else
            //{
            //    DisMinX = (_Object.Position.X + _Object.Sprite.FrameWidht) - (Position.X);
            //    DisMaxX = _Object.Position.X - (Position.X + m_Sprite.FrameWidht);
            //}

            //if (tempVelocity.Y > 0.0f)
            //{
            //    DisMinY = _Object.Position.Y - (Position.Y + m_Sprite.FrameHeight);
            //    DisMaxY = (_Object.Position.Y + _Object.Sprite.FrameHeight) - (Position.Y);
            //}
            //else
            //{
            //    DisMinY = (_Object.Position.Y + _Object.Sprite.FrameHeight) - (Position.Y);
            //    DisMaxY = _Object.Position.Y - (Position.Y + m_Sprite.FrameHeight);
            //}

            //float EntryTimeX, ExitTimeX;
            //float EntryTimeY, ExitTimeY;

            //if (m_Velocity.X == 0.0f)
            //{
            //    EntryTimeX = float.NegativeInfinity;
            //    ExitTimeX = float.PositiveInfinity;
            //}
            //else
            //{
            //    EntryTimeX = DisMinX / (tempVelocity.X * m_GameTime);
            //    ExitTimeX = DisMaxX / (tempVelocity.X * m_GameTime);
            //}

            //if (m_Velocity.Y == 0.0f)
            //{
            //    EntryTimeY = float.NegativeInfinity;
            //    ExitTimeY = float.PositiveInfinity;
            //}
            //else
            //{
            //    EntryTimeY = DisMinY / (tempVelocity.Y * m_GameTime);
            //    ExitTimeY = DisMaxY / (tempVelocity.Y * m_GameTime);
            //}

            //if (m_Velocity.X == 0.0f && _Object.Velocity.X != 0)
            //{
            //    EntryTimeX = DisMinX / (tempVelocity.X * m_GameTime);
            //    ExitTimeX = DisMaxX / (tempVelocity.X * m_GameTime);
            //}

            //if (m_Velocity.Y == 0.0f && _Object.Velocity.Y != 0)
            //{
            //    EntryTimeY = DisMinY / (tempVelocity.Y * m_GameTime);
            //    ExitTimeY = DisMaxY / (tempVelocity.Y * m_GameTime);
            //}

            //float EntryTime;
            //float ExitTime;

            //EntryTime = Math.Max(EntryTimeX, EntryTimeY);
            //ExitTime = Math.Min(ExitTimeX, ExitTimeY);

            //if (EntryTime > ExitTime)
            //    return DirectCollision.NONE;
            //if (EntryTimeX < 0.0f && EntryTimeY < 0.0f)
            //    return DirectCollision.NONE;
            //if (EntryTimeX > 1.0f || EntryTimeY > 1.0f)
            //    return DirectCollision.NONE;

            //if (EntryTimeX < 0.0f)
            //{
            //    if (Position.X + Sprite.FrameWidht < _Object.Position.X || Position.X > _Object.Position.X + _Object.Sprite.FrameWidht)
            //        return DirectCollision.NONE;
            //}
            //if (EntryTimeY < 0.0f)
            //{
            //    if (Position.Y + Sprite.FrameHeight < _Object.Position.Y || Position.Y > _Object.Position.Y + _Object.Sprite.FrameHeight)
            //        return DirectCollision.NONE;
            //}


            //if (EntryTimeX > EntryTimeY && Position.Y + Sprite.FrameHeight != _Object.Position.Y)
            //{
            //    if (DisMinX < 0.0f)
            //    {
            //        return DirectCollision.RIGHT;
            //    }
            //    else
            //    {
            //        return DirectCollision.LEFT;
            //    }
            //}
            //else
            //{
            //    if (DisMinY < 0.0f)
            //    {
            //        return DirectCollision.BOTTOM;
            //    }
            //    else
            //    {
            //        return DirectCollision.TOP;
            //    }
            //}
            #endregion

            float   moveX        = 0.0f;
            float   moveY        = 0.0f;
            float   normalX      = 0.0f;
            float   normalY      = 0.0f;
            float   timeCollsion = 0.0f;
            Vector2 velocity     = Vector2.Zero;

            // kiểm tra 2 vật có va chạm với nhau không (không tính trường hợp có vận tốc)
            if (SweptAABB.CheckAABB(this.GetBox(), _Object.GetBox(), ref moveX, ref moveY) == false)
            {
                // nếu vật thứ 2 có vận tốc thì ta trừ vận tốc với nhau, xem vật thứ 2 là vật tĩnh
                velocity = new Vector2(this.Velocity.X - _Object.Velocity.X, this.Velocity.Y - _Object.Velocity.Y);
                // kiểm tra xem vật thứ 2 có nằm trong vùng di chuyển của vật 1 hay không ?
                if (SweptAABB.CheckAABB(this.BoxToBroadPhase(GetBox(velocity)), _Object.GetBox(), ref moveX, ref moveY) == true)
                {
                    // chạy sweptAABB, nếu có khả năng xảy ra va chạm
                    timeCollsion = SweptAABB.Swept_AABB(GetBox(velocity), _Object.GetBox(), ref normalX, ref normalY);
                    if (timeCollsion < 1.0f && timeCollsion > 0.0f)
                    {
                        if (Math.Abs(m_MoveX) >= Math.Abs(velocity.X * m_GameTime * timeCollsion + normalX))
                        {
                            m_MoveX = velocity.X * m_GameTime * timeCollsion + normalX;
                        }

                        if (Math.Abs(m_MoveY) >= Math.Abs(velocity.Y * m_GameTime * timeCollsion + normalY))
                        {
                            m_MoveY = velocity.Y * m_GameTime * timeCollsion + normalY; // trong collision tao lam += move Y ma, ko chuyên position
                        }

                        if (normalX != 0)
                        {
                            if (moveX != 0)
                            {
                                if (normalX == 1)
                                {
                                    return(DirectCollision.RIGHT);
                                }
                                else if (normalX == -1)
                                {
                                    return(DirectCollision.LEFT);
                                }
                            }
                        }
                        else
                        {
                            if (moveY != 0)
                            {
                                if (normalY == -1)
                                {
                                    return(DirectCollision.TOP);
                                }
                                else if (normalY == 1)
                                {
                                    return(DirectCollision.BOTTOM);
                                }
                            }
                        }
                    }
                }
                else
                {
                    // làm cái gì đó tùy thích !!!!!
                }
            }
            else
            {
                m_MoveX = moveX;
                m_MoveY = moveY;

                //if (m_MoveX <= moveX)
                //    m_MoveX = moveX;

                //if (m_MoveY <= moveY)
                //    m_MoveY = moveY;

                if (moveX != 0)
                {
                    if (moveX < 0.0f)
                    {
                        return(DirectCollision.LEFT);
                    }
                    else
                    {
                        return(DirectCollision.RIGHT);
                    }
                }
                else if (moveY != 0)
                {
                    if (moveY <= 0.0f)
                    {
                        return(DirectCollision.TOP);
                    }
                    else
                    {
                        return(DirectCollision.BOTTOM);
                    }
                }
                else
                {
                    if ((GetBound().X + GetBound().Width == _Object.GetBound().X&& GetBound().Y + GetBound().Height == _Object.GetBound().Y) ||
                        (GetBound().X == _Object.GetBound().X + _Object.GetBound().Width&& GetBound().Y + GetBound().Height == _Object.GetBound().Y))
                    {
                        return(DirectCollision.NONE);
                    }

                    if (GetBound().Y + GetBound().Height == _Object.GetBound().Y)
                    {
                        m_Position.Y -= 0.0001f;
                        return(DirectCollision.TOP);
                    }
                    else if (_Object.GetBound().Y + _Object.GetBound().Height == GetBound().Y)
                    {
                        m_Position.Y += 0.0001f;
                        return(DirectCollision.BOTTOM);
                    }
                    else if (GetBound().X + GetBound().Width == _Object.GetBound().X)
                    {
                        m_Position.X -= 0.0001f;
                        return(DirectCollision.LEFT);
                    }
                    else if (_Object.GetBound().X + _Object.GetBound().Width == GetBound().X)
                    {
                        m_Position.X += 0.0001f;
                        return(DirectCollision.RIGHT);
                    }
                }
            }

            return(DirectCollision.NONE);
        }
示例#3
0
        void Update()
        {
            _collided          = false;
            _withColliderIndex = -1;

            if (debug_positions.Count > 1)
            {
                for (int i = 1; i < debug_positions.Count; i++)
                {
                    Debug.DrawLine(debug_positions[i - 1], debug_positions[i], Color.yellow);
                }
            }

            var input  = _inputMaster.Player.Movement.ReadValue <Vector2>();
            var action = (short)_inputMaster.Player.MainAction.ReadValue <float>();

            float3 position = transform.position;

            //var direction = new float2(input.x, input.y);

            if (input.sqrMagnitude < 0.01)
            {
                return;
            }
            //Debug.Log($"Input {input}");
            //var vx = (input.x * Time.deltaTime * speed) * Time.realtimeSinceStartup;
            //var vy = (input.y * Time.deltaTime * speed) * Time.realtimeSinceStartup;

            var vx = input.x * Time.deltaTime * speed;
            var vy = input.y * Time.deltaTime * speed;

            var box = new Box(position.x - size * 0.5f, position.z - size * 0.5f, size, size, vx, vy);
            //var box = new Box(position.x, position.z, size, size, vx, vy );

            float   moveX         = 0.0f;
            float   moveY         = 0.0f;
            float   normalX       = 0.0f;
            float   normalY       = 0.0f;
            float   collisionTime = 1.0f;
            Vector2 velocity      = Vector2.zero;

            for (var index = 0; index < colliders.Count; index++)
            {
                var collider = colliders[index];
                if (collider.Type != ColliderType.Box)
                {
                    continue;
                }

                var broadPhaseBox = SweptAABB.GetBroadPhaseBox(box);
                var block         = collider.ToBox();

                if (SweptAABB.CheckAABB(broadPhaseBox, block, ref normalX, ref normalY))
                {
                    _collided          = true;
                    _withColliderIndex = index;

                    collisionTime = SweptAABB.Swept(box, block, ref normalX, ref normalY);
                    //     box.x += box.vx * collisiontime;
                    //     box.y += box.vy * collisiontime;

                    Debug.Log($"Collided {collisionTime} {normalX} {normalY}");
                    break;
                }
            }

            var newPosition = Vector3.zero;

            if (_collided)
            {
                var remainingtime = 1.0f - collisionTime;

                if (collisionResolveType == PhysicsCollisionResolveType.Push)
                {
                    float magnitude = math.sqrt((box.vx * box.vx + box.vy * box.vy)) * remainingtime;
                    float dotprod   = box.vx * normalY + box.vy * normalX;

                    if (dotprod > 0.0f)
                    {
                        dotprod = 1.0f;
                    }
                    else if (dotprod < 0.0f)
                    {
                        dotprod = -1.0f;
                    }

                    box.vx = dotprod * normalY * magnitude;
                    box.vy = dotprod * normalX * magnitude;

                    newPosition = new Vector3(position.x + (box.vx), 0, position.z + (box.vy));
                }
                else if (collisionResolveType == PhysicsCollisionResolveType.Slide)
                {
                    float dotprod = (box.vx * normalY + box.vy * normalX) * remainingtime;

                    box.vx = dotprod * normalY;
                    box.vy = dotprod * normalX;

                    newPosition = new Vector3(position.x + (box.vx), 0, position.z + (box.vy));
                }
            }
            else
            {
                newPosition = new Vector3(position.x + (box.vx * collisionTime), 0,
                                          position.z + (box.vy * collisionTime));
            }

            transform.position = newPosition;
            debug_positions.Add(newPosition);
        }