我正在使用cocos2d-x 3.8。 我尝试使用以下代码创建两个多边形精灵。
我知道我们可以检测到与BoundingBox的交叉但是太粗糙了。 另外,我知道我们可以使用Cocos2d-x C ++物理引擎来检测碰撞,但是它不会浪费移动设备的大量资源吗?我正在开发的游戏不需要物理引擎。
有没有办法检测多边形精灵的交叉? 谢谢。
auto pinfoTree = AutoPolygon::generatePolygon("Tree.png");
auto treeSprite= Sprite::create(pinfoTree);
treeSprite-> setPosition(width / 4 * 3 - 30 , height / 2 - 200);
this->addChild(treeSprite);
auto pinfoBird = AutoPolygon::generatePolygon("Bird.png");
auto Bird= Sprite::create(pinfoTree);
Bird->setPosition(width / 4 * 3, height / 2);
this->addChild(Bird)
答案 0 :(得分:0)
我曾经不得不编写一个碰撞检测算法,其中一个球与一个旋转的多边形障碍物发生碰撞。在我的情况下,弧线具有一定厚度的障碍物。在原点附近移动的地方。基本上它是在轨道上旋转。球也围绕同一起源的轨道旋转。它可以在轨道之间移动。为了检查碰撞,我必须检查相对于原点的球角是否在弧形障碍物的下限和上限之间,并检查球和障碍物是否在同一轨道上。
换句话说,我使用碰撞中涉及的对象的各种约束和属性来提高它的效率。因此,使用对象的属性来导致碰撞。根据您的对象尝试使用类似的方法
答案 1 :(得分:-1)
这有点复杂:AutoPolygon为您提供了一堆三角形 - PhysicsBody :: createPolygon需要一个顺时针缠绕的凸多边形......所以这些是两个不同的东西。顶点数甚至可能是有限的。我认为Box2d的1个多边形的最大计数是8。
如果你想尝试这个,你必须合并三角形以形成多边形。一个选项是从一个三角形开始,只要整个东西保持凸起,就可以添加更多。如果无法再添加三角形,请启动一个新的多边形。将所有多边形作为PhysicsShapes添加到物理实体中以形成复合对象。
我建议您不要遵循此路径,因为
我会尝试一些不同的方法:离线生成碰撞形状。这为您提供了许多优势:
但是如果你想知道多边形如何交叉工作。你可以查看这段代码。
// Calculate the projection of a polygon on an axis
// and returns it as a [min, max] interval
public void ProjectPolygon(Vector axis, Polygon polygon, ref float min, ref float max) {
// To project a point on an axis use the dot product
float dotProduct = axis.DotProduct(polygon.Points[0]);
min = dotProduct;
max = dotProduct;
for (int i = 0; i < polygon.Points.Count; i++) {
flaot d = polygon.Points[i].DotProduct(axis);
if (d < min) {
min = dotProduct;
} else {
if (dotProduct> max) {
max = dotProduct;
}
}
}
}
// Calculate the distance between [minA, maxA] and [minB, maxB]
// The distance will be negative if the intervals overlap
public float IntervalDistance(float minA, float maxA, float minB, float maxB) {
if (minA < minB) {
return minB - maxA;
} else {
return minA - maxB;
}
}
// Check if polygon A is going to collide with polygon B.
public boolean PolygonCollision(Polygon polygonA, Polygon polygonB) {
boolean result = true;
int edgeCountA = polygonA.Edges.Count;
int edgeCountB = polygonB.Edges.Count;
float minIntervalDistance = float.PositiveInfinity;
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];
}
// ===== 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 = false;
return result;
}
}
该功能可以这种方式使用
boolean result = PolygonCollision(polygonA, polygonB);