似乎不可能,但必须有一个解决方案。
我有以下课程:
@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;
}
}