0

首先,这将是开源的,您将被提及以寻求帮助。


我们一直在用 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 边缘。

任何想法如何解决这个问题?

4

1 回答 1

0

如果你已经在使用 Cocos2D,我建议你看一下Box2D碰撞检测。更多信息在这里:

http://www.raywenderlich.com/606/how-to-use-box2d-for-just-collision-detection-with-cocos2d-iphone

于 2013-05-17T13:41:41.850 回答