SpriteKit SKTexture.preloadTextures 高内存使用 Swift

Posted

技术标签:

【中文标题】SpriteKit SKTexture.preloadTextures 高内存使用 Swift【英文标题】:SpriteKit SKTexture.preloadTextures high memory usage Swift 【发布时间】:2015-05-20 11:49:37 【问题描述】:

我有一个包含大约 90 个 PNG 图像的 SKTextureAtlas。每张图片的分辨率为 2000 x 70 像素,大小约为 1 KB。

现在我将这些来自 Atlas 的图像放入这样的数组中:

var dropBarAtlas = SKTextureAtlas(named: "DropBar")

for i in 0..<dropBarAtlas.textureNames.count
        var textuteName = NSString(format: "DropBar%i", i)
        var texture = dropBarAtlas.textureNamed(textuteName)
        dropFrames.addObject(texture)
   

然后我在 didMoveToView 中预加载带有纹理的数组:

SKTexture.preloadTextures(dropFrames, withCompletionHandler:  () -> Void in)

要以 30 fps 播放动画,我使用 SKAction.animateWithTextures

var animateDropBar = SKAction.animateWithTextures(dropFrames, timePerFrame: 0.033)
dropBar.runAction(animateDropBar)

我的问题是,当我预加载纹理时,内存使用量增加到大约 300 MB。 有没有更高效的解决方案? 对于 SKAction.animateWithTextures,建议使用哪种帧速率和图像大小?

【问题讨论】:

问题是您根本无法同时将这么多图像解码到主内存中。有更高级的动画可用,它们不会一次将所有解码的字节保存在内存中。 有效SpriteKit纹理压缩的例子,看这个答案***.com/a/38679128/763355 【参考方案1】:

您应该记住,图像文件大小(在您的示例中为 1Kb)与将相同图像存储在 RAM 中所需的内存量无关。您可以使用以下公式计算所需的内存量:

宽 x 高 x 每像素字节数 = 内存大小

如果您使用标准 RGBA8888 像素格式,这意味着您的图像将需要大约 0.5 兆字节的 RAM 内存,因为 RGBA8888 每个像素使用 4 个字节 - 每个红色、绿色、蓝色各 1 个字节,以及 1 个字节用于 alpha 透明度。你可以阅读更多here。

所以你能做的就是优化你的纹理并使用不同的纹理格式。这是另一个关于纹理的例子optimization。

【讨论】:

对于 2016 年以上的读者,您应该查看 SpriteKit 和 GameplayKit 上的 WWDC 2015 视频。短版:Xcode 纹理图集已经对您的图像进行了大量优化,而 ios 9 的应用切片技术意味着您的应用的用户将自动接收设备需要的那些图形资源。例如iPhone 5s 用户只会下载 X2 分辨率的图像,而不是 X1 或 X3。此外,iOS 会在使用纹理后自动缓存它们。 (虽然也有预加载纹理的方法。)

以上是关于SpriteKit SKTexture.preloadTextures 高内存使用 Swift的主要内容,如果未能解决你的问题,请参考以下文章

Spritekit - 屏幕坐标的底部

SpriteKit - 暂停输入

SpriteKit 暂停和恢复 SKView

CAShapeLayer 和 SpriteKit

SpriteKit - 生成随机节点

SpriteKit 丢失纹理