2011-09-02 84 views
12


这是我在这里的第一篇文章,因此对任何错误表示歉意。
我正在开发一个简单的动作游戏,使用OpenGL ES 2.0和Android 2.3。我目前正在研究的游戏框架是基于三维世界中存在的二维精灵。当然,我的世界实体拥有虚构世界中的位置,float []矩阵形式的旋转值,OpenGL纹理句柄以及Android的位图句柄等信息(我不确定后者是否有必要,因为我正在做使用OpenGl机器进行光栅化,但暂时只是在那里,为了我的方便)。这是简要的背景,现在是有问题的问题。
目前我坚持基于像素的碰撞检测,因为我不知道我需要采样哪个对象(这里是OGL纹理或Android位图)。我的意思是,我已经试图对Android的Bitmap进行示例,但它完全不适用于我 - 许多运行时崩溃与读取位图之外的内容有关。当然,为了能够从位图读取像素,我已经使用 Bitmap.create方法来获得正确旋转的精灵。下面的代码片段:
Android下基于像素的OpenGLES 2.0碰撞检测问题

android.graphics.Matrix m = new android.graphics.Matrix(); 
if(o1.angle != 0.0f) {   
    m.setRotate(o1.angle); 
    b1 = Bitmap.createBitmap(b1, 0, 0, b1.getWidth(), b1.getHeight(), m, false); 
} 

另一个问题,这可能会增加的问题,甚至是主要的问题,是我的路口的矩形(长方形表示二维空间中相互两个对象)是建立来自使用OpenGL矩阵计算的两个边界框的部分,其功能(以下代码)为Matrix.multiplyMV。难道那两个Android和OpenGL矩阵的计算方法是不相等的吗?

Matrix.rotateM(mtxRotate, 0, -angle, 0, 0, 1); 

// original bitmap size, equal to sprite size in it's model space, 
// as well as in world's space 
float[] rect = new float[] { 
    origRect.left, origRect.top, 0.0f, 1.0f, 
    origRect.right, origRect.top, 0.0f, 1.0f, 
    origRect.left, origRect.bottom, 0.0f, 1.0f, 
    origRect.right, origRect.bottom, 0.0f, 1.0f 
}; 

android.opengl.Matrix.multiplyMV(rect, 0, mtxRotate, 0, rect, 0); 
android.opengl.Matrix.multiplyMV(rect, 4, mtxRotate, 0, rect, 4); 
android.opengl.Matrix.multiplyMV(rect, 8, mtxRotate, 0, rect, 8); 
android.opengl.Matrix.multiplyMV(rect, 12, mtxRotate, 0, rect, 12); 

// computation of object's bounding box (it is necessary as object has been 
// rotated second ago and now it's bounding rectangle doesn't match it's host 
float left = rect[0]; 
float top = rect[1]; 
float right = rect[0]; 
float bottom = rect[1]; 
for(int i = 4; i < 16; i += 4) { 
    left = Math.min(left, rect[i]); 
    top = Math.max(top, rect[i+1]); 
    right = Math.max(right, rect[i]); 
    bottom = Math.min(bottom, rect[i+1]); 
}; 
+0

一般来说,OpenGL *仅用于图形。您不应该让它触及您的游戏/世界坐标,除非将其转换后的*副本*呈现给屏幕。这意味着你拥有的边界框应该使用你自己的代码进行计算。并且注意基于像素的物理系统:)这听起来像是一个好主意,直​​到你尝试它,并发现它不是物理交互的物品是一个好主意(任何物品在你触摸时会消失,就像子弹或物品接起来,或者如果你在触摸时立即死亡)。 –

+0

谢谢你的回答。我想要达到的结果是比基于圆圈和框的更好的碰撞。这可能是像素碰撞不够好,因为它们在计算上是昂贵的。 Sill最近读了一些叫做“凸形”的东西,我可能会使用它们来增加我的碰撞系统的行为 – cplusogl

+1

关于每个像素的警告主要是因为我玩过它,实现了一个旧的躲避功能学校风格的平台游戏,并发现它感觉不对。使用正确的技术可以大大减少计算复杂性(最初仅进行AABB冲突,可能通过空间分区信息(如网格系统或动态四叉树)进行减少,然后使用特殊的仅黑白冲突蒙版,然后仅测试交叠)。凸形的形状绝对是一种很好的方式,并且可以让你在只有2D的交互中用3D艺术代替游戏。 –

回答

0

干杯,

首先要注意有代码中的错误。您不能使用Matrix.multiplyMV()与源矢量和目标矢量相同(该函数将正确计算将在源矢量中覆盖的x坐标,但它需要原始x来计算y,z和w坐标 - 这又是有缺陷的)。还要注意,在第一次检测碰撞步骤中使用边界球会更容易,因为它们不需要这样复杂的代码来执行矩阵变换。

然后,碰撞检测。你不应该从位图或纹理读取。你应该做的是为你的对象建立一个轮廓(这很简单,轮廓只是一个位置列表)。之后,您需要构建填充(非凸)轮廓的凸形对象。它可以通过例如。耳廓修剪算法。它可能不是最快的,但它很容易实现,而且只会执行一次。一旦你有凸对象,你可以使用矩阵来转换它们的坐标并检测与你的世界的碰撞(你可以使用光线三角形交叉点上有很多好的文章),并且你可以获得与使用像素相同的精度基于碰撞检测。

我希望它可以帮助...

+0

哦,我必须检查我的其他multiplyMV电话,谢谢指出。尽管如此,有趣的是,应用程序的行为从来没有出现任何故障,因为multiplyMV的使用不当...... 至于凸形状,我必须深入研究这个主题。非常感谢! – cplusogl