游戏对象与组合和CCSpriteBatchNode [英] Game object with composition and CCSpriteBatchNode

查看:95
本文介绍了游戏对象与组合和CCSpriteBatchNode的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在iPhone上使用cocos2d和box2d开发一个游戏。

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

I'm currently developing a game with cocos2d and box2d on iPhone.
I read a lot of articles concerning game code organization, game objects structure etc. I first started developing my game objects by inheriting from a base class itself inheriting from CCSprite. I had a CCSpriteBatchNode to draw all the game items, which the player can interact with, in one draw call. This was easy because my Item class indirectly inherit from CCSprite so I could easily add my items to the CCSpriteBatchNode. And on top of that I could rely on cocos2d to retain my objects.

在我阅读文章后,我理解需要重构我的代码,而不是继承的风格。
所以我去了一个GameObject基类继承自NSObject并且具有一个或多个CCSprite,一个b2Body等属性。

After I read the articles, I understood the need to refactor my code with a more composition oriented style rather than the inheritance style. So I went with a GameObject base class inherited from NSObject and having properties such as one or more CCSprite, one b2Body etc.

我面对的问题现在是我不能直接添加我的GameObject到CCSpriteBatchNode。我首先认为我可以很容易地通过添加游戏对象的sprite属性到CCSpriteBatchNode来解决这个问题。它是确定,但谁保留拥有CCSprite的对象?如何从CCSprite(是userData / Object确定)轻松访问原始对象?

The problem I'm facing now is that I can't directly add my GameObject to the CCSpriteBatchNode anymore. I first thought I could easily fix the problem by adding the sprite property of the GameObject to the CCSpriteBatchNode. It's ok but who retains the object owning the CCSprite ? How can I easily access the original object from the CCSprite (are userData/Object ok) ?

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

Should I create an array retaining my items ? I'd like to know how you would use a CCSpriteBatchNode with such a game object structure ?

已经有一个线程关于那是没有答案,我真的想听听这个主题。

There is already a thread about that which is unanswered and I'd really like to hear about the subject. Not a straight answer but some elements to go further.

推荐答案

我个人不建议使用NSObject作为cocos2d类的基类。只是因为你失去了一些cocos2d方便的功能,如日程安排,你可以轻松地拍摄自己在脚,内存管理聪明。

Personally I don't recommend using NSObject as the base class for cocos2d classes anymore. Simply because you lose some cocos2d convenience features such as scheduling and you can easily shoot yourself in the foot, memory-management wise.

你想要的是一个设置,场景有一个或多个子画面批处理节点。你可以考虑他们的图层为你的精灵。

What you want is a setup where the scene has one or more sprite batch nodes. You can consider them layers for your sprites. Your actual game objects (consider them to be MVC controllers) deriving from CCNode can be added anywhere, typically directly to the scene.

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

要记住的一点是,每个游戏节点都有一个或多个sprite作为实例变量,但它们不是节点的子节点。因此,例如游戏节点1类可能看起来像这样:

The thing to keep in mind is that each game node has one or more sprites as instance variables, but they're not childs of the node. So for example the game node 1 class might look like this:

game node 1 class
  CCSprite* sprite1;  // instance variable
  CCSprite* sprite2;  // instance variable



现在当你初始化游戏节点1及其精灵时,适当的sprite批处理节点。通常你将想要像单例一样访问你的场景,以获取它的sprite批次属性。

Now when you init game node 1 and its sprites, you add the sprites to the appropriate sprite batch node. Typically you will want to access your scene like a singleton to get access to its sprite batch properties.

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

注意,你不需要保留精灵,只要它们是子画面的子节点。 addChild方法为您保留它。实际上,它只是将它添加到一个数组,进行保留。此外,如果您仍在考虑保留,一定要开始使用ARC

Note that you do not need to retain the sprites as long as they are children of the sprite batch node. The addChild method retains it for you. Actually, it just adds it into an array which does the retaining. Also, if you're still thinking about "retain", by all means start using ARC.

你不需要弄明白如何访问精灵批处理中的精灵。它可以作为你的游戏节点类的一个实例变量,如果你愿意的话,你也可以把它作为一个属性公开给其他类。

You do not need to figure out how to access the sprite in the sprite batch. It's available as an instance variable of your game node class, and if you wish, you can also make it publicly available to other classes as a property.

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

The game node class obviously runs all the object's game logic, including positioning and otherwise modifying the sprite's properties. The only thing you need to take care of in the game node class is that you remove the sprites from the batch node, otherwise it may be leaking. To do so, override the cleanup method:

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

    [super cleanup];
}

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

It's important to set the variables to nil because there may be code running after cleanup, including the code in the dealloc method. You could also remove the sprites in dealloc but depending on your setup, dealloc may not even get called because of the references to the sprite the game node class is still holding. Therefore it is generally safer to use the cleanup method if the sprites are not children (or grandchildren) of the game node class itself.

这篇关于游戏对象与组合和CCSpriteBatchNode的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆