Пример #1
0
        public virtual void HandleCollision( CollisionResult result,ICollideObj objA, ICollideObj objB )
        {
            Pos += result.NormalVector * BaseGame.CoordinMgr.LogicLength( 0.5f );

            if (OnCollied != null)
                OnCollied( result, objA, objB );
        }
Пример #2
0
        /// <summary>
        /// 检测是否在边界矩形外
        /// </summary>
        /// <param name="BorderRect"></param>
        /// <returns></returns>
        public CollisionResult CheckOutBorder(Rectanglef BorderRect)
        {
            if (!this.mSupportIntersectDect)
            {
                throw new Exception("the sprite doesn't support IntersectDect!");
            }

            UpdateTransformBounding();

            CollisionResult result     = new CollisionResult();
            Rectanglef      screenRect = BorderRect;


            if (!this.mBounding.Intersects(screenRect))
            {
                result.IsCollided = false;
                return(result);
            }

            int widthA  = this.mTexture.Width;
            int heightA = this.mTexture.Height;

            // Calculate a matrix which transforms from A's local space into
            // world space
            Matrix transformAToWorld = mTransform;

            Vector2 stepX = Vector2.TransformNormal(Vector2.UnitX, transformAToWorld);
            Vector2 stepY = Vector2.TransformNormal(Vector2.UnitY, transformAToWorld);

            Vector2 oriPosInWorld = Vector2.Transform(Vector2.Zero, transformAToWorld);


            CircleList <BorderPoint>     list = mBorder.BorderCircle;
            CircleListNode <BorderPoint> cur  = list.First;

            bool justStart = true;
            bool find      = false;

            CircleListNode <BorderPoint> firstNode = cur;
            int length = 0;

            #region 找出第一个相交点和该连续相交线的长度
            for (int i = 0; i < list.Length; i++)
            {
                Point bordPointA = cur.value.p;

                if (PointOutBorder(oriPosInWorld, stepX, stepY, bordPointA, screenRect))
                {
                    if (!justStart)
                    {
                        if (!find)
                        {
                            find      = true;
                            firstNode = cur;
                        }
                        else
                        {
                            length++;
                        }
                    }
                    else
                    {
                        CircleListNode <BorderPoint> temp = cur.pre;

                        int leftLength = list.Length;
                        while (PointOutBorder(oriPosInWorld, stepX, stepY, temp.value.p, screenRect) && leftLength >= 0)
                        {
                            temp = temp.pre;
                            leftLength--;
                        }
                        cur = temp;
                        i--;
                        justStart = false;
                    }
                }
                else
                {
                    justStart = false;

                    if (find)
                    {
                        break;
                    }
                }

                cur = cur.next;
            }
            #endregion

            if (find)
            {
                cur = firstNode;

                for (int i = 0; i < Math.Round((float)length / 2); i++)
                {
                    cur = cur.next;
                }

                Point bordPointA = cur.value.p;
                result.IsCollided = true;
                Vector2 InterPos = Vector2.Transform(new Vector2(bordPointA.X, bordPointA.Y), mTransform);
                result.NormalVector = Vector2.Transform(mBorder.GetNormalVector(cur, mAverageSum), mTransform)
                                      - Vector2.Transform(Vector2.Zero, mTransform);
                result.NormalVector.Normalize();
                result.InterPos = InterPos;
                return(result);
            }


            // No intersection found
            result.IsCollided = false;
            return(result);
        }
Пример #3
0
        /// <summary>
        /// Determines if there is overlap of the non-transparent pixels between two
        /// sprites.
        /// 检查两个精灵是否发生碰撞
        /// </summary>
        /// <returns>True if non-transparent pixels overlap; false otherwise</returns>
        public static CollisionResult IntersectPixels(Sprite spriteA, Sprite spriteB)
        {
            if (!spriteA.mSupportIntersectDect || !spriteB.mSupportIntersectDect)
            {
                throw new Exception("At lest one of the two sprite doesn't support IntersectDect!");
            }

            spriteA.UpdateTransformBounding();
            spriteB.UpdateTransformBounding();

            CollisionResult result = new CollisionResult();

            if (!spriteA.mBounding.Intersects(spriteB.mBounding))
            {
                result.IsCollided = false;
                return(result);
            }

            int widthA  = spriteA.mTexture.Width;
            int heightA = spriteA.mTexture.Height;
            int widthB  = spriteB.mTexture.Width;
            int heightB = spriteB.mTexture.Height;

            // Calculate a matrix which transforms from A's local space into
            // world space and then into B's local space
            Matrix transformAToB = spriteA.mTransform * Matrix.Invert(spriteB.mTransform);

            // When a point moves in A's local space, it moves in B's local space with a
            // fixed direction and distance proportional to the movement in A.
            // This algorithm steps through A one pixel at a time along A's X and Y axes
            // Calculate the analogous steps in B:
            Vector2 stepX = Vector2.TransformNormal(Vector2.UnitX, transformAToB);
            Vector2 stepY = Vector2.TransformNormal(Vector2.UnitY, transformAToB);

            // Calculate the top left corner of A in B's local space
            // This variable will be reused to keep track of the start of each row
            Vector2 oriPosInB = Vector2.Transform(Vector2.Zero, transformAToB);

            CircleList <BorderPoint>     list = spriteA.mBorder.BorderCircle;
            CircleListNode <BorderPoint> cur  = list.First;

            bool justStart = true;
            bool find      = false;

            CircleListNode <BorderPoint> firstNode = cur;
            int length = 0;

            #region 找出第一个相交点和该连续相交线的长度
            for (int i = 0; i < list.Length; i++)
            {
                Point bordPointA = cur.value.p;

                if (SpriteBBlockAtPos(spriteB, oriPosInB, stepX, stepY, bordPointA))
                {
                    if (!justStart)
                    {
                        if (!find)
                        {
                            find      = true;
                            firstNode = cur;
                        }
                        else
                        {
                            length++;
                        }
                    }
                    else
                    {
                        CircleListNode <BorderPoint> temp = cur.pre;
                        while (SpriteBBlockAtPos(spriteB, oriPosInB, stepX, stepY, temp.value.p))
                        {
                            temp = temp.pre;
                        }
                        cur = temp;
                        i--;
                        justStart = false;
                    }
                }
                else
                {
                    justStart = false;

                    if (find)
                    {
                        break;
                    }
                }

                cur = cur.next;
            }
            #endregion

            if (find)
            {
                cur = firstNode;

                for (int i = 0; i < Math.Round((float)length / 2); i++)
                {
                    cur = cur.next;
                }

                Point bordPointA = cur.value.p;
                result.IsCollided = true;
                Vector2 InterPos = Vector2.Transform(new Vector2(bordPointA.X, bordPointA.Y), spriteA.mTransform);
                result.NormalVector = Vector2.Transform(spriteA.mBorder.GetNormalVector(cur, spriteA.mAverageSum), spriteA.mTransform)
                                      - Vector2.Transform(Vector2.Zero, spriteA.mTransform);
                result.NormalVector.Normalize();
                result.InterPos = InterPos;
                return(result);
            }


            // No intersection found
            result.IsCollided = false;
            return(result);
        }
Пример #4
0
 public virtual void HandleOverlap( CollisionResult result, ICollideObj objA, ICollideObj objB )
 {
     if (OnOverlap != null)
         OnOverlap( result, objA, objB );
 }
Пример #5
0
 public CollisionResultGroup ( ICollideObj colA, ICollideObj colB, CollisionResult result )
 {
     this.colA = colA;
     this.colB = colB;
     this.result = result;
 }
Пример #6
0
 /// <summary>
 /// 处理重叠,空函数
 /// </summary>
 /// <param name="result"></param>
 /// <param name="objB"></param>
 public void HandleOverlap( CollisionResult result, ICollideObj objA, ICollideObj objB )
 {
 }
Пример #7
0
 /// <summary>
 /// 处理碰撞,空函数
 /// </summary>
 /// <param name="result"></param>
 /// <param name="objB"></param>
 public void HandleCollision( CollisionResult result, ICollideObj objA, ICollideObj objB )
 {
 }
Пример #8
0
        /// <summary>
        /// 检测是否在边界矩形外
        /// </summary>
        /// <param name="BorderRect"></param>
        /// <returns></returns>
        public CollisionResult CheckOutBorder ( Rectanglef BorderRect )
        {
            if (!this.mSupportIntersectDect)
                throw new Exception( "the sprite doesn't support IntersectDect!" );

            UpdateTransformBounding();

            CollisionResult result = new CollisionResult();
            Rectanglef screenRect = BorderRect;


            if (!this.mBounding.Intersects( screenRect ))
            {
                result.IsCollided = false;
                return result;
            }

            int widthA = this.mTexture.Width;
            int heightA = this.mTexture.Height;

            // Calculate a matrix which transforms from A's local space into
            // world space
            Matrix transformAToWorld = mTransform;

            Vector2 stepX = Vector2.TransformNormal( Vector2.UnitX, transformAToWorld );
            Vector2 stepY = Vector2.TransformNormal( Vector2.UnitY, transformAToWorld );

            Vector2 oriPosInWorld = Vector2.Transform( Vector2.Zero, transformAToWorld );


            CircleList<BorderPoint> list = mBorder.BorderCircle;
            CircleListNode<BorderPoint> cur = list.First;

            bool justStart = true;
            bool find = false;

            CircleListNode<BorderPoint> firstNode = cur;
            int length = 0;

            #region 找出第一个相交点和该连续相交线的长度
            for (int i = 0; i < list.Length; i++)
            {
                Point bordPointA = cur.value.p;

                if (PointOutBorder( oriPosInWorld, stepX, stepY, bordPointA, screenRect ))
                {
                    if (!justStart)
                    {
                        if (!find)
                        {
                            find = true;
                            firstNode = cur;
                        }
                        else
                        {
                            length++;
                        }
                    }
                    else
                    {
                        CircleListNode<BorderPoint> temp = cur.pre;

                        int leftLength = list.Length;
                        while (PointOutBorder( oriPosInWorld, stepX, stepY, temp.value.p, screenRect ) && leftLength >= 0)
                        {
                            temp = temp.pre;
                            leftLength--;
                        }
                        cur = temp;
                        i--;
                        justStart = false;
                    }
                }
                else
                {
                    justStart = false;

                    if (find)
                    {
                        break;
                    }
                }

                cur = cur.next;
            }
            #endregion

            if (find)
            {
                cur = firstNode;

                for (int i = 0; i < Math.Round( (float)length / 2 ); i++)
                {
                    cur = cur.next;
                }

                Point bordPointA = cur.value.p;
                result.IsCollided = true;
                Vector2 InterPos = Vector2.Transform( new Vector2( bordPointA.X, bordPointA.Y ), mTransform );
                result.NormalVector = Vector2.Transform( mBorder.GetNormalVector( cur, mAverageSum ), mTransform )
                    - Vector2.Transform( Vector2.Zero, mTransform );
                result.NormalVector.Normalize();
                result.InterPos = InterPos;
                return result;
            }


            // No intersection found
            result.IsCollided = false;
            return result;
        }
Пример #9
0
        /// <summary>
        /// Determines if there is overlap of the non-transparent pixels between two
        /// sprites.
        /// 检查两个精灵是否发生碰撞
        /// </summary>
        /// <returns>True if non-transparent pixels overlap; false otherwise</returns>
        public static CollisionResult IntersectPixels ( Sprite spriteA, Sprite spriteB )
        {
            if (!spriteA.mSupportIntersectDect || !spriteB.mSupportIntersectDect)
                throw new Exception( "At lest one of the two sprite doesn't support IntersectDect!" );

            spriteA.UpdateTransformBounding();
            spriteB.UpdateTransformBounding();

            CollisionResult result = new CollisionResult();

            if (!spriteA.mBounding.Intersects( spriteB.mBounding ))
            {
                result.IsCollided = false;
                return result;
            }

            int widthA = spriteA.mTexture.Width;
            int heightA = spriteA.mTexture.Height;
            int widthB = spriteB.mTexture.Width;
            int heightB = spriteB.mTexture.Height;

            // Calculate a matrix which transforms from A's local space into
            // world space and then into B's local space
            Matrix transformAToB = spriteA.mTransform * Matrix.Invert( spriteB.mTransform );

            // When a point moves in A's local space, it moves in B's local space with a
            // fixed direction and distance proportional to the movement in A.
            // This algorithm steps through A one pixel at a time along A's X and Y axes
            // Calculate the analogous steps in B:
            Vector2 stepX = Vector2.TransformNormal( Vector2.UnitX, transformAToB );
            Vector2 stepY = Vector2.TransformNormal( Vector2.UnitY, transformAToB );

            // Calculate the top left corner of A in B's local space
            // This variable will be reused to keep track of the start of each row
            Vector2 oriPosInB = Vector2.Transform( Vector2.Zero, transformAToB );

            CircleList<BorderPoint> list = spriteA.mBorder.BorderCircle;
            CircleListNode<BorderPoint> cur = list.First;

            bool justStart = true;
            bool find = false;

            CircleListNode<BorderPoint> firstNode = cur;
            int length = 0;

            #region 找出第一个相交点和该连续相交线的长度
            for (int i = 0; i < list.Length; i++)
            {
                Point bordPointA = cur.value.p;

                if (SpriteBBlockAtPos( spriteB, oriPosInB, stepX, stepY, bordPointA ))
                {
                    if (!justStart)
                    {
                        if (!find)
                        {
                            find = true;
                            firstNode = cur;
                        }
                        else
                        {
                            length++;
                        }
                    }
                    else
                    {
                        CircleListNode<BorderPoint> temp = cur.pre;
                        while (SpriteBBlockAtPos( spriteB, oriPosInB, stepX, stepY, temp.value.p ))
                        {
                            temp = temp.pre;
                        }
                        cur = temp;
                        i--;
                        justStart = false;
                    }
                }
                else
                {
                    justStart = false;

                    if (find)
                    {
                        break;
                    }
                }

                cur = cur.next;
            }
            #endregion

            if (find)
            {
                cur = firstNode;

                for (int i = 0; i < Math.Round( (float)length / 2 ); i++)
                {
                    cur = cur.next;
                }

                Point bordPointA = cur.value.p;
                result.IsCollided = true;
                Vector2 InterPos = Vector2.Transform( new Vector2( bordPointA.X, bordPointA.Y ), spriteA.mTransform );
                result.NormalVector = Vector2.Transform( spriteA.mBorder.GetNormalVector( cur, spriteA.mAverageSum ), spriteA.mTransform )
                    - Vector2.Transform( Vector2.Zero, spriteA.mTransform );
                result.NormalVector.Normalize();
                result.InterPos = InterPos;
                return result;
            }


            // No intersection found
            result.IsCollided = false;
            return result;
        }