【问题标题】:Cocos2D 2.0 - Can one CCSpriteBatchNode be used for multiple classes?Cocos2D 2.0 - 一个 CCSpriteBatchNode 可以用于多个类吗?
【发布时间】:2012-06-10 04:50:29
【问题描述】:

我不知道这是否可能,但我想创建一个大纹理图集并将其用于应用程序的所有类。

一个CCSpriteBatchNode可以用于多个类吗?

假设我在主类上创建它

[[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:@"atlasGeral.plist"];
self.batchNodeGeneral = [CCSpriteBatchNode batchNodeWithFile:@"atlasGeral.png"];
[self addChild:self.batchNodeGeneral];

我有另一个类在主类上创建 CCLayers,它在使用 CCSpriteBatchNode 之前已初始化,如下所示:

-(id) init 
{

   if( (self=[super init])) {

        self.bg = [CCSprite spriteWithFile: @"cCircularBG.png"];
        [self addChild:self.bg];

        self.dr = [CCSprite spriteWithFile: @"cCircularDR.png"];
        [self addChild:self.dr];      
  }
  return self;  // self is a CCLayer
}

可以使用主类中的 self.batchNodeGeneral 进行优化吗?我的想法是用 [CCSprite spriteWithSpriteFrameName:...

之类的东西替换这两个精灵和其他精灵

谢谢

【问题讨论】:

    标签: cocos2d-iphone


    【解决方案1】:

    我不完全确定我是否遵循,但我很确定答案是肯定的。

    CCSpriteBatchNode 与类没有任何关系,它与资产有关。使用批处理节点的重要限制是批处理中的每个精灵都需要引用相同的纹理图集。因此,为您的整个应用程序拥有一个批处理节点并让每个游戏类将其自己的精灵添加到该批处理中是非常好的。如果您的纹理图集变得大于目标硬件上的最大纹理大小,这可能会变成一个实际问题(有关详细信息,请参阅 iOS 设备规范),但如果您仍然希望拥有全局批次和大量资产,则创建起来并不难一个由纹理 ID 索引的批处理池,为每个图集创建一个批处理节点,并且每当您创建一个新的精灵时,将其添加到相应的批处理中。

    老实说,我觉得整个批处理节点的事情对 Cocos2D 来说是一个可怕的组合,它可以对开发人员几乎完全透明,同时仍然保持其效率,但也许这种观点并不完全公平,因为我没有挖掘过在渲染代码中了解他们的动机。我想这会与对深度排序的工作方式等的期望相混淆,但我仍然不明白为什么渲染的批处理对象是程序员的责任,应该由引擎来完成。

    编辑以添加可能的解决方案:

    -(id) initWithMainClass:(MainClass*)mc
    {
    
       if( (self=[super init])) {
    
            self.bg = [CCSprite spriteWithSpriteFrameName: @"cCircularBG.png"];
            [mc.batchNodeGeneral addChild:self.bg];
    
            self.dr = [CCSprite spriteWithSpriteFrameName: @"cCircularDR.png"];
            [mc.batchNodeGeneral addChild:self.dr];      
      }
      return self;  // self is a CCLayer
    }
    `
    

    因此,当您初始化其他类之一时,您将主类实例作为参数传递,以便您可以访问其字段。或者将 main/manager 类设为单例,或者找到适合您需求的其他架构。

    【讨论】:

    • 谢谢,但是假设您的主类有一个名为 self.batchNodeGeneral 的属性和一个将返回该属性的方法,您将如何重写我在 init 部分发布的代码以使用该纹理主类的 self.batchNodeGeneral 属性?
    • 嗯,这对您来说更像是一个架构决策。您可以将您的主要对象变成负责批处理的游戏管理器之类的东西,并使其成为单例,这似乎是 Cocos2D 和一般 iOS 开发的超级流行选项。或者你可以让你的其他游戏类在初始化时将主类作为参数,这样他们就可以访问它。很大程度上取决于你的想法和目标,像这样的建筑材料会变得非常虔诚。
    • 好的,但我的主要观点是:在主类上我有这一行 [self addChild: self.batchNodeGeneral];... 在类的初始化部分我怎么能有另一个这些行将相同的节点再次添加到该类?听起来不对,如果我尝试它会崩溃。
    • @Suboptimus:我同意,精灵批处理可以而且应该在使用纹理图集时自动化。强制精灵批处理的唯一缺点是来自同一纹理图集的精灵不能轻易地在其他批处理的(z-order-wise)精灵之间绘制。
    • 对不起,我没有适当考虑您正在创建 CCLayers 的事实。一个 CCSprite 只能有一个父级,您不能将它同时添加到图层和全局精灵批处理节点,因此您将无法使用 CCLayers 执行此操作。不幸的是,您甚至不能将 CCLayers 添加到具有正确纹理的 CCSpriteBatchNode 中,因为它仅支持将 CCSprites 作为子项。绝对是一个烦恼,特别是因为它限制了您在获得最佳性能的同时对精灵进行明智分组的选择。就像我说的,Cocos2D 中的批处理是一个杂物,会妨碍你做一些明智的事情。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-12-16
    • 2019-12-19
    • 1970-01-01
    • 2014-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多