我个人不建议再使用 NSObject 作为 cocos2d 类的基类。仅仅因为你失去了一些 cocos2d 的便利特性,比如调度,你可以很容易地在内存管理方面给自己开枪。
您想要的是场景具有一个或多个精灵批处理节点的设置。您可以将它们视为您的精灵的图层。从 CCNode 派生的实际游戏对象(将它们视为 MVC 控制器)可以添加到任何地方,通常直接添加到场景中。
scene
+ batch node 1
+ sprite 1
+ sprite 2
+ sprite n
+ batch node 2
+ sprite 1
+ sprite 2
+ sprite n
+ game node 1
+ game node 2
+ game node 3
+ game node n
要记住的是,每个游戏节点都有一个或多个精灵作为实例变量,但它们不是节点的子节点。例如,游戏节点 1 类可能如下所示:
game node 1 class
CCSprite* sprite1; // instance variable
CCSprite* sprite2; // instance variable
现在,当您初始化游戏节点 1 及其精灵时,您将精灵添加到适当的精灵批处理节点。通常,您会希望像单例一样访问您的场景以访问其 sprite 批处理属性。
sprite1 = [CCSprite spriteWithSpriteFrameName:@"doodle.png"];
[[scene sharedScene].batchNode1 addChild:sprite1];
sprite2 = [CCSprite spriteWithSpriteFrameName:@"splash.png"];
[[scene sharedScene].batchNode2 addChild:sprite2];
请注意,您不需要保留精灵,只要它们是精灵批处理节点的子节点。addChild 方法为您保留它。实际上,它只是将其添加到执行保留的数组中。另外,如果您仍在考虑“保留”,请务必开始使用 ARC。
您不需要弄清楚如何访问精灵批处理中的精灵。它可以作为游戏节点类的实例变量使用,如果您愿意,也可以将其作为属性公开提供给其他类。
游戏节点类显然运行所有对象的游戏逻辑,包括定位和修改精灵的属性。在游戏节点类中唯一需要注意的是从批处理节点中删除精灵,否则可能会泄漏。为此,请覆盖清理方法:
-(void) cleanup
{
[sprite1 removeFromParentAndCleanup:YES];
sprite1 = nil;
[sprite2 removeFromParentAndCleanup:YES];
sprite2 = nil;
[super cleanup];
}
将变量设置为 nil 很重要,因为清理后可能会有代码运行,包括 dealloc 方法中的代码。您也可以删除 dealloc 中的精灵,但根据您的设置,由于对游戏节点类仍持有的精灵的引用,甚至可能不会调用 dealloc。因此,如果精灵不是游戏节点类本身的子(或孙),则使用清理方法通常更安全。