2D移动的精灵碰撞

我试图创造一个游戏,我有两个abjects AB

1:我知道两个物体( Rectangles )的形状。

2:每个对象的speedposition

我试图弄清楚这两个物体最终是否会碰撞

我使用这个公式来计算物体path相交的点

在这里输入图像描述

y也一样

但是我还是不知道这两个物体究竟是碰撞还是会错过对方。

你只需要比较边线。 这些是垂直或水平线的代数表示。 请注意,这将只返回当前值,不会返回,但从这里只是一个步骤来做到这一点。

我们来定义一个具有以下属性的矩形:

Rectangle.x1 :矩形的左边线(这是一条垂直线)

Rectangle.x2 :矩形的右边线(相同)

Rectangle.y1 :矩形的顶边线(这是一条水平线)

Rectangle.y2 :矩形的底边线(相同)

这些值是矩形的属性,它们可以是任何types的数值数据(int,float,…)。 该algorithm将使用两个矩形,并比较它们的边(伪代码):

 Function rectCollision(rect1, rect2) { if (rect1.x1 > rect2.x2) //the first rectangle is after the second rectangle, they are not colliding or (rect1.x2 < rect2.x1) //the first rectangle is before the second or (rect1.y1 > rect2.y2) //the first is under the second or (rect1.y2 < rect2.y1) //the first is above the second //then { return false } else { //there is explicitly no other way for collision return true } } 

这是如何工作的? 我们在x和y轴上投射碰撞盒。 如果它们不在y轴上的x OR上碰撞,它们不会相遇。 如果它们在x轴 y轴上碰撞,那么就会发生碰撞。

你可以在http://lazyfoo.net/tutorials/SDL/27_collision_detection/index.phpfind一些关于这个的图片和附加代码(用C ++)。

Lasoloz

检查这个来源。 我基于它编写了下面的代码,使其更适合C#应用程序。 这也适用于凸多边形,这可能是有点矫枉过正,考虑到你只需要矩形,但它可以工作。

我发现更多的教程和解释为什么单独的轴定理(这使用)的作品,所以我想你会欣赏这个链接 。 此外,如果您正在寻找多边形中包含的特定点,则此链接也可能在将来派上用场。

PS我在代码中写了一些额外的评论,请花些时间过去。

 public class MainForm { // Structure that stores the results of the PolygonCollision function public struct PolygonCollisionResult { public bool WillIntersect; // Are the polygons going to intersect forward in time? public bool Intersect; // Are the polygons currently intersecting public Vector MinimumTranslationVector; // The translation to apply to polygon A to push the polygons apart } // Check if polygon A is going to collide with polygon B for the given velocity public static PolygonCollisionResult PolygonCollision(Polygon polygonA, Polygon polygonB, Vector velocity) { var result = new PolygonCollisionResult { Intersect = true, WillIntersect = true }; int edgeCountA = polygonA.Edges.Count; int edgeCountB = polygonB.Edges.Count; float minIntervalDistance = float.PositiveInfinity; Vector translationAxis = new Vector(); //default value Vector edge; // Loop through all the edges of both polygons for (int edgeIndex = 0; edgeIndex < edgeCountA + edgeCountB; edgeIndex++) { if (edgeIndex < edgeCountA) { edge = polygonA.Edges[edgeIndex]; } else { edge = polygonB.Edges[edgeIndex - edgeCountA]; } // ===== 1. Find if the polygons are currently intersecting ===== // Find the axis perpendicular to the current edge Vector axis = new Vector(-edge.Y, edge.X); axis.Normalize(); // Find the projection of the polygon on the current axis float minA = 0; float minB = 0; float maxA = 0; float maxB = 0; ProjectPolygon(axis, polygonA, ref minA, ref maxA); ProjectPolygon(axis, polygonB, ref minB, ref maxB); // Check if the polygon projections are currentlty intersecting if (IntervalDistance(minA, maxA, minB, maxB) > 0) result.Intersect = false; // ===== 2. Now find if the polygons *will* intersect ===== // Project the velocity on the current axis float velocityProjection = axis.DotProduct(velocity); // Get the projection of polygon A during the movement if (velocityProjection < 0) { minA += velocityProjection; } else { maxA += velocityProjection; } // Do the same test as above for the new projection float intervalDistance = IntervalDistance(minA, maxA, minB, maxB); if (intervalDistance > 0) result.WillIntersect = false; // If the polygons are not intersecting and won't intersect, exit the loop if (!result.Intersect && !result.WillIntersect) break; // Check if the current interval distance is the minimum one. If so store // the interval distance and the current distance. // This will be used to calculate the minimum translation vector intervalDistance = Math.Abs(intervalDistance); if (intervalDistance < minIntervalDistance) { minIntervalDistance = intervalDistance; translationAxis = axis; Vector d = polygonA.Center - polygonB.Center; if (d.DotProduct(translationAxis) < 0) translationAxis = -translationAxis; } } // The minimum translation vector can be used to push the polygons appart. // First moves the polygons by their velocity // then move polygonA by MinimumTranslationVector. if (result.WillIntersect) result.MinimumTranslationVector = translationAxis * minIntervalDistance; return result; } // Calculate the distance between [minA, maxA] and [minB, maxB] // The distance will be negative if the intervals overlap public static float IntervalDistance(float minA, float maxA, float minB, float maxB) { if (minA < minB) { return minB - maxA; } else { return minA - maxB; } } // Calculate the projection of a polygon on an axis and returns it as a [min, max] interval public static void ProjectPolygon(Vector axis, Polygon polygon, ref float min, ref float max) { // To project a point on an axis use the dot product float d = axis.DotProduct(polygon.Points[0]); min = d; max = d; for (int i = 0; i < polygon.Points.Count; i++) { d = polygon.Points[i].DotProduct(axis); if (d < min) { min = d; } else { if (d > max) { max = d; } } } } } 

如何使用:你想要做的是创建一个结构typesPolygonCollisionResult。 使用所需的参数调用PolygonCollision方法,并将结果存储在该结构中。

代码中的概念不以任何方式,形状或forms属于我。

希望这有助于你的游戏,祝你好运!