我正处于iPhone游戏的初始构建阶段,我正在使用精灵表来创建一些随机的人,每个人都有头发,衣服等子精灵。
我正在使用CCSpriteBatchNode将精灵图像存储在spritesheets中。我现在正在进行初始设置测试,点击屏幕以生成一组新的随机人员。所以奇怪的是,你可以点击一次,它将删除旧人并用新人替换它们,但第二次,它崩溃了错误: “CCSpriteBatchNode不包含精灵。无法删除它” 现在我确定我已经将精灵添加到批处理节点,在我的Person.m构造函数中我有这一行:
[spriteSheet addChild:person];
在我的ccTouchesEnded测试代码中,我得到了以下代码:
//updated with changes suggested by Mazyod and Jer
for(int i=6; i>=0; i--){
Person *per = [_people objectAtIndex:i];
[_people fastRemoveObjectAtIndex:i];
[_spritesheet removeChild:per cleanup:YES];
per = nil;
}
for(int i = 0; i < 7; i++){
Person *per = nil;
per = [Citizen personFromCountry:_country1 WithSpriteSheet:_spritesheet];
per.position = ccp(100 + (50 * i),160);
[_people addObject:per];
[_spritesheet addChild:per];
}
有人能说出我错过的东西吗?我已经在cocos2d中阅读了一些关于spritesheets的内容,并且我理解删除单个精灵是非常棘手的,所以我确定我需要在这里添加一些重要的行。谢谢你的帮助!
编辑:我搜索了错误并找到了这个帖子:http://www.cocos2d-iphone.org/forum/topic/17170这似乎证实Cocos2d认为我没有将精灵添加到spritesheet中 - 但我证明了事实上,精灵第一次正确添加,而不是第二次。
一种解决方案是简单地避免删除精灵,只是让它们不可见,并在需要重复使用时重新绘制它们。我宁愿知道真正的解决方案是什么,因为它似乎更清洁。
答案 0 :(得分:1)
好吧,我现在可以帮你清除一件事:
任何CCNode只能是一个父母的孩子。即它必须有一个单亲。
但是,你在这里有什么:
for(int i=0; i<7; i++){
Person *per = [_people objectAtIndex:i];
[self removeChild:per cleanup:YES];
[_spritesheet removeChild:per cleanup:YES];
per = nil;
}
建议您尝试同时将此人添加到spriteSheet和self中。检查您的日志,它必须具有以下内容:
cocos2d:removeChild,找不到孩子。
从你得到的错误中,我打赌这个人被添加到自己而不是精灵表。
好吧,你必须将这个人作为孩子添加到spriteSheet,然后将spriteSheet作为孩子添加到self。 (实际上,你添加它们的顺序并不重要)。
排除这个问题,也许这个问题会消失,或者至少会更清楚,所以我们可以帮助你。
答案 1 :(得分:1)
看起来你需要改变
[_people addObject:per];
到
[_people replaceObjectAtIndex:i withObject:per];
在第一个循环中,您只是将数组中对象的值设置为nil,而不是将其从数组中删除。在第二个循环中,您只需将其添加到数组的末尾,但您的数组中已经有7个nils。
让我知道它是否有效。
答案 2 :(得分:1)
我只想提一下我在这里遇到这个问题的经验以及我是如何解决它的。
请记住,您要么想要删除一个从未添加过的孩子......
OR
尝试删除子TWICE。
对我来说就是这种情况。我游戏中的碰撞检测是可靠的(至少我认为)。然后随机,就像每7-10次运行中的1次......我会得到这个崩溃。我意识到这是因为我编码了我的射弹,一旦它们与目标相交就会被移除。
然而,我没有设置故障保护,如果我的tick方法检测到它与MORE一次碰撞一次。
这是因为对于每个射弹,我遍历每个目标以检查碰撞,然后在检测到碰撞时移除相应的投射。所以我创建了一个简单的BOOL,如果它已经与目标相撞,则将其设置为YES。然后,如果弹丸没有与任何物体相撞,我只检查了碰撞。
所以...之前:
if (CGRectIntersectsRect(projectileRect, targetRect))
{
//code to remove projectile
}
后:
if (CGRectIntersectsRect(projectileRect, targetRect) && projectile.hasHitaTarget == NO)
{
//code to remove projectile
}