2009-08-30 39 views
2

我正在为iPhone制作基本的平台游戏,并遇到了碰撞检测问题。iPhone SDK:碰撞检测,它必须是一个矩形?

if (CGRectIntersectsRect(player.frame, platform.frame)) 
    pos2 = CGPointMake(0.0, +0.0); 
else 
    pos2 = CGPointMake(0.0, +10.0); 

碰撞检测是停止在游戏中重力存在,当球员是在一个平台上,这个问题是与事实碰撞检测是各地玩家的矩形,反正是有做碰撞检测图像的实际形状(具有透明度),而不是围绕它的矩形?

回答

3

您必须自行编程,并且小心逐像素碰撞对于iPhone来说可能太昂贵。我的建议是编写一个Collidable协议(在所有其他编程语言中称为接口),给它一个collidedWith:(Collidable *)c函数,然后将它用于任何想要允许碰撞的对象。然后,您可以编写逐案碰撞逻辑。同样,你可以创建一个大的超类,它包含了碰撞所需要的所有信息(在你的情况下,可以是X,Y,宽度和高度,或者X,Y和像素数据数组)和collidesWith方法。无论哪种方式,您都可以编写一些不同的碰撞方法 - 如果您只是在几个方面进行像素碰撞,那么性能不会受到太大影响。通常情况下,最好是根据几何图形进行包围盒碰撞或其他碰撞,因为它的速度明显快于

在metanetsoftware的人们在碰撞技术上做了一些很棒的教程,其中包括axis separation collsiongrid based collision,后者听起来像是对你的游戏更加可行。然而,如果你想坚持使用强力碰撞检测(检查每个对象与其他物体),那么制作一个简单的的边界框比图像通常是正确的路径。这就是有多少成功的平台玩家,包括超级马里奥兄弟。你也可以考虑加权边界框 - 也就是说,你有一个边界框用于一种类型的对象,另一种边界框用于其他类型的边界框。例如在马里奥,你有一个比你做敌人更大的箱子来打钱。

现在,尽管我已经警告过你不要这样做,但我会责备你并且投入如何进行基于像素的碰撞。您将要CGImage的access the pixel data,然后迭代所有像素以查看此图像是否与任何其他图像共享一个位置。这里有一些代码。

for (int i = 0; i < [objects count]; i++) 
{ 
    MyObject *obj1 = [objects objectAtIndex:i]; 

    //Compare every object against every other object. 
    for (int j = i+1; j < [objects count]; j++) 
    { 
     MyObject *obj2 = [objects objectAtIndex:j]; 

     //Store whether or not we've collided. 
     BOOL collided = NO; 

     //First, do bounding box collision. We don't want to bother checking 
     //Pixels unless we are within each others' bounds. 
     if (obj1.x + obj1.imageWidth >= obj2.x && 
      obj2.x + obj2.imageWidth >= obj1.x && 
      obj1.y + obj1.imageHeight >= obj2.y && 
      obj2.y + obj2.imageGeight >= obj1.y) 
     { 
      //We want to iterate only along the object with the smallest image. 
      //This way, the collision checking will take the least time possible. 
      MyObject *check = (obj1.imageWidth * obj1.imageHeight < obj2.imageWidth * obj2.imageHeight) ? obj1 : obj2; 

      //Go through the pixel data of the two objects. 
      for (int x = check.x; x < check.x + check.imageWidth && !collided; x++) 
      { 
       for (int y = check.y; y < check.y + check.imageHeight && !collided; y++) 
       { 
        if ([obj1 pixelIsOpaqueAtX:x andY:y] && [obj2 pixelIsOpaqueAtX:x andY:y]) 
        { 
         collided = YES; 
        } 
       } 
      } 
     } 
    } 
} 

我说得那么pixelIsOpaque需要全局坐标,而不是一个局部坐标,所以当你编程的那部分,你必须要小心,再减去x和y出这一点,否则你会被检查超出你的形象的界限。