一直在为iOS的塔防游戏工作。我正在使用Cocos2d(v0.99.5不确定)。最近我开始删除sprite时遇到了一些问题。
使用乐器和僵尸拥有配置文件,这是我得到的:
更新sprite(以及删除它们)的代码位于update:
-(void) update:(ccTime)deltaTime {
if (paused)
return;
CCArray *childs = [textureAtlas children];
//Update all objects
for (GameSprite *tempChar in childs) {
if ([tempChar respondsToSelector:@selector(updateStateWithDeltaTime:andListOfGameObjects:andAtlas:)]) {
[(GameSprite*)tempChar updateStateWithDeltaTime:deltaTime andListOfGameObjects:[textureAtlas children] andAtlas:textureAtlas];
}
}
//Remove dead projectiles
for (GameSprite *tempChar in childs) {
if ([tempChar isKindOfClass:Projectile.class]) { //(**)
if (![tempChar alive]) {
[tempChar remove];
}
}
}
//Remove dead towers
for (GameSprite *tempChar in childs) {
if ([tempChar isKindOfClass:Tower.class]) {
if (![tempChar alive]) {
[tempChar remove];
}
}
}
//Remove dead creeps
for (GameSprite *tempChar in childs) {
if ([tempChar isKindOfClass:Creep.class]) {
if (![tempChar alive]) {
[tempChar remove];
}
}
}
}
GameSprite.m中的remove方法:
-(void)remove {
CCLOG(@"remove");
[self removeFromParentAndCleanup:YES];
}
第一个块更新SpriteBatchNode / textureAtlas中的精灵。如果应删除,则剩余的三个块将检查不同的对象。 (他们的活动变量设置为NO?)。我有三个不同类型的块的原因是因为射弹具有(弱)参考它们射击的蠕变并且需要在蠕变之前被删除。
所以我的问题是,当一个弹丸撞到一个蠕变时,它随机崩溃,并且要移除射弹(以及所有其他射弹在该蠕变中射击)。 creeps引用计数降为0,但似乎仍然在childs数组中。导致我得到的错误是:
*** -[NormalProjectile isKindOfClass:]: message sent to deallocated instance 0xff33e30
在我用(**)
标记的行上要么问题是我理解Cocos2d的removeFromParentAndCleanUP:或者从记忆的角度来看我处理弹丸 - 蠕变关系的“解决方案”是坏的。关于如何解决这个问题或进一步调试它的任何想法?
答案 0 :(得分:3)
你通过数组的快速枚举技术是将你在该数组中的所有精灵作为CCSprite的自定义子类,然后检查它们是否是一个不同的自定义子类,如Tower等。我看不到这是一种健康的编程实践,因为一个类中的方法可能不在另一个类中,但是你仍在使用它们。
这可能会或可能不会对您的问题做出贡献,但更明智的做法是为特定班级的孩子保留assign
iVar CCArray。即将所有射弹放入一个阵列创建时并添加到批处理节点然后你可以通过遍历那些单独的阵列遍历所有射弹,塔等,你知道什么样的他们已经上课了。然后在必要时从数组中删除它们以及从父项中删除它们。我认为这比通过你的整个游戏中的所有精灵更加安全,这可能包括没有被使用的spite,也许,并且将它们投射并测试它们作为不同的类。