首先,这将是开源的,您将被提及以寻求帮助。
我们一直在用 Cocos2d 为 iPhone 编写超级马里奥重制版,供学校使用。
它看起来很棒,我们决定将其开源,因为由于版权问题我们无法获得任何利润。
我们自己编写了物理程序,但它有一些问题。
不断检查碰撞,这就是我的做法:
碰撞处理
- (void)updateCollisions:(ccTime)delta {
for (STGameObject *child in self.gameObjects) {
for (STGameObject *child2 in self.gameObjects) {
// Don't check same object
if (child == child2) {
break;
}
if (STRectIntersect(child.boundingBox, child2.boundingBox)) {
// Position objects
STRectEdge edge1 = [self updateCollisionOfGameObject:child withGameObject:child2 delta:delta];
STRectEdge edge2 = [self updateCollisionOfGameObject:child2 withGameObject:child delta:delta];
// Send notifications
[child collisionWithGameObject:child2 edge:edge1];
[child2 collisionWithGameObject:child edge:edge2];
}
}
}
}
- (STRectEdge)updateCollisionOfGameObject:(STGameObject *)gameObject
withGameObject:(STGameObject *)gameObject2
delta:(ccTime)delta {
STRectEdge rectEdge;
float edgeLeft = (gameObject.boundingBox.origin.x - gameObject2.boundingBox.origin.x - gameObject.boundingBox.size.width) * -1;
float edgeRight = (gameObject.boundingBox.origin.x + gameObject2.boundingBox.size.width - gameObject2.boundingBox.origin.x);
float edgeTop = (gameObject.boundingBox.origin.y + gameObject.boundingBox.size.height - gameObject2.boundingBox.origin.y);
float edgeBottom = (gameObject.boundingBox.origin.y - gameObject2.boundingBox.size.height - gameObject2.boundingBox.origin.y) * -1;
float offset = 0.0;
if (edgeLeft < edgeRight) {
rectEdge = STRectEdgeMinX;
offset = edgeLeft;
} else {
rectEdge = STRectEdgeMaxX;
offset = edgeRight;
}
if (edgeTop < edgeBottom) {
float cached = edgeTop;
if (cached < offset) {
rectEdge = STRectEdgeMaxY;
offset = cached;
}
} else {
float cached = edgeBottom;
if (cached < offset) {
rectEdge = STRectEdgeMinY;
offset = cached;
}
}
if (gameObject.bodyType != STGameObjectBodyTypeStatic) {
if (gameObject2.bodyType != STGameObjectBodyTypeStatic) {
offset /= 2.0;
}
if ([gameObject bodyType] != STGameObjectBodyTypeNonColliding && [gameObject2 bodyType] != STGameObjectBodyTypeNonColliding) {
switch (rectEdge) {
case STRectEdgeMinX:
{
[gameObject move:ccp(offset, 0)];
}
break;
case STRectEdgeMaxX:
{
[gameObject move:ccp(-offset, 0)];
}
break;
case STRectEdgeMinY:
{
[gameObject move:ccp(0, offset)];
}
break;
case STRectEdgeMaxY:
{
[gameObject move:ccp(0, -offset)];
}
break;
}
if (rectEdge == STRectEdgeMinY && gameObject.velocity.y < 0) {
gameObject.velocity = ccp(gameObject.velocity.x, 0);
}
if (rectEdge == STRectEdgeMaxY && gameObject.velocity.y > 0) {
gameObject.velocity = ccp(gameObject.velocity.x, 0);
}
}
}
return rectEdge;
}
它基本上检查矩形的哪个碰撞边缘最小(最容易调整)。
现在的问题如下
如您所见,如果马里奥在其底部边缘倒塌砖块,看起来就像在最小 Y 边缘发生了碰撞。然而,这种情况并非如此。这会导致不断地破坏块,即使在该边缘没有真正的碰撞,而是在最小 X 边缘。
任何想法如何解决这个问题?