首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >具有composition和CCSpriteBatchNode的游戏对象

具有composition和CCSpriteBatchNode的游戏对象
EN

Stack Overflow用户
提问于 2012-05-03 05:35:57
回答 1查看 1.1K关注 0票数 1

我目前正在与cocos2d和box2d在iPhone上开发一款游戏。

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

在我读完这些文章后,我明白了需要用一种更面向组合的风格而不是继承风格重构我的代码。因此,我选择了一个继承自NSObject的GameObject基类,它具有一个或多个CCSprite、一个b2Body等属性。

我现在面临的问题是,我不能再直接将GameObject添加到CCSpriteBatchNode中。我首先想到的是,我可以通过向CCSpriteBatchNode添加GameObject的sprite属性来轻松地解决这个问题。没问题,但是谁会保留拥有CCSprite的对象呢?如何从CCSprite轻松访问原始对象(用户数据/对象是否正常)?

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

已经有一个关于未回答的问题的thread,我真的很想听听这个话题。不是一个直截了当的答案,但有一些元素需要更进一步。

谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-05-03 20:28:27

就我个人而言,我不建议再使用NSObject作为cocos2d类的基类。原因很简单,因为你失去了一些cocos2d的便利特性,比如调度,而且你很容易在内存管理方面自找麻烦。

您需要的是场景具有一个或多个精灵批处理节点的设置。你可以为你的精灵考虑它们的层。从CCNode派生的实际游戏对象(假设它们是MVC控制器)可以添加到任何地方,通常是直接添加到场景中。

代码语言:javascript
复制
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

要记住的是,每个游戏节点都有一个或多个sprites作为实例变量,但它们不是节点的子节点。例如,游戏节点1类可能如下所示:

代码语言:javascript
复制
game node 1 class
  CCSprite* sprite1;  // instance variable
  CCSprite* sprite2;  // instance variable

现在,当您初始化游戏节点1及其精灵时,将精灵添加到适当的精灵批处理节点。通常,您需要像访问单例一样访问场景,以访问其精灵批处理属性。

代码语言:javascript
复制
sprite1 = [CCSprite spriteWithSpriteFrameName:@"doodle.png"];
[[scene sharedScene].batchNode1 addChild:sprite1];
sprite2 = [CCSprite spriteWithSpriteFrameName:@"splash.png"];
[[scene sharedScene].batchNode2 addChild:sprite2];

请注意,只要精灵是精灵批处理节点的子节点,就不需要保留它们。addChild方法会为您保留它。实际上,它只是将其添加到一个数组中,该数组执行保留。另外,如果你还在考虑“保留”,那就用start using ARC吧。

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

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

代码语言:javascript
复制
-(void) cleanup
{
    [sprite1 removeFromParentAndCleanup:YES];
    sprite1 = nil;
    [sprite2 removeFromParentAndCleanup:YES];
    sprite2 = nil;

    [super cleanup];
}

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

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10422081

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档