C++ cocos2dx使用多边形精灵检测交点

C++ cocos2dx使用多边形精灵检测交点,c++,c++11,cocos2d-iphone,cocos2d-x,cocos2d-x-3.0,C++,C++11,Cocos2d Iphone,Cocos2d X,Cocos2d X 3.0,我正在使用cocos2d-x3.8。 我尝试用以下代码创建两个多边形精灵 我知道我们可以用BoundingBox检测相交,但它太粗糙了。 而且,我知道我们可以使用COCOS2D-XC++物理引擎来检测碰撞,但是它不会浪费大量的移动设备资源吗?我正在开发的游戏不需要物理引擎 有没有办法检测多边形精灵的相交? 多谢各位 auto pinfoTree = AutoPolygon::generatePolygon("Tree.png"); auto treeSprite= Sprite::create(

我正在使用cocos2d-x3.8。 我尝试用以下代码创建两个多边形精灵

我知道我们可以用BoundingBox检测相交,但它太粗糙了。 而且,我知道我们可以使用COCOS2D-XC++物理引擎来检测碰撞,但是它不会浪费大量的移动设备资源吗?我正在开发的游戏不需要物理引擎

有没有办法检测多边形精灵的相交? 多谢各位

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)

我曾经编写过一个碰撞检测算法,其中一个球将与旋转的多边形障碍物碰撞。在我的例子中,障碍物上有一定厚度的弧。以及在原点附近移动的位置。基本上它是在轨道上旋转的。球也绕着同一原点的轨道旋转。它可以在轨道之间移动。为了检查碰撞,我只需要检查球相对于原点的角度是否在弧形障碍物的下限角和上限角之间,检查球和障碍物是否在同一轨道上


换句话说,我使用了碰撞中涉及的对象的各种约束和属性来提高效率。因此,请使用对象的属性来引起碰撞。根据对象的不同,尝试使用类似的方法这有点复杂:AutoPolygon会为您提供一组三角形-PhysicsBody::createPolygon需要一个顺时针缠绕的凸多边形…因此这是两个不同的东西。顶点计数甚至可能受到限制。我认为Box2d对于一个多边形的最大计数是8

如果你想试试这个,你必须合并三角形形成多边形。一种选择是从一个三角形开始,然后添加更多三角形,只要整个三角形保持凸面。如果无法添加更多三角形,请启动一个新多边形。将所有多边形作为PhysicsShapes添加到物理实体以形成复合对象

我建议你不要走这条路,因为

  • Autopolygon针对渲染进行了优化,而不是针对最佳拟合 物理-这是一个不同。使用“自动多边形”跟踪的多边形将始终大于原始精灵-否则您将看到渲染瑕疵
  • 您几乎无法控制生成的多边形
  • 在应用程序中跟踪形状将增加启动时间
  • 三角形网格和物理轮廓是两种不同的东西
  • 我会尝试一些不同的方法:离线生成碰撞形状。这为您提供了一系列优势:

  • 您可以在可视化编辑器中生成和调整多边形,例如 使用PhysicsEditor
  • 加载多边形要快得多
  • 可以设置其他参数,如质量等
  • 该解决方案是经过战斗验证的,是开箱即用的
  • 但如果你想知道多边形相交是如何工作的。您可以查看此代码

        // 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);