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 sprite 之间的碰撞(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

我认为问题出在这一行:

 CGPoint newPosition = [laserBeam convertToWorldSpace:laserBeam.position];

LaserBeam 不在laserBeam 的空间中,而是在laserBeams 的父空间中。所以正确的是:

 CGPoint newPosition = [[laserBeam parent] convertToWorldSpace:laserBeam.position];

整个代码

-(BOOL) collidesWithLaser:(CCSprite*)laserBeam { CGPoint newPosition = [laserBeam convertToWorldSpace:laserBeam.position]; CGRect 激光边界框 = [激光束边界框];激光边界框.origin = newPosition;

CGRect hitBox = [self boundingBox];
hitbox.origin = [[self parent] convertToWorldSpace:hitbox.origin];

if(CGRectIntersectsRect(hitbox, laserBoundingBox))
{
    laserBeam.showCollisionBox=TRUE;
    return TRUE;
}
else {
    return FALSE;
}

}

于 2013-10-15T09:03:41.770 回答
0

对于两个边界框都做:

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

现在你可以比较矩形...

更新更新:

boundingBox 是一个轴对齐的边界框。

如果实体旋转,边界框大小会增加以包含精灵的所有角。因此,在测试轴对齐的边界框时,甚至可以在距离节点相对较远的地方检测到碰撞(相交)。

ccConfig.h中,您可以打开一个选项来绘制精灵边界框,您应该将其设置为 1 以查看边界框:#define CC_SPRITE_DEBUG_DRAW 1

对于定向矩形,您需要不同的数据结构和不同的交集测试,例如,请参见本教程

于 2013-10-15T10:38:25.810 回答