2009-08-30 53 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出這一點,否則你會被檢查超出你的形象的界限。