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 ); }
/// <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); }
/// <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); }
public virtual void HandleOverlap( CollisionResult result, ICollideObj objA, ICollideObj objB ) { if (OnOverlap != null) OnOverlap( result, objA, objB ); }
public CollisionResultGroup ( ICollideObj colA, ICollideObj colB, CollisionResult result ) { this.colA = colA; this.colB = colB; this.result = result; }
/// <summary> /// 处理重叠,空函数 /// </summary> /// <param name="result"></param> /// <param name="objB"></param> public void HandleOverlap( CollisionResult result, ICollideObj objA, ICollideObj objB ) { }
/// <summary> /// 处理碰撞,空函数 /// </summary> /// <param name="result"></param> /// <param name="objB"></param> public void HandleCollision( CollisionResult result, ICollideObj objA, ICollideObj objB ) { }
/// <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; }
/// <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; }