2011-06-01 14 views
2

我正在为我的游戏使用与花栗鼠物理学的空间管理器。 我想要做的是将一个球打到一个支柱上,并让球消失。我正在不同的位置重新创建球,以便用户可以击中另一个支柱。我有球形和球形精灵作为成员变量。程序崩溃时,删除空间管理器中的形状 - cocos2d

以下是创建球,圆柱形状等

ball = [smgr addCircleAt:cpv(1000,10) mass:0.5 radius:35]; 
ball->collision_type = kBallCollisionType; 

ballSprite = [cpCCSprite spriteWithShape:ball file:@"head.png"]; 
//[ballSprite autoFreeShape]; 
[self addChild:ballSprite]; 
ballSprite.spaceManager = smgr; 
//ballSprite.ignoreRotation = NO; 

cpShape *dome = [smgr addRectAt:cpv(400,500) mass:1 width:400 height:100 rotation:0]; 
dome->collision_type = kRectCollisionType; 
cpCCSprite *dome1 = [cpCCSprite spriteWithShape:dome file:@"001.png"]; 
[self addChild:dome1]; 
dome1.spaceManager = smgr; 

cpShape *pillarone = [smgr addRectAt:cpv(300,300) mass:1 width:45 height:194 rotation:0]; 
pillarone->collision_type = kRectCollisionType; 
cpCCSprite *pillar1 = [cpCCSprite spriteWithShape:pillarone file:@"004.png"]; 
[self addChild:pillar1]; 

pillar1.spaceManager = smgr; 

cpShape *pillartwo = [smgr addRectAt:cpv(500,300) mass:1 width:45 height:194 rotation:0]; 
pillartwo->collision_type = kRectCollisionType; 
cpCCSprite *pillar2 = [cpCCSprite spriteWithShape:pillartwo file:@"004.png"]; 
[self addChild:pillar2]; 

pillar2.spaceManager = smgr; 


cpShape *staticground = [smgr addRectAt:cpv(510,25) mass:1 width:0 height:0 rotation:0]; 
cpCCSprite *staticground1 = [cpCCSprite spriteWithShape:staticground file:@"grass1-1024.png"]; 
[self addChild:staticground1 z:1 tag:0]; 


[smgr addCollisionCallbackBetweenType:kRectCollisionType 
          otherType:kBallCollisionType 
           target:self 
          selector:@selector(handleCollisionWithFragmentingRect:arbiter:space:)]; 

代码,这里是用于冲突解决的代码。

- (void) handleCollisionWithFragmentingRect:(CollisionMoment)moment arbiter:(cpArbiter*)arb space:(cpSpace*)space{ 
if (moment == COLLISION_POSTSOLVE) 
{ 
    [self removeChild:ball->data cleanup:YES]; 
    [smgr removeAndFreeShape:ball]; 

    ball = [smgr addCircleAt:cpv(1000,10) mass:0.5 radius:35]; 
    ball->collision_type = kBallCollisionType; 
    ballSprite = [cpCCSprite spriteWithShape:ball file:@"head.png"]; 
    [self addChild:ballSprite]; 
    ballSprite.spaceManager = smgr; 
} 

}

当第一球击中消失罚款支柱。但是对于第二次,有时候我会选择第三个球,并撞到它撞上的柱子,错误如下。

Chipmunk warning: Cannot remove a constraint that was not added to the space. (Removed twice maybe?) 
Failed condition: cpArrayContains(space->constraints, constraint) 

我不确定我哪里出了问题,请谁能帮忙。

谢谢。

回答

0

我认为你需要添加teh球以将其移除到“垃圾”数组,而不是在handleCollisionWithFragmentingRect函数中删除它。对于所有的安全措施,包括

- (void) update : (ccTime) dt 
{ 
    for (cpShape *shape in _garbage) 
    { 
     // Remove shape 
     [self removeChild:shape->data cleanup:YES]; 
     [smgr removeAndFreeShape:shape]; 

     // Add new ball 
     ball = [smgr addCircleAt:cpv(1000,10) mass:0.5 radius:35]; 
     ball->collision_type = kBallCollisionType; 
     ballSprite = [cpCCSprite spriteWithShape:ball file:@"head.png"]; 
     [self addChild:ballSprite]; 
     ballSprite.spaceManager = smgr; 
    } 
    ... 

} 

然后你会改变手柄功能,这一点:

- (void) handleCollisionWithFragmentingRect:(CollisionMoment)moment arbiter:(cpArbiter*)arb space:(cpSpace*)space 
{ 
    if (moment == COLLISION_POSTSOLVE) 
    { 
     // SHOULDNT BE A DIRECT REFERENCE TO MEMBER VARIABLE BALL. 
     // SHOULD BE ADDED FROM INFORMATION WITHIN THE PARAMETERS OF THIS FUNCTION. 
     _garbage.addObject(ball); 
    } 
}