你必须自己编程,并且要注意逐像素碰撞对于 iPhone 来说可能太昂贵了。我的建议是编写一个 Collidable 协议(在所有其他编程语言中称为接口),给它一个 collidedWith:(Collidable *)c 函数,然后为您想要允许碰撞的任何对象实现它。然后您可以编写逐案碰撞逻辑。同样,您可以创建一个大型超类,其中包含碰撞所需的所有信息(在您的情况下,可以是 X、Y、宽度和高度,或者 X、Y 和像素数据数组)和一个 collidesWith 方法. 无论哪种方式,您都可以编写一堆不同的碰撞方法 - 如果您只是为一些事情进行像素碰撞,那么它不会对性能造成太大影响。但是,通常情况下,它'明显更快。
metanetsoftware 的人就碰撞技术做了一些很棒的教程,其中包括轴分离碰撞和基于网格的碰撞,后者听起来对你的游戏更可行。但是,如果您想坚持使用蛮力碰撞检测(检查每个对象与每个其他对象),那么制作一个比图像更小的边界框通常是正确的方法。这就是有多少成功的平台游戏做到了,包括超级马里奥兄弟。你也可以考虑加权边界框——也就是说,你有一个边界框用于一种类型的对象,而另一种大小则不同。例如,在马里奥中,你有一个比敌人更大的盒子可以用来击打硬币。
现在,即使我已经警告过你不要这样做,我还是会答应你并介绍如何进行基于像素的碰撞。您将要访问 CGImage 的像素数据,然后遍历所有像素以查看此图像是否与任何其他图像共享位置。这是它的一些代码。
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,否则你会检查出图像的边界.