具有组合和CCSpriteBatchNode的游戏对象

时间:2012-05-02 21:35:57

标签: cocos2d-iphone code-organization

我目前正在iPhone上用cocos2d和box2d开发游戏 我阅读了很多关于游戏代码组织,游戏对象结构等的文章。 我首先通过从继承自CCSprite的基类本身继承来开发我的游戏对象。 我有一个CCSpriteBatchNode可以在一次绘制调用中绘制玩家可以与之交互的所有游戏项目。这很容易,因为我的Item类间接地从CCSprite继承,所以我可以轻松地将我的项添加到CCSpriteBatchNode。最重要的是,我可以依靠cocos2d来保留我的对象。

在阅读完文章后,我理解需要使用更加面向构造的样式而不是继承样式来重构我的代码。 所以我使用了一个继承自NSObject的GameObject基类,并具有一个或多个CCSprite,一个b2Body等属性。

我现在面临的问题是我无法直接将我的GameObject添加到CCSpriteBatchNode。我首先想到我可以通过将GameObject的sprite属性添加到CCSpriteBatchNode来轻松解决问题。没关系,但是谁保留了拥有CCSprite的对象?如何从CCSprite轻松访问原始对象(是userData / Object ok)?

我应该创建一个保留我的项目的数组吗? 我想知道如何使用具有这种游戏对象结构的CCSpriteBatchNode?

关于这个问题已经有thread没有答案,我真的很想听听这个问题。不是一个直接的答案,而是一些要进一步的元素。

感谢。

1 个答案:

答案 0 :(得分:3)

我个人不建议再使用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及其精灵时,将精灵添加到相应的精灵批处理节点。通常,您需要像单例一样访问场景以访问其精灵批处理属性。

sprite1 = [CCSprite spriteWithSpriteFrameName:@"doodle.png"];
[[scene sharedScene].batchNode1 addChild:sprite1];
sprite2 = [CCSprite spriteWithSpriteFrameName:@"splash.png"];
[[scene sharedScene].batchNode2 addChild:sprite2];

请注意,只要它们是精灵批处理节点的子节点,就不需要保留精灵。 addChild方法为您保留它。实际上,它只是将它添加到一个保留的数组中。此外,如果您仍在考虑“保留”,请务必使用start using ARC

您不需要弄清楚如何在精灵批处理中访问精灵。它可以作为游戏节点类的实例变量使用,如果您愿意,也可以将其作为属性公开提供给其他类。

游戏节点类显然运行所有对象的游戏逻辑,包括定位和修改精灵的属性。在游戏节点类中唯一需要注意的是从批处理节点中删除精灵,否则它可能会泄漏。为此,请覆盖清理方法:

-(void) cleanup
{
    [sprite1 removeFromParentAndCleanup:YES];
    sprite1 = nil;
    [sprite2 removeFromParentAndCleanup:YES];
    sprite2 = nil;

    [super cleanup];
}

将变量设置为nil非常重要,因为清理后可能会运行代码,包括dealloc方法中的代码。你也可以删除dealloc中的sprite,但是根据你的设置,dealloc甚至可能因为对游戏节点类仍然持有的sprite的引用而被调用。因此,如果精灵不是游戏节点类本身的子(或孙子),则使用清理方法通常更安全。