【问题标题】:SKTextureAtlas Loading and Memory ManagementSKTextureAtlas 加载和内存管理
【发布时间】:2014-03-18 05:14:25
【问题描述】:

我在 SpriteKit 上开发了一个游戏,每个场景都有多个场景 至少来自 3 个 TextureAtlas 每个TextureAtlas中图像的最大尺寸为60K 我的游戏因内存崩溃问题

我在每个场景中所做的就是在头文件中定义动作,例如:

initialise them in -(id)initWithSize:(CGSize)size  Function 


@interface FirstLevel : SKScene
{

    SKAction  *RedBirdAnimation;
}

在实施文件中:

-(id)initWithSize:(CGSize)size{
if(self=[super initWithSize:size])
{[self setupRedBirdActions];}
return self;
}


-(void)setupRedBirdActions{

    SKTextureAtlas *RedBirdAtlas = [SKTextureAtlas atlasNamed:@"RedBird"]; 

    SKTexture *RedBird1 = [RedBirdAtlas textureNamed:@"Redbird_01_iphone.png"];
    SKTexture *RedBird2 = [RedBirdAtlas textureNamed:@"Redbird_02_iphone.png"];
    SKTexture *RedBird3 = [RedBirdAtlas textureNamed:@"Redbird_03_iphone.png"];

    NSArray *atlasTexture = @[RedBird1, RedBird2, RedBird3];

    SKAction* atlasAnimation = [SKAction animateWithTextures:atlasTexture timePerFrame:0.2];

    RedBirdAnimation = atlasAnimation;}

在我的游戏中是否有类似最佳实践的加载纹理图集 以防止它因内存而崩溃。

我在每个 Skscene 结束时用 Nil 制作所有 SkAction 并从 All SkSpriteNode 中删除所有操作

有什么解决办法

【问题讨论】:

  • 什么时候发生崩溃?
  • 它会在一段时间后发生

标签: sprite-kit


【解决方案1】:

每个 TextureAtlas 为 60K

也许是一个文件。但这不是内存使用量。要计算图像文件的内存使用量,请获取文件的尺寸并乘以颜色位深度(通常为 32 位 = 4 字节)。

例如,一个 4096x4096 的纹理使用 16 MB 的纹理内存(但它可能远小于 1 MB 作为 PNG 文件)。

4096 x 4096 x (32/8) = 16 Megabytes

长话短说:使用 Instruments 来验证您的应用的实际内存消耗。

【讨论】:

  • 我验证我的应用程序在游戏开始时消耗了大约 100 MB,在玩游戏后达到 250 MB 并在一段时间后崩溃请帮助我如何以安全的方式加载 SKTextureAtlas 以防止崩溃记忆
  • @user3429971 您是否创建了一个名为:texture.atlas 的文件夹? (纹理只是一个例子,重要的是.atlas)这样Xcode减少了每个精灵的内存使用
  • 是的,我制作的每个纹理都是使用 RedBid.atlas CowEating.Atlas 等在文件夹中创建的
  • @LearnCocos2D 你能帮我如何安全地在我的游戏中加载 TextureAtlas
  • 这个计算不正确,一个 4 字节的 4096x4096 纹理消耗大约 68 Megs 的内存,而不是 16。
【解决方案2】:

基于 SpriteKit 的游戏内存不足的问题几乎总是由开发人员使用太多纹理导致所有活动 RAM 都被纹理占用所致。我将假设您使用基于标准 SKAction 的动画方法,并且您没有任何由强 refs 或任何东西引起的奇怪内存泄漏。确定纹理消耗的 RAM 量的正确方法是 (WIDTH * HEIGHT * 4 / 1000),这表示存储纹理所需的内存 kB 数。对于 4096x4096 纹理,即 67108 kB 或大约 68 Megs。将其存储在图集中还是作为单个纹理都没有关系。实际减少 SpriteKit 游戏使用的内存总量的关键是减少每个纹理消耗的内存量。请查看此SpriteKitFireAnimation example 的源代码,它显示了如何减少每个帧的内存使用量可以将 286 Megs 减少到 130 Megs,以实现在 64 位 iOS 上以 60FPS 执行的非常复杂的 alpha 通道动画系统。此方法仅适用于 A7 和更新的 64 位系统。如果您正在寻找质量较低但完全免费的方法,请参阅 this comparison 使用 SpriteKit 的非常有损纹理压缩方法。作为最后的努力,可以将每个纹理的宽度和高度减少 1/2,然后在渲染到节点时重新缩放纹理,它看起来不太好,但在运行时使用的内存减少了 4 倍。

【讨论】:

  • 1 MB = 1024 kB; 1 kB = 1024 B; 1 B = 8 位。因此,您必须除以 1024,而不是 1000,对于上面的示例,这正好为您提供 64 MB。
  • kB 形式表示使用 1000 作为倍数,在 MacOSX Explorer 中查看文件大小时也会看到这种格式:en.wikipedia.org/wiki/Kilobyte
  • 谢谢 - 不知道。据此,我说的是千字节,你的回答是完全正确的 :-) 因此 67.108864 MB 等于 64 MiB。
【解决方案3】:

textureAtlas 太大,系统无法加载。您需要将图像分成两个或更多单独的纹理图集,以便系统管理内存。将初始设置所需的图像放置在其自己的图集中,以便您可以在游戏开始时预加载这些图像。将图像作为单个文件引用,系统将根据需要加载和卸载图集。系统可以更好地管理内存,然后您就可以任其发展。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-19
    • 1970-01-01
    • 1970-01-01
    • 2016-10-12
    相关资源
    最近更新 更多