您必須自行編程,並且小心逐像素碰撞對於iPhone來說可能太昂貴。我的建議是編寫一個Collidable協議(在所有其他編程語言中稱爲接口),給它一個collidedWith:(Collidable *)c函數,然後將它用於任何想要允許碰撞的對象。然後,您可以編寫逐案碰撞邏輯。同樣,你可以創建一個大的超類,它包含了碰撞所需要的所有信息(在你的情況下,可以是X,Y,寬度和高度,或者X,Y和像素數據數組)和collidesWith方法。無論哪種方式,您都可以編寫一些不同的碰撞方法 - 如果您只是在幾個方面進行像素碰撞,那麼性能不會受到太大影響。通常情況下,最好是根據幾何圖形進行包圍盒碰撞或其他碰撞,因爲它的速度明顯快於。
在metanetsoftware的人們在碰撞技術上做了一些很棒的教程,其中包括axis separation collsion和grid 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出這一點,否則你會被檢查超出你的形象的界限。
來源
2009-08-31 18:09:46
Eli