如何正确使用CCSpriteBatchNode?

发布于 2024-12-11 01:58:35 字数 447 浏览 0 评论 0原文

我将精灵帧添加到 CCSpriteFrameCache 中。然后,我使用所需的图像文件创建一个 CCSpriteBatchNode

这是我不太明白的地方:

当我制作CCSprite时,如果我想利用CCSpriteBatchNode,我需要初始化CCSprite< /code> 与 [CCSprite spriteWithBatchNode: rect:]?但如果是这样的话,我不知道如何利用 CCSpriteFrameCache 来获取帧,因为现在我将手动制作矩形。

所以我想我使用 [CCSprite spriteWithSpriteFrameName:] 然后我将此精灵添加到批处理节点。但我仍然不确定。

I add my sprite frames to CCSpriteFrameCache. Then I create a CCSpriteBatchNode with my desired image file.

This is what I don't quite understand:

When I make a CCSprite, if I want to take advantage of the CCSpriteBatchNode, I need to initialize the CCSprite with [CCSprite spriteWithBatchNode: rect:]? But if that's the case, I don't see how am I taking advantage of CCSpriteFrameCache to get the frames, since now I would be manually making the rect.

So I guess I use [CCSprite spriteWithSpriteFrameName:] and then I add this sprite to the batch node. But I am still unsure.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

独行侠 2024-12-18 01:58:35

您应该使用:

CCSprite *sp = [CCSprite spriteWithSpriteFrameName:@"monster.png"];

您在 SpriteFrameCache 中指定的 .plist 将为您处理帧。
然后创建精灵并添加到批次中。

如果您使用名为“myArt.png”的文件创建批处理节点,则只能向其中添加包含在“myArt.png”内的精灵。

希望有帮助!

You should use:

CCSprite *sp = [CCSprite spriteWithSpriteFrameName:@"monster.png"];

The .plist that you specified in the SpriteFrameCache will take care of the frames for you.
Then you create the sprite and add to the batch.

If you create the batchnode with a file called "myArt.png", you CAN ONLY add a sprite to it that is contained inside "myArt.png".

Hope it helps!

花伊自在美 2024-12-18 01:58:35

根据我对cocos2d的了解。 SpriteFrameCache 和 SpriteBatchNode 具有相同的结果,但使用方式不同,如果您的游戏非常大,可以注意到轻微的性能差异...

CCSpriteFrameCache 根据根据给定的 plist 文件命名的调用帧的时间加载您的帧。与 plist 关联的图集也必须添加到项目中,否则将调用框架但不会发现任何内容可绘制。 Plist就像图像在图像图集中的位置地址。
CCSpriteFrameCache 的优点在于,代码比 CCSpriteBatchNode 方法更简洁、更小,但代价是每次调用该帧时,都会转到该特定图集并绘制它。

另一方面,CCSpriteBatchNode 加载图集并在一次绘制调用中加载它。这是有效的,因为它减少了游戏中根据需要进行抽签的次数。这里唯一的困难是您需要对图集中每个精灵的矩形进行数学计算。这是因为假设您的图集包含一个角色的 2 个动作,图集图像文件的大小为 1024x1024,每个精灵的大小为 128x128。例如,您需要进行数学计算来获取整个跳跃动作的每个矩形。(这就是 .plist 派上用场的地方,以避免进行此类数学计算)

代码变得复杂,如您所见,但它只会执行一次调用,使得就性能而言,这是您最好的选择。
使用 CCSpriteBatchNode 的另一种方法是拥有不同的静态精灵,您只需对这些多个静态图像或精灵进行一次绘制调用。

如果您需要示例代码,请询问,我将非常乐意提供。


更新:添加 SpriteBatchNode 的链接和我自己的示例。

SpriteBatchNode:

将 SpriteBatchNode 与 Ray Wenderlich 结合使用的示例
我相信这个人,并且我从他的教程中学到了很多 Cocos2d 知识。我建议您阅读他的其他教程。

简而言之,CCSpriteBatchNode 与我们下面使用 CCSpriteFrameCache 执行的过程完全相同,唯一的区别是您将 Sprite 子节点添加到 CCSpriteBatchNode 而不是 Layer,但是您确实将 CCSpriteBatchNode 添加到 Layer。
这是 Cocos2d 新手最纠结的一个难题。


SpriteFrameCache:

SpriteFrameCache 我找不到一个很好的例子,所以这里是一个简单的例子。

//By doing this your sprites are now in the cache ready to be used 
//by their names declared in the .plist file.
-(void) loadingSprites:(NSString*) plistName {
     [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:plistName];

}

-(id)initGameLayer {
     //CCSprite accepts CCSpriteFrame and your img is now ready to be displayed.
     //However is still not drawn yet.
     CCSprite * mySprite = [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:framename];


     //set a position if desired 
     //20 pixels to the right and 0 pixels to the top.
     mySprite.position = CGPointMake(20,0);

     //Now the Image has been drawn, making 1 draw call.
     [self addChild:mySprite];

 }

值得注意的是,CCSpriteBatchNode 仅进行 1 次绘制调用,但是添加到批处理节点的所有精灵都必须是同一 SpriteAtlas 的一部分。

使用 SpriteFrameCache 只是它更容易和更简单,但是对于添加到图层中的每个子元素,这意味着正在完成 +1 绘制调用。(这是性能的缺点)

因此,如果您使用 SpriteFrameCache 将 10 个精灵添加到图层中,您将拥有 10 个精灵抽奖。

但是,如果您实现 SpriteBatchNode 并将这 10 个 Sprite 添加到 CCSpriteBatchNode 中,然后仅将该 CCSpriteBatchNode 添加到图层中,您将添加相同的 10 个 Sprite,但只会完成一次绘制调用。因此,在大型游戏中,性能差异(最好的情况)将非常显着。

希望有帮助,干杯!

According to what I've learned of cocos2d. SpriteFrameCache and SpriteBatchNode have the same result but are used differently and can notice a slight performance difference if your game is very big...

CCSpriteFrameCache loads your frames according to when they are called by their named according to the plist file it was given. The atlas associated with the plist has to be added to the project as well or else the frames will be called but nothing will be found to be drawn. The Plist is like the address of where the image is located inside the image atlas.
The good part of CCSpriteFrameCache is that the code is neater, and smaller than CCSpriteBatchNode method, at the cost that for every call of that frame, it goes to that specific atlas and draws it.

CCSpriteBatchNode, on the other hand, loads the atlas and loads it in one draw call. This is efficient because it reduces the amount of times the draw has to be done per need in the game. The only difficulty here is that you need to do math for the rectangles of each sprite in the atlas. This is because lets say your atlas is of 2 actions of a character, the atlas image file has a size of 1024x1024, and each sprite has a size of 128x128. so you would do the math to get each rectangle for the whole jump action for example.(This is where .plist come in handy to avoid doing such math)

The code gets complicated as you can see but it will only do one call, making it performance-wise your best call.
Another way to use CCSpriteBatchNode is to have different static sprites and you would just do one draw call for those multiple static images or sprites.

If you need example code just ask, I would be more than happy to provide it.


Update: Adding Link for SpriteBatchNode and an Example of my own.

SpriteBatchNode:

Example using SpriteBatchNode with Ray Wenderlich
I believe in this guy, and I have learned alot of Cocos2d from his tutorials. I would suggest you to read other of his tutorials.

In a nutshell, CCSpriteBatchNode is the exact same process we did below with the CCSpriteFrameCache the ONLY difference and its that you add the Sprite Child Node to the CCSpriteBatchNode and not the Layer, BUT you do Add the CCSpriteBatchNode to the Layer.
This is the hard concept that new comers to Cocos2d get entangled at.


SpriteFrameCache:

The SpriteFrameCache I couldn't find a good example so here is one simple one.

//By doing this your sprites are now in the cache ready to be used 
//by their names declared in the .plist file.
-(void) loadingSprites:(NSString*) plistName {
     [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:plistName];

}

-(id)initGameLayer {
     //CCSprite accepts CCSpriteFrame and your img is now ready to be displayed.
     //However is still not drawn yet.
     CCSprite * mySprite = [[CCSpriteFrameCache sharedSpriteFrameCache] spriteFrameByName:framename];


     //set a position if desired 
     //20 pixels to the right and 0 pixels to the top.
     mySprite.position = CGPointMake(20,0);

     //Now the Image has been drawn, making 1 draw call.
     [self addChild:mySprite];

 }

It is noteworthy to point out that CCSpriteBatchNode makes just 1 drawcall, HOWEVER all the sprites being added to the batchnode have to be part of the same SpriteAtlas.

And using SpriteFrameCache only its easier and simpler, but for every child added to the layer it means +1 draw call is being done.(This is the downside, performance)

So if you add 10 Sprites to the layer with SpriteFrameCache you will have 10 drawcalls.

However if you implement the SpriteBatchNode and add those 10 Sprites in the CCSpriteBatchNode instead and just add that CCSpriteBatchNode to the layer, you will have the same 10 sprites added but only ONE draw call will be done. Hence the Performance difference(for the best) will be significant in larger games.

Hope it helps, Cheers!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文