我想知道如何优化CCSpriteBatchNode的用法。 换句话说,我理解:

  • 1)每个CCSpriteBatchNode实例执行一次对draw方法的调用,从而减少了OpenGL调用,从而显着提高了性能
  • 2)每个CCSpriteBatchNode只能引用一个纹理图集

我不确定100%,请问您的答案是:

  • 3)如果我有一个纹理图集,例如game-art-hd.png,并在各个类中创建了几个CCSpriteBatchNode,我会得到多个绘制调用吗? 换句话说,我假设CCSpriteBatchNode的每个实例都将调用其自己的draw方法,从而导致进行多个GL绘图调用,并且比具有一个共享的批处理节点的性能要差。 我对吗?

    -4)如果我在Sprite上使用由多个帧组成的动画,我想应该将动画帧添加到Sprite批处理节点中。 我该怎么办?

    以下是有关我通常如何为子画面设置动画的代码段。 可以注意到,没有将子画面帧添加到子画面批处理节点。 为了获得更好的性能,我可能应该在初始化时执行此操作。 这个对吗?

      NSMutableArray* frames = [[NSMutableArray alloc]initWithCapacity:2]; for (int i = 0; i < 4; i++) { NSString*bulletFrame = [NSString stringWithFormat:@"animation-%i.png", i]; CCSpriteFrame* frame = [[CCSpriteFrameCache sharedSpriteFrameCache]spriteFrameByName:bulletFrame]; [frames addObject:frame]; } CCAnimation* anim = [CCAnimation animationWithFrames:frames delay:0.1f]; CCAnimate* animate = [CCAnimate actionWithAnimation:anim]; CCRepeatForever* repeat = [CCRepeatForever actionWithAction:animate]; [self runAction:repeat]; } 
  • 5)部分引用4.是否确定最好避免在运行时将sprite添加到sprite批处理节点或从中删除sprite?

  • 6)CCSpriteBatchNode将仅考虑将visible设置为true的sprite还是实际位于屏幕区域之外的sprite?


关于3的其他考虑

为了满足我在3.中的假设并减少CCSpriteBatchNode实例的数量,我的解决方案将遵循@Suboptimus在此答案中提出的建议。 我喜欢建议的初始化类的方法,这些类希望与MainScene类共享同一批处理节点,而不是让它们通过self.parent.parent。(...)。parent.finallysharedbatchNode访问MainScene

其他人则建议通过使用self.parent ..... parent并正确转换它来引用MainScene。

就软件工程而言,这也是最好的方法吗?

我更喜欢通过使用对MainScene类的显式引用来明确将sprites添加到何处。如果我在团队中工作或更改类层次结构,这应该会有所帮助。 但是,这样做的缺点是,如果我想向批处理节点中添加后续的精灵,则“需要”存储对该引用的引用,从而导致需要维护更多代码。

我问这个问题的原因是,如果在我的传统“软件工程”思想和“ Cocos2d父节点”层次结构方法之间发现一点冲突。 我是游戏编程的新手,我想了解大型团队中经验丰富的游戏开发人员所使用的方法是:)。 H

#1楼 票数:1 已采纳

  1. 正确,但是“绘制调用”并不等同于执行draw方法。 绘制调用是OpenGL状态的更改,需要执行昂贵的操作才能重置状态机。 绑定新纹理或更改变换可以满足要求。
  2. 正确。
  3. 正确。
  4. 没必要那样做。 动画在精灵上运行。 因此,只有精灵需要进行批处理。 如果一个动画帧不是来自同一纹理图集,则当动画尝试使用这样的帧时,CCSpriteBatchNode会抱怨。
  5. 更好 在CCSpriteBatchNode中添加/删除精灵比添加/删除任何其他节点要昂贵。 因为精灵批处理节点的四边形需要更新。 但是,如果您有许多子节点并频繁添加/删除,则可能只会有所不同。
  6. 不,不。 在这里查看我的答案

关于3的其他注意事项:

如果场景层次不太深,则有时可以使用self.parent或self.parent.parent,但仅在父/父关系实际上固定的情况下(即,从批处理的sprite依次绕过sprite批处理节点)以获得基础的“真实”父级)。 但是我不建议更深入。 请参阅我的答案,了解有关self.parent和避免保留周期的技术。

self.parent.parent.(…).parent在于,如果您需要更改父子关系,例如通过在层次结构中添加或删除父节点,这会完全中断。 然后,这将在EXC_BAD_ACCESS中严重崩溃,并且很难调试,因为您将必须检查每个父对象和父对象的父对象,以查看其实际是哪种对象。 访问超过3个或更多层次结构的父级,我不会认为是不好的做法。 这是一种可怕的做法

就个人而言,为了访问共享的Sprite批处理等常用节点,我更喜欢这样的解决方案:“ MainScene”在活动时变为临时的Singleton类。 然后,您可以从任何子节点执行以下操作:

CCSpriteBatchNode* mainBatch = [MainScene sharedMainScene].spriteBatchNode;

要创建此临时单例:

static MainScene* instance;
-(id) init
{
    self = [super init];
    if (self)
    {
        instance = self;
    }
    return self;
}
-(void) dealloc
{
    instance = nil;
}
-(MainScene*) sharedMainScene
{
    NSAssert(instance, @"MainScene is not initialized!");
    return instance;
}

与实际单例的区别在于,如果实例不存在,则不初始化实例。 因此,sharedMainScene中的NSAssert。 您仅应在场景实例已经运行时访问它,即,该实例只能由该特定场景的子节点使用。

此半单例允许访问场景的所有属性。 您还可以发送场景可以中继到其他节点的消息。 或将需要移除但无法在碰撞处理过程中移除的物理对象排队到场景中。

而且,如果那个单身汉打扰您,那么总有可能从导演那里获得现场表演:

MainScene* mainScene = (MainScene*)[CCDirector sharedDirector].runningScene;

仅当runningScene确实是MainScene对象时,才应谨慎转换到MainScene。 isKindOfClass:按顺序检查或断言。

  ask by mm24 translate from so

未解决问题?本站智能推荐:

1回复

无法为Android加载框架cocos2d

我试图从地图集中绘制一个精灵。我用Zwoptex创建了地图集和plist文件。 将两个文件放在assest文件夹中。 在代码中,我创建了新的GameScene类 并尝试加载它。 在调试器中,我得到以下错误: 04-28 12:45:31.662:WARN / Sy
2回复

如何在Cocos2d中继承AtlasSpriteManager?

我需要创建一些将同时移动和旋转的复合精灵。 由于可以更改AtlasSpriteManager的位置和旋转,因此我一直试图对其进行子类化,因此我可以创建一些快捷方式,例如 在内部,它看起来像这样 但是,当我运行应用程序时,它崩溃,但出现以下异常 另外,如果删除“ Make
1回复

Cocos2d:动态更改Sprite的zOrder(使用CCSpriteBatchNode)

有没有办法更改由CCSpriteBatchNode呈现的精灵的zOrder? 我试过这样的: 我得到这个错误: '如果CCSprite由CCSpriteBatchNode呈现,CCSprite #draw应该不被调用' 我也尝试使用sprite的zOrder属性,但遗憾的是它是只
1回复

困惑的将0.99 Cocos2d-iPhone之前的代码重新升级到当前版本-AtlasSpriteManager

在0.99版之前的迁移指南的帮助下,我一直在非常快速地处理代码-http: //www.cocos2d-iphone.org/wiki/doku.php/prog_guide :migrating_to_0_9-但是转换已陷入困境AtlasSpriteManager,AtlasSprite到CC
1回复

Cocos2D游戏场景中CCSpriteBatchNode和纹理表的最佳方法是什么

我正在修改在Learn Cococs2D上找到的一些教程,发现每当我在一个类中使用多个CCSpriteBatchNode时,帧速率就会下降。 仔细阅读后,我了解到一个CCSpriteBatchNode一次只能接受一张纹理表,这对关卡设计提出了一些限制( 讨论时,该子图表最大为2048x20
1回复

Cocos2D精灵表

我有一些正在制作的游戏所使用的Sprite Sheet,并且正在寻求有关Sprite Sheet的内存管理方面的帮助。 我目前有8个Sprite工作表(2048x2048),每个工作表代表我的可玩角色能力和动作之一。 目前,一旦用户选择了该角色,我便将它们添加到缓存中。 我还有另外1张
1回复

Cocos2d子弹运动

截至目前,我已经使用CCAction moveTo播放器位置放置了子弹(子画面)。 我进行了设置,以使子弹始终使用t = d / v以恒定的速率行进。 但是我需要帮助,以便子弹穿过给定的点并保持一定距离。 需要知道如何在范围内射击(我想我有那个部分),朝着玩家的位置射击,然后一直朝那
3回复

在cocos2d上制作CCSprite动画?

大家好,我是cocos2d和iPhone开发的新手,我目前正尝试创建类似“ PapiJump”的游戏,目前遇到的问题是使游戏中的角色CCSprite动画化,我已经为自己的游戏制作了3张图片字符,字符指向右,左和中间(http://i53.tinypic.com/ngzoyh.png) 因此