在SurfaceView上使用位图进行碰撞检测';Android中的画布

在SurfaceView上使用位图进行碰撞检测';Android中的画布,android,2d,collision-detection,Android,2d,Collision Detection,在Android中,我使用SurfaceView来显示一个简单的2D游戏。带有alpha(表示游戏对象)的位图(.png)绘制在画布上 现在我想做一个简单但准确的碰撞检测。检查这些位图是否重叠非常容易 但是,当这些位图具有透明区域时,如何检查冲突?我的挑战是检测两个球是否碰撞。它们在宽度和高度上都填满了整个位图,但在所有四条边上,都有透明区域,因为它是正方形中的一个圆 只有当球真正碰撞,而不是它们周围的位图框碰撞时,检测碰撞的最简单方法是什么 我必须在球的轮廓上存储尽可能多的点的坐标吗?或者An

在Android中,我使用SurfaceView来显示一个简单的2D游戏。带有alpha(表示游戏对象)的位图(.png)绘制在画布上

现在我想做一个简单但准确的碰撞检测。检查这些位图是否重叠非常容易

但是,当这些位图具有透明区域时,如何检查冲突?我的挑战是检测两个球是否碰撞。它们在宽度和高度上都填满了整个位图,但在所有四条边上,都有透明区域,因为它是正方形中的一个圆

只有当球真正碰撞,而不是它们周围的位图框碰撞时,检测碰撞的最简单方法是什么


我必须在球的轮廓上存储尽可能多的点的坐标吗?或者Android在检查碰撞时是否可以“忽略”alpha通道?

如果是球碰撞,则可以执行分析碰撞检测-比每像素检测快得多。您只需要有两个球的中心(x1,y1)和(x2,y2),第一个球的半径为r1,第二个球的半径为r2。现在,如果球中心之间的距离小于或等于半径之和,则球发生碰撞:

    colide = sqrt((x1-x2)^2+(y1-y2)^2)<=r1+r2

colide=sqrt((x1-x2)^2+(y1-y2)^2)像这样使用现有的库比重新设计轮子容易得多。不过,我不确定它是否可以与
SurfaceView一起使用。查看这篇文章:。

我能想到的另一种方法将用于可以使用s构建的简单对象

有两个边界由路径表示的对象后,可以尝试以下操作:

Path path1 = new Path();
path1.addCircle(10, 10, 4, Path.Direction.CW);
Path path2 = new Path();
path2.addCircle(15, 15, 8, Path.Direction.CW);

Region region1 = new Region();
region1.setPath(path1, clip);
Region region2 = new Region();
region2.setPath(path2, clip);

if (!region1.quickReject(region2) && region1.op(region2, Region.Op.INTERSECT)) {
    // Collision!
}

将对象作为路径后,可以使用直接绘制它们。您也可以通过移动路径来执行移动。

非常感谢!以球为例,这可能是一个完美的解决方案。我应该提到,我希望有一个更通用的解决方案(例如,每像素检测),但这是我的错。谢谢,因为我不想使用精灵,这可能是最好的方法,只使用部分代码,对吗?这是重要的部分吗?难道没有任何可能检查每像素位图的颜色吗?我可以通过这种方式检查真正的颜色(不是alpha)并确定真实对象的轮廓。谢谢,这是一个非常有趣和有用的非圆形对象解决方案!无论如何,我还没有真正弄清楚什么是
clip
。。根据我的理解,上面代码中的变量“clip”应该是路径的边界框。出于一般目的,我使用Region clip=new Region(0,0,layoutWidth,layouthweight);其中,布局宽度和高度可以是画布或活动的大小或其他任何大小。如果有人对剪辑感到困惑,请将剪辑表示为区域,例如,RectF bounds=new RectF();计算边界(边界,真);Region region1=新区域();region1.setPath(路径,新区域((int)bounds.left,(int)bounds.top,(int)bounds.right,(int)bounds.bottom));区域1.设置路径(路径,区域1)。。。请注意,
setPath
可以返回
false
,这意味着结果区域为空。在这种情况下,由于明显的原因,以下检查不起作用。
Path path1 = new Path();
path1.addCircle(10, 10, 4, Path.Direction.CW);
Path path2 = new Path();
path2.addCircle(15, 15, 8, Path.Direction.CW);

Region region1 = new Region();
region1.setPath(path1, clip);
Region region2 = new Region();
region2.setPath(path2, clip);

if (!region1.quickReject(region2) && region1.op(region2, Region.Op.INTERSECT)) {
    // Collision!
}