0

不可能に思えますが、解決策が必要です。

次のクラスがあります。

@interface EnemiesEntities : CCSprite {
    bool isFunctional;
    CCSprite * laserBeam;   // <----------- !!!!! That's where I want to check the collision.
    CCSprite * leftRingEffect;
    CCSprite * rightRingEffect;
}

@interface ShipEntity : CCSprite
{}

そして、ShipEntity と laserBeam スプライト(laserBeam はメンバー変数であり、EnemiesEntities クラスの子) の間の衝突を確認したいだけです。メソッド [laserBeam boundingBox] は、 boundingBox が親ノードに対する座標を変換するため機能しません。

CCNode に、世界に対する境界ボックスを計算するメソッドを追加しようとしましたが、これも機能しませんでした。

- (CGRect) worldBoundingBox
{
    CGRect rect = CGRectMake(0, 0, contentSize_.width, contentSize_.height);
    return CGRectApplyAffineTransform(rect, [self nodeToWorldTransform]);
}

オンラインで調べたところ、同じ質問に対する(私にとって)役に立たない回答しか見つかりませんでした。

次に、別のアプローチを試し、boudningBox から開始して、次のように親の位置に対して取得した四角形の位置を変更しようとしました。

-(BOOL) collidesWithLaser:(CCSprite*)laserBeam
{
    CGPoint newPosition = [laserBeam convertToWorldSpace:laserBeam.position];

    [laserBeam worldBoundingBox];

    CGRect laserBoundingBox = [laserBeam boundingBox];

    CGRect laserBox = CGRectMake(laserBeam.parent.position.x, laserBeam.parent.position.y, laserBoundingBox.size.width, laserBoundingBox.size.height);
    CGRect hitBox = [self hitBox];

    if(CGRectIntersectsRect([self boundingBox], laserBox))
    {
        laserBeam.showCollisionBox=TRUE;
        return TRUE;
    }
    else {
        return FALSE;
    }
}

残念ながら、これは親スプライトの回転が 0.0 に設定されている場合にのみ機能しますが、実際に変更された場合は機能しません(おそらく、boundingBox がワールドではなく親ノードに対して相対的であるためです)。

私は少し迷っており、この問題を解決するのに幸運があったかどうか、またどの解決策 (コード スニペットをお願いします :)) を使用したか疑問に思っていました。

@LearnCocos2Dの回答に応じて編集:

私は提案に従い、正しく動作しない次のコードを追加しました (たとえば、EnemiesEntities オブジェクトを -130.0f にローテーションしてみてください)。

-(BOOL) collidesWithLaser:(CCSprite*)laserBeam
{
    CCLOG(@"rotation %f", laserBeam.rotation);

    CGRect laserBoundingBox = [laserBeam boundingBox];
    laserBoundingBox.origin = [self convertToWorldSpace:laserBeam.position];

    CGRect shipBoundingBox = [self boundingBox]; //As we are in ShipEntity class
    shipBoundingBox.origin = [self convertToWorldSpace:shipBoundingBox.origin];

    //As this method is in the ShipEntity class there is no need to convert the origin to the world space. I added a breakpoint here and doing in this way the CGRect of both ShipEntity and gets misplaced.   


    if(CGRectIntersectsRect(shipBoundingBox, laserBoundingBox))
    {
        return TRUE;
    }
    else {
        return FALSE;
    }
    }
4

2 に答える 2

0

両方の境界ボックスに対して次のことを行います。

bbox.origin = [self convertToWorldSpace:bbox.origin];

これで、四角形を比較できます...

更新する更新:

boundingBox は、軸に沿ったバウンディング ボックスです。

エンティティが回転すると、バウンディング ボックスのサイズが大きくなり、スプライトのすべてのコーナーが取り囲まれます。したがって、軸に沿ったバウンディング ボックスをテストすると、ノードから比較的離れた場所でも衝突 (交差) が検出される場合があります。

ccConfig.hには、スプライトのバウンディング ボックスを描画するためにオンにできるオプションがあります。バウンディング ボックスを表示するには、これを 1 に設定する必要があります。#define CC_SPRITE_DEBUG_DRAW 1

方向付けられた長方形の場合、別のデータ構造と別の交差テストが必要です。たとえば、このチュートリアルを参照してください。

于 2013-10-15T10:38:25.810 に答える