首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >对于小对象,像素级碰撞检测失败。(Java)

对于小对象,像素级碰撞检测失败。(Java)
EN

Stack Overflow用户
提问于 2012-09-04 04:40:59
回答 2查看 942关注 0票数 3

对于一个项目,我们得到了一个游戏引擎,可以用来创建游戏。作为其中的一部分,我们必须在通过边界框检测方法发现可能的冲突后实现像素级冲突检测。我已经实现了这两种方法,但我的像素级别测试对于小对象(在本例中是项目符号)失败。我已经检查过它是否适用于慢弹,但也失败了。

对于我的像素级实现,我使用可用的IntBuffer ( ByteBuffer也可用?)为每个纹理创建位掩码。IntBuffer是RGBA格式的,它的大小是宽*高,我把它放在一个二维数组中,并用1替换所有非零的数字来创建掩码。在边界框发生冲突后,我找到了由重叠部分表示的矩形(使用.createIntersection),然后使用逐位和检查此交叉点内两个精灵的映射是否存在非零像素。

下面是我的像素级测试代码:

代码语言:javascript
复制
/**
 * Pixel level test
 *
 * @param rect the rectangle representing the intersection of the bounding
 * boxes
 * @param index1 the index at which the first objects texture is stored
 * @param index the index at which the second objects texture is stored
 */
public static boolean isBitCollision(Rectangle2D rect, int index1, int index2)
{
    int height = (int) rect.getHeight();
    int width = (int) rect.getWidth();

    long mask1 = 0;
    long mask2 = 0;

    for (int i = 0; i < width; i++)
    {
        for (int j = 0; j < height; j++)
        {
            mask1 = mask1 + bitmaskArr[index1].bitmask[i][j];//add up the current column of "pixels"
            mask2 = mask2 + bitmaskArr[index2].bitmask[i][j];

            if (((mask1) & (mask2)) != 0)//bitwise and, if both are nonzero there is a collsion
            {
                return true;
            }
            mask1 = 0;
            mask2 = 0;
        }

    }


    return false;
}

我已经在这个问题上挣扎了几天,任何帮助都将不胜感激。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-09-10 00:33:26

我设法解决了我自己的问题,现在它正常工作了。对于任何感兴趣的人,我所做的就是找到由两个精灵的两个边界框重叠创建的矩形。然后我把每个物体都放到原点,相对来说,就是相交的矩形。应该注意的是,我把每个对象都放到了一个“独立的”原点--也就是说,我实际上有了两个相交的矩形--每个都有一个。现在在两个对象的位掩码2D数组的边界内的每个相交矩形的坐标用于检查两个对象的重叠的正确区域:

我从下到上、从左到右循环通过位掩码作为upside中提供的图像数据-显然,这是图像数据的规范。

代码语言:javascript
复制
 /**
 * My Pixel level test - 2D
 *
 * @param rect the rectangle representing the intersection of the bounding
 * boxes
 * @param index1 the index at which the first objects texture is stored
 * @param index2 the index at which the second objects texture is stored
 * @param p1 the position of object 1
 * @param p2 the position of object 2
 * @return true if there is a collision at a pixel level false if not
 */
//public static boolean isPixelCollision(Rectangle2D rect, Point2D.Float p1, Bitmask bm1, Point2D.Float p2, Bitmask bm2)
public static boolean isPixelCollision(Rectangle2D rect, Point2D.Float p1, int index1, Point2D.Float p2, int index2)
{
    int height = (int) rect.getHeight();
    int width = (int) rect.getWidth();

    byte mask1 = 0;
    byte mask2 = 0;

    //drop both objects to the origin and drop a rectangle of intersection for each along with them
    //this allows for us to have the co-ords of the rect on intersection within them at number that are inbounds.
    Point2D.Float origP1 = new Point2D.Float((float) Math.abs(rect.getX() - p1.x), (float) Math.abs(rect.getY() - p1.y));//rect for object one
    Point2D.Float origP2 = new Point2D.Float((float) Math.abs(rect.getX() - p2.x), (float) Math.abs(rect.getY() - p2.y));//rect for object two

    //to avoid casting with every iteration
    int start1y = (int) origP1.y;
    int start1x = (int) origP1.x;
    int start2y = (int) origP2.y;
    int start2x = (int) origP2.x;

    //we need to loop within the rect of intersection
    //goind bottom up and left to right
    for (int i = height - 1; i > 0; i--)
    {
        for (int j = 0; j < width; j++)
        {
            mask1 = bitmaskArr[index1].bitmask[start1y + i][start1x + j];
            mask2 = bitmaskArr[index2].bitmask[start2y + i][start2x + j];
            if ((mask1 & mask2) > 0)
            {
                return true;
            }
        }

    }
    //no collsion was found
    return false;
}
票数 2
EN

Stack Overflow用户

发布于 2012-09-04 07:09:59

问题可能出在代码的这一部分:

代码语言:javascript
复制
if (((mask1) & (mask2)) != 0)//bitwise and, if both are nonzero there is a collsion
{
    return true;
}

您似乎正在使用逐位and来检查这两个值是否都非零-但这可能不会以这种方式工作。

例如,以下表达式的值:

代码语言:javascript
复制
3 & 4 == 0

是真的

这是因为当您执行按位操作时,您需要将数字视为其位表示,并逐位执行该操作。

所以:

代码语言:javascript
复制
  3 = 0000 0011
& 4 = 0000 0100
---------------
  0 = 0000 0000

这是因为1位值彼此对齐的方式。对于位中的位,并具有1的值-不同数字中相同位置的两位需要为1。

另一个例子是:

代码语言:javascript
复制
  3 = 0000 0011
& 2 = 0000 0010
---------------
  2 = 0000 0010

因此,在您的情况下,更好的检查方法是:

代码语言:javascript
复制
if ( mask1>0 && mask2>0 )//logical and if both are nonzero there is a collsion
{
    return true;
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12253786

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档