2013-10-14 99 views
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和激光光束精灵(激光光束是EnemiesEntities类的成员变量和子)之间的碰撞。 [laserBeam boundingBox]方法不起作用,因为boundingBox会将坐标相对于父节点转换为坐标系

我试图thend增加CCNode的方法boundingBox的相对于世界计算也是这样一个没有工作:

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

我在网上查,发现只有无用的(对我来说)答案,same问题。

然后我尝试了不同的方法,并试图从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; 
    } 
} 

不幸的是这样做才有效,当父Sprite的旋转设置为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; 
    } 
    } 

回答

0

的问题是在这条线,我认为:

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

的激光光束是不是在激光光束的空间,但laserBeams父空间。因此,正确的是:

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

整个代码

- (BOOL)collidesWithLaser:(CCSprite *)激光光束 { CGPoint在newPosition = [激光光束convertToWorldSpace:laserBeam.position]; CGRect laserBoundingBox = [laserBeam boundingBox]; laserBoundingBox.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; 
} 

}

0

两个boundingboxes做:

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

现在你可以比较rects ...

更新来更新:

boundingBox的是轴对齐包围盒。

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

ccConfig.h有可以打开绘制精灵包围盒,你应该将其设置为1,看边界框的选项:#define CC_SPRITE_DEBUG_DRAW 1

对于面向矩形,你需要不同的数据结构和不同的相交测试,例如参见this tutorial

+0

嗨Steffen,谢谢,但不幸的是它不工作。激光束似乎没有旋转信息(就像它在类中它将旋转值保持为0,即使父类具有不同的旋转值(例如-135.0f))。我将用我试过的代码添加一个编辑。 – mm24