Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/383.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 像素级的圆与精灵的快速碰撞检测_Java_Android_Geometry_Collision Detection - Fatal编程技术网

Java 像素级的圆与精灵的快速碰撞检测

Java 像素级的圆与精灵的快速碰撞检测,java,android,geometry,collision-detection,Java,Android,Geometry,Collision Detection,我一直在考虑一些快速和辉煌的像素完美的碰撞检测之间的一个圆圈和任何精灵。我需要得到两个碰撞点,以便以后能够从中计算出法向量。我设法想出了一些解决方案,但在我的游戏中进行的缩放越多,冲突就越不准确和不精确…似乎我在下面发布的代码是好的和正确的,因为我已经检查了几次,并且花了几天时间反复阅读它。。。我还目视检查了碰撞遮罩和碰撞区域是否在下面的代码中计算得非常好,因此问题肯定不在那里,而是在这个方法中 所以我猜这里的问题是浮点运算中的数据丢失,除非有人发现这个方法有缺陷 然而,如果问题真的是数据的浮点

我一直在考虑一些快速和辉煌的像素完美的碰撞检测之间的一个圆圈和任何精灵。我需要得到两个碰撞点,以便以后能够从中计算出法向量。我设法想出了一些解决方案,但在我的游戏中进行的缩放越多,冲突就越不准确和不精确…似乎我在下面发布的代码是好的和正确的,因为我已经检查了几次,并且花了几天时间反复阅读它。。。我还目视检查了碰撞遮罩和碰撞区域是否在下面的代码中计算得非常好,因此问题肯定不在那里,而是在这个方法中

所以我猜这里的问题是浮点运算中的数据丢失,除非有人发现这个方法有缺陷

然而,如果问题真的是数据的浮点丢失,您会推荐什么其他解决方案来在“完美像素”中找到圆圈和任何其他精灵之间的2个碰撞点?我真的很喜欢我的解决方案,因为它比较快

int xOffset1 = (int)colRectLeft;  // left boundary of the collision area for the first sprite
int xOffset2 = (int)colCircleLeft; // left boundary of the collision area for the circle sprite
int yOffset1 = (int)colRectBottom; // bottom boundary of the collision area for the first sprite
int yOffset2 = (int)colCircleBottom; // bottom boundary of the collision area for the circle sprite
int width = (int)(colCircleRight - colCircleLeft); //width of the collision area - same for both sprites
int height = (int)(colCircleTop - colCircleBottom); // height of the collision area same for both sprites

// Pixel-perfect COLLISION DETECTION between circle and a sprite
// my custom vector classes - nothing special
Math2D.Vector_2 colRightPoint = new Math2D.Vector_2(-1, -1); // The right point of collision lying on the circle's circumference
Math2D.Vector_2 colLeftPoint = new Math2D.Vector_2(-1, -1); // the left point of collision lying on the circle's circumference
boolean colRightFound = false;
boolean colLeftFound = false;

// I'm going through y in the circle's area of collision
for (float y = yOffset2; y < yOffset2 + height; y += 1)
{
    // from equation: (x-Sx)^2 + (y-Sy)^2 = r^2
    // x1/2 = (+-)sqrt(r^2 - (y - Sy)^2) + Sx
    //(Sx, Sy) is (circle's radius, circle's radius) becouse I want the points on the circle's circumference to have positive coordinates
    float x1 =  (float) (Math.sqrt(radius*radius - (y - radius)*(y - radius)) + radius); // the right pixel on the circumference
    float x2 =  (float) (-x1 + 2*radius); // the left pixel on the circumference

    //first I check if the calculated x is inside of the previously calculated area of collision for both circle's area and a sprite's area
    if (x1 >= xOffset2 &&
        x1 <= xOffset2 + width &&
        xOffset1 + x1 - xOffset2 < rectFrameW &&
        yOffset1 + (int)y-yOffset2 < rectFrameH &&
        yOffset1 + (int)y-yOffset2 > 0 &&
        xOffset1 + x1 - xOffset2 > 0)
    {
        //I don't have to check if the point on the circle's circumference is opaque becouse it's always so just check if the same point translated to sprite's area of collision is opaque
        boolean opaqueRectPixel = go.gameData.images.get(go.pic_nr)
            .collision_mask[(int)((yOffset1 + (int)y-yOffset2)*rectFrameW +
                                  (xOffset1 + x1 - xOffset2))];

        if(opaqueRectPixel)
        {
            if(!colRightFound)
            {
                colRightPoint.x = (xOffset1 + x1 - xOffset2);
                colRightPoint.y = (yOffset1 + (int)y - yOffset2);
                colRightFound = true;
            }
            else if(!colLeftFound)
            {
                colLeftPoint.x = (xOffset1 + x1 - xOffset2);
                colLeftPoint.y = (yOffset1 + (int)y - yOffset2);
            }
        }
    }

    //the same logic for the left point on the circle's circumference
    if (x2 >= xOffset2 &&
        x2 <= xOffset2 + width &&
        xOffset1 + x2 - xOffset2 < rectFrameW &&
        yOffset1 + (int)y-yOffset2 < rectFrameH &&
        yOffset1 + (int)y-yOffset2 > 0 &&
        xOffset1 + x2 - xOffset2 > 0)
    {
        boolean opaqueRectPixel = go.gameData.images.get(go.pic_nr)
            .collision_mask[(int)((yOffset1 + (int)y-yOffset2)*rectFrameW +
                                  (xOffset1 + x2 - xOffset2))];

        if(opaqueRectPixel)
        {
            if(!colLeftFound)
            {
                colLeftPoint.x = (xOffset1 + x2 - xOffset2);
                colLeftPoint.y = (yOffset1 + (int)y - yOffset2);
                colLeftFound = true;
            }
            else if(!colRightFound)
            {
                colRightPoint.x = (xOffset1 + x2 - xOffset2);
                colRightPoint.y = (yOffset1 + (int)y - yOffset2);
            }
        }
    }

    // if both points are already found, finish
    if(colLeftFound && colRightFound)
        break;
}
int-xOffset1=(int)colrectlft;//第一个精灵碰撞区域的左边界
int xOffset2=(int)colcircleleleft;//圆形精灵碰撞区域的左边界
int yOffset1=(int)colRectBottom;//第一个精灵碰撞区域的底部边界
int yOffset2=(int)colCircleBottom;//圆形精灵碰撞区域的底部边界
int-width=(int)(colCircleRight-colcircleleleft)//碰撞区域的宽度-两个精灵的宽度相同
int高度=(int)(colCircleTop-colCircleBottom);//两个精灵的碰撞区域高度相同
//圆和精灵之间的像素完美碰撞检测
//我的自定义向量类-没有什么特别的
Math2D.Vector_2 colRightPoint=新的Math2D.Vector_2(-1,-1);//位于圆圆周上的正确碰撞点
Math2D.Vector_2 colLeftPoint=新的Math2D.Vector_2(-1,-1);//位于圆圆周上的左侧碰撞点
布尔值colRightFound=false;
布尔colLeftFound=false;
//我在圆的碰撞区域通过y
对于(浮动y=yOffset2;y=xOffset2&&
x10&&
xOffset1+x1-xOffset2>0)
{
//我不必检查圆周上的点是否不透明,因为它总是不透明的,所以只需检查转换到sprite碰撞区域的同一点是否不透明即可
布尔运算opaQueectPixel=go.gameData.images.get(go.pic\u nr)
.collision_mask[(int)((yOffset1+(int)y-yOffset2)*rectFrameW+
(xOffset1+x1-xOffset2));
if(不透明像素)
{
如果(!colRightFound)
{
colRightPoint.x=(xOffset1+x1-xOffset2);
colRightPoint.y=(yOffset1+(int)y-yOffset2);
colRightFound=true;
}
否则,如果(!colLeftFound)
{
colLeftPoint.x=(xOffset1+x1-xOffset2);
colLeftPoint.y=(yOffset1+(int)y-yOffset2);
}
}
}
//同样的逻辑也适用于圆圆周上的左侧点
如果(x2>=xOffset2&&
x20&&
xOffset1+x2-xOffset2>0)
{
布尔运算opaQueectPixel=go.gameData.images.get(go.pic\u nr)
.collision_mask[(int)((yOffset1+(int)y-yOffset2)*rectFrameW+
(xOffset1+x2-xOffset2));
if(不透明像素)
{
如果(!colLeftFound)
{
colLeftPoint.x=(xOffset1+x2-xOffset2);
colLeftPoint.y=(yOffset1+(int)y-yOffset2);
colLeftFound=true;
}
如果(!colRightFound),则为else
{
colRightPoint.x=(xOffset1+x2-xOffset2);
colRightPoint.y=(yOffset1+(int)y-yOffset2);
}
}
}
//如果两个点都已找到,则完成
如果(colLeftFound&&colRightFound)
打破
}
编辑:实际上,我在这个方法中所做的是找到圆和精灵之间的交点

编辑:好的,我上传图片来更好地描述我的算法。我真的尽力解释了,但如果还有什么遗漏,请告诉我

此外,如果您不想查看我的代码,我也会接受任何其他好的解决方案,以在像素完美中找到圆和任何精灵之间的交点:(…呃,我总是遇到碰撞问题…

如果您绝对想要(或需要)像素完美,您的解决方案看起来不错。 在测试像素完美检测之前,不要忘记先进行矩形到矩形的碰撞,以避免不必要的处理

如果你想得到另一种可能更有效的精确方法,请寻找分离轴定理

您可以在此处找到有关它的更多信息:

在这里:


最后一个有很好的交互式解释和演示。请欣赏:)

…因为我无法在评论中显示光栅:



我没有在心里解析您的代码,但是从图像中我看到您试图检测边界冲突。使圆或圆