gpt4 book ai didi

iphone - SpriteKit在何处加载数千个Sprite的纹理图集

转载 作者:行者123 更新时间:2023-12-03 16:05:45 24 4
gpt4 key购买 nike

在我的游戏中,有成千上万个构成游戏地图的“平铺”节点(想像得很简单),我想知道用于构造和动画化每个节点的最帧速率/内存有效路径是什么?有几种独特的图块“类型”,每种都有自己的纹理图集/动画,因此确保在可能的情况下重用纹理是关键。

我所有的tile节点都是单个map节点的子节点,地图节点是否应处理识别图块类型并加载必要的图集和动画(例如,通过从plist加载纹理和图集名称)?

或者,每种图块类型都是某个子类。每个SKSpriteNode磁贴处理它们自己的Sprite Atlas是否更好,例如[tileInstance texturise];(Sprite Kit如何处理此问题?这种方法是否会导致将相同纹理贴图集加载到内存中,以用于每种特定图块类型的实例?)

我一直在仔细研究文档,以获取有关地图集和纹理重用的更深入的解释,但是我不知道这种情况下的典型过程是什么。任何帮助,将不胜感激,谢谢。

最佳答案

记忆优先:不会有任何明显的差异。您必须加载图块的纹理,纹理将至少占据Map + Tiles内存的99%,仅此而已。

纹理重用:自动重用/缓存纹理。使用相同纹理的两个精灵将引用相同的纹理,而不是每个都有其自己的纹理副本。

帧率/批处理:这就是正确进行批处理的全部。 Sprite Kit通过按照将它们添加到child数组的顺序渲染它们来对节点的child进行批处理。只要下一个子节点使用与上一个相同的纹理,它们将全部被分批进行一个绘制调用。可能最糟糕的事情是添加一个精灵,一个标签,一个精灵,一个标签等等。您将要尽可能连续地使用相同的纹理添加尽可能多的精灵。

地图集用法:这是您最大的赢家。开发人员通常会尝试对地图集进行分类,这是错误的处理方式。与其要为每个图块(及其动画)创建一个图集,不如创建尽可能少的纹理图集,每个纹理图集包含尽可能多的图块。在所有iOS 7设备上,纹理图集可以为2048x2048,除iPhone 4和iPad 1外,所有其他设备都可以使用最大4096x4096像素的纹理。

该规则有例外,例如,如果您有大量纹理,则可能无法一次将它们全部加载到所有设备的内存中。在这种情况下,请根据您的最佳判断找到内存使用率与批处理效率之间的良好折衷。例如,一种解决方案可能是为每个唯一场景创建一个或两个纹理地图集,或者甚至是“风景”,即使这意味着在其他纹理地图集中为另一个场景复制一些图块。如果您的瓷砖几乎总是出现在任何风景中,则将它们放在“共享的”地图集中会很有意义。

至于对瓦片进行子类化,我强烈建议避免对节点类进行子类化。特别是如果要对其进行子分类的主要原因是仅更改其正在使用/动画化的纹理。 Sprite已经是纹理的容器,因此您还可以更改Sprite纹理并从外部对其进行动画处理。

要将数据或其他代码添加到节点,您可以通过创建自己的NSMutableDictionary并向其添加所需的任何对象来细化其userData属性。典型的基于组件的方法如下:

SKSpriteNode* sprite = [SKSpriteNode spriteWithWhatever..];
[self addChild:sprite];

// create the controller object
sprite.userData = [NSMutableDictionary dictionary];
MyTileController* controller = [MyTileController controllerWithSprite:sprite];
[sprite.userData setObject: forKey:@"controller"];


然后,此控制器对象将执行图块所需的任何自定义代码。它可能会为瓷砖和其他物体设置动画。唯一重要的一点是使对拥有节点的引用(此处为sprite)成为弱引用:

@interface MySpriteController
@property (weak) sprite; // weak is important to avoid retain cycle!
@end


因为精灵保留了字典。词典保留了控制器。如果控制器保留该子画面,则该子画面无法取消分配,因为仍然有对其的保留引用-因此它将继续保留字典,该字典保留了保留该子画面的控制器。

使用基于组件的方法的优点(也受到 Kobold Kit的青睐并在中实现):


如果设计合理,则可与任何或多个节点一起使用。如果有一天想要标签,效果,形状节点图块,该怎么办?
您不需要为每个磁贴创建一个子类。一些图块可能是简单的静态精灵。因此,对这些使用简单的静态SKSpriteNode。
它使您可以根据需要启动/停止或添加/删除各个方面。即使在瓷砖上,您最初也不希望拥有或需要某个方面。
组件使您可以构建经常甚至可能在其他项目中需要使用的功能。
组件使体系结构更好。一个典型的OOP设计错误是拥有Player和Enemy类,然后意识到两者都需要能够射箭并装备盔甲。因此,您 move the code to the root GameObject class,使代码可用于所有子类。使用组件,您只需拥有一个设备,而拍摄组件就可以添加到需要它的那些对象中。
基于组件的设计的最大好处是,您可以与其他事物分开开始开发各个方面,因此可以按需重用和添加它们。您几乎自然会编写出更好的代码,因为您以不同的心态处理事情。
从我自己的经验来看,一旦将游戏模块化为组件,您得到的bug就会少得多,而且更易于解决,因为您不必查看或考虑其他组件的代码-除非由组件使用,否则即使组件触发另一个您有明确的边界,即,当另一个组件接管时,传递的值是否仍然正确?如果不是,则该错误必须在第一个组件中。


这是 good introduction on component-based design。混合方法无疑是必经之路。这里是 more resources on component based design,但是我强烈建议不要像“公认的答案的作者”所建议的那样走开路来研究FRP-FRP是一个有趣的概念,但是在游戏开发中还没有实际应用。

关于iphone - SpriteKit在何处加载数千个Sprite的纹理图集,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19353843/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com