0

我正处于 iphone 游戏的初始构建阶段,我正在使用精灵表来创建一些随机的人,每个人都有头发、衣服等的子精灵。

我使用 CCSpriteBatchNode 将我的精灵图像存储在精灵表中。我现在只是在进行初始设置测试,您可以在其中点击屏幕以生成一组新的随机人员。所以奇怪的是,你可以点击一次,它会删除旧人并用新人替换他们,但第二次,它会崩溃并出现错误:“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 的内容,并且了解到删除单个 sprite 是很棘手的,所以我确信我需要在这里添加一些重要的行。谢谢你的帮助!

编辑: 我用谷歌搜索了错误并找到了这个线程: http: //www.cocos2d-iphone.org/forum/topic/17170这似乎证实了 Cocos2d 认为我没有将精灵添加到精灵表中 - 但我是,正如精灵第一次正确添加的事实所证明的那样,而不是第二次。

一种解决方案是完全避免删除精灵,只是让它们不可见,并在需要重用时用新特性重新绘制它们。我宁愿知道真正的解决方案是什么,因为它看起来更干净。

4

3 回答 3

1

我只想在这里提一下我在这个问题上的经验以及我是如何解决它的。

请记住,您要么尝试删除从未添加的孩子..

或者

试图删除一个孩子两次。

我就是这种情况。我的游戏中的碰撞检测是可靠的(至少我认为)。然后随机地,比如每 7-10 次运行中的 1 次......我会遇到这个崩溃。我意识到这是因为我已经对我的射弹进行了编码,一旦它们与目标相交就会被移除。

但是,如果我的滴答方法检测到它一次与 MORE then 1 个目标发生冲突,我没有设置故障保护。

这是因为对于每个射弹,我遍历每个目标以检查碰撞,然后在检测到碰撞时移除相应的投影。所以我创建了一个简单的 BOOL,如果它已经与目标发生碰撞,则将其设置为 YES。然后我只在弹丸没有与任何东西碰撞时检查碰撞。

所以...之前:

if (CGRectIntersectsRect(projectileRect, targetRect))
{
//code to remove projectile
}

后:

if (CGRectIntersectsRect(projectileRect, targetRect) && projectile.hasHitaTarget == NO)
{
//code to remove projectile
}
于 2012-11-14T00:17:00.530 回答
1

看起来你需要改变

[_people addObject:per];

[_people replaceObjectAtIndex:i withObject:per];

在您的第一个循环中,您只是将数组中对象的值设置为 nil,而不是将其从数组中删除。在第二个循环中,您只需将其添加到数组的末尾,但您的数组中已经有 7 个 nil。

让我知道它是否有效。

于 2012-02-20T22:36:58.003 回答
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 添加到自己作为孩子。(实际上,添加它们的顺序无关紧要)。

解决这个问题,也许这个问题会消失,或者至少它会更清晰,以便我们为您提供帮助。

于 2012-02-20T07:49:29.423 回答