iphone – SpriteKit在哪里加载数千个精灵的纹理图集

iphone – SpriteKit在哪里加载数千个精灵的纹理图集,第1张

概述在我的游戏中,我有数以千计的“平铺”节点组成一个游戏地图(想想simcity),我想知道每个节点的纹理和动画的最大帧率/内存效率路径是什么?有一些独特的瓷砖“类型”,每个都有自己的纹理图集/动画,所以确保纹理在可能的时候被重用是关键. 我的所有tile节点都是单个map节点的子节点,如果map节点处理识别tile类型并加载必要的atlas&动画(例如通过从plist加载纹理和地图集名称?) 或者, 在我的游戏中,我有数以千计的“平铺”节点组成一个游戏地图(想想simcity),我想知道每个节点的纹理和动画的最大帧率/内存效率路径是什么?有一些独特的瓷砖“类型”,每个都有自己的纹理图集/动画,所以确保纹理在可能的时候被重用是关键.

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

或者,每个瓦片类型是某个子类.每个SKSpriteNode磁贴处理它们自己的精灵图集加载是否更好? [tileInstance texturise]; (sprite kit如何处理这个?这个方法会导致为某个tile类型的每个实例加载到内存中的相同纹理图集吗?)

我一直在搜索文档以更深入地解释地图集和纹理重用,但我不知道这种情况的典型程序是什么.任何帮助将不胜感激,谢谢.

解决方法 记忆优先:不会有任何明显的差异.你必须加载图块的纹理,纹理将至少占地图图块内存的99%,就是这样.

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

帧率/批处理:这都是关于正确批处理的. Sprite Kit通过按照将它们添加到children数组的顺序进行渲染来接近对节点的子节点进行批处理.只要下一个子节点使用与前一个子节点相同的纹理,它们就会被批量分配到一个绘制调用中.可能你做的最糟糕的事情是添加一个精灵,一个标签,一个精灵,一个标签等等.您将希望尽可能使用相同的纹理添加尽可能多的精灵.

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

这个规则有例外,比如你有如此大量的纹理,你不可能一次性将它们全部加载到所有设备的内存中.在这种情况下,使用您的最佳判断来找到关于内存使用与批处理效率的良好折衷.例如,一种解决方案可能是为每个独特场景创建一个或两个纹理图集,或者更确切地说是“风景”,即使这意味着复制另一个场景的其他纹理图集中的一些图块.如果您的瓷砖几乎总是出现在任何风景中,那么将它们放在“共享”地图集中是有意义的.

至于子类化tile,我强烈支持避免子类化节点类.特别是如果将它们子类化的主要原因仅仅是改变它们正在使用/动画的纹理.精灵已经是纹理的容器,因此您也可以更改精灵纹理并从外部设置动画.

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

SKSpriteNode* sprite = [SKSpriteNode spriteWithWhatever..];[self addChild:sprite];// create the controller objectsprite.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

因为精灵保留了字典.字典保留了控制器.如果控制器将保留精灵,则精灵无法解除分配,因为仍然会有一个保留引用 – 因此它将继续保留保留保留精灵的控制器的字典.

使用基于组件的方法的优势(也受到@L_404_0@的青睐和实施):

>如果设计合理,可与任何或多个节点配合使用.如果有一天你想要一个标签,效果,形状节点瓷砖怎么办?
>每个磁贴都不需要子类.一些瓷砖可能是简单的静态精灵.所以使用简单的静态SKSpriteNode.
>它允许您根据需要启动/停止或添加/删除各个方面.即使在瓷砖上,您最初并不期望拥有或需要特定方面.
>组件允许您构建一个经常需要的功能集,甚至可能在其他项目中.
>组件可实现更好的架构.经典的OOP设计错误是拥有玩家和敌人的类,然后意识到两者都需要能够射箭和装备盔甲.所以你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在哪里加载数千个精灵的纹理图集全部内容,希望文章能够帮你解决iphone – SpriteKit在哪里加载数千个精灵的纹理图集所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://www.54852.com/web/1021923.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-23
下一篇2022-05-23

发表评论

登录后才能评论

评论列表(0条)

    保存