我从raywnderlich跟随sample project冒险进入我的第一个cocos2d应用程序。
在该应用程序中添加移动目标,如下所示
-(void)addMonster
{
__strong CCSprite * monster = [CCSprite spriteWithFile:@"monster.png"];
CGSize winSize=[CCDirector sharedDirector].winSize;
int minY=monster.contentSize.height/2;
int maxY=winSize.height-minY;
int rangY=maxY-minY;
int actualY=(arc4random()%rangY)+minY;
monster.position=ccp(winSize.width+monster.contentSize.width, actualY);
[self addChild:monster];
monster.tag=1;
int minDuration=2.0;
int maxDuration=4.0;
int actualDuration=(arc4random()%(maxDuration-minDuration))+minDuration;
CCMoveTo *actionMove=[CCMoveTo actionWithDuration:actualDuration
position:ccp(-monster.contentSize.width/2, actualY)];
CCCallBlock *actionDone=[CCCallBlock actionWithBlock:^(CCSprite *node){
[node removeFromParentAndCleanup:YES];// crashed at this point
[_monsters removeObject:node];
}];
[monster runAction:[CCSequence actions:actionMove,actionDone,nil]];
[_monsters addObject:monster];
}
我从我的CCLayerColor子类(场景)的-init方法安排上面的方法,如下所示
-(id)init
{
// player adding code
[self schedule:@selector(gameLogic) interval:1.0];
}
-(void)gameLogic
{
[self addMonster];
}
即从ipad屏幕的左端移动到右端
我的问题是,在访问节点对象时,应用程序在CCCallBlock中崩溃了
我没有下载源代码,而是计划从起点复制步骤,但仍无法找到它的发布位置。帮助我同行
更新: - 我在崩溃时发布了截图
答案 0 :(得分:4)
问题非常简单,即您使用的块不符合预期的接口。 CCCallBlock
操作需要一个没有参数的块,但是您将块定义为接收参数(节点)。我很惊讶这甚至可以编译。当然,传入的节点将是一个垃圾指针,并在访问时崩溃。
要解决此问题,请使用CCCallBlockN
,其中CCNode*
指针作为参数:
CCCallBlockN *actionDone = [CCCallBlockN actionWithBlock:^(CCNode *node){
// ...
}];
答案 1 :(得分:0)
看起来问题是在actionDone中进行大量清理。
You add monster to self (+1),
add to array _monsters (+1),
then remove [node removeFromParentAndCleanup:YES]; (-1),
[_monsters removeObject:node]; (-1),
[self removeChild:node]; (-1)
+2, -3 —> bad access
另外(在这种特殊情况下)你尝试删除节点两次,首先删除removeFromParentAndCleanup:,然后从父removeChild:中选择一个,你不能删除两次