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

Box2Dすでに Cocos2D を使用している場合は、衝突検出について調べてみることをお勧めします。詳細はこちら:

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

于 2013-05-17T13:41:41.850 に答える