【问题标题】:Memory crash with animation pre-loading cocos2dcocos2d动画预加载导致内存崩溃
【发布时间】:2012-07-12 12:55:10
【问题描述】:

我在 cocos2d 项目中遇到内存管理问题。对于我的应用程序,我需要在交互开始之前构建所有动画。我有三个动画。 每个都有大约 20 个 png 文件,分辨率为 1300 x 1000 像素,大小为 200ko。

所以在我的初始化中我只是写了:

self.animation = [CCAnimation animation];
[_animation setDelayPerUnit:0.04];
for(int i = 1; i <= 20; i++)
{
   [_animation addSpriteFrameWithFilename:[NSString stringWithFormat:@"image(%d)@2x.png",i]];
}
[[CCAnimationCache sharedAnimationCache] addAnimation:_animation name:@"animationWin"];

这种代码被执行了 3 次。如果我运行我的应用程序,它会直接崩溃。如果我只预加载 2 个动画,我就不会崩溃。 如果我在 for 循环中设置断点,我可以看到它在其中崩溃。

我不知道如何解决这个问题......你有什么想法吗?

非常感谢您的帮助!

【问题讨论】:

    标签: animation cocos2d-iphone ccsprite


    【解决方案1】:

    每个人都有大约 20 个分辨率为 1300 x 1000 像素的 png 文件,并且 大小为 200ko。

    让我们做一些数学,好吗?

    假设 PNG 文件是 32 位并且您没有启用 NPOT(非二次幂)支持,每个纹理都会消耗:

    1300x1000 => 扩展为 2 的幂 => 2048x1024 => 像素数 => 2,097,152 => 每像素乘以 32 位(4 字节)颜色深度 => 8 MB => 乘以 20 纹理 => tadaaa … a高达 160 MB 的纹理内存使用量。

    那是你的问题!

    PNG 的文件大小无关紧要。它是一种压缩格式。但是纹理是未压缩的,除非您切换到压缩效果非常好的 PVR,但您也会得到伪影和变色。

    绝对最好的解决方案是调低您尝试加载的艺术品的大小和/或数量。

    【讨论】:

    • 感谢您的解释。我减少了 PNG 上的空白空间,现在很好
    【解决方案2】:

    以下内容将为您清除内容。

    NSLog(@"AppDelegate<applicationDidReceiveMemoryWarning> : before purging all caches");
    [[CCTextureCache sharedTextureCache] dumpCachedTextureInfo];
    [[CCSpriteFrameCache sharedSpriteFrameCache] removeUnusedSpriteFrames];
    [[CCDirector sharedDirector] purgeCachedData];
    NSLog(@"AppDelegate<applicationDidReceiveMemoryWarning> : after purging all caches");
    [[CCTextureCache sharedTextureCache] dumpCachedTextureInfo];
    

    更改为 PVR 格式无济于事,因为它是决定内存量的纹理大小(PVR 只会在“磁盘”大小和加载时间方面受益,而不是运行时所需的 RAM)。每个像素的深度将:

    +(void) mediumPixelFormat{
        [CCTexture2D setDefaultAlphaPixelFormat:kTexture2DPixelFormat_RGBA4444];
    }
    

    您可以随时更改格式。我还注意到 1300x1000,这在 POT 中非常浪费。这实际上将占用与 2048x2048 纹理一样多的空间。您可以与您的图形艺术家合作将其剃成 1024x1024 的任何方式,或者将 3 个纹理组合成 2 个?

    【讨论】:

      【解决方案3】:

      嗯,我认为你使用了太多的内存。您应该尝试使用 spritesheets/batchnodes,另一种纹理格式,如 PVRTC,并尝试使用不同的像素格式。

      为了帮助解决上述所有问题,我推荐Texture Packer

      【讨论】:

      • f***。有没有办法删除我不再使用的所有以前的精灵?
      • CCSprites 或纹理 (png)?如果是第二个,您可以尝试在纹理缓存中删除UnusedTextures
      • 我试图弹出我的旧场景,然后重新分配我的导演并删除所有缓存的纹理,然后推送我的新场景......同样
      • 使用 [[CCSpriteFrameCache sharedSpriteFrameCache] removeUnusedSpriteFrames]; :)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-09
      • 2014-11-22
      • 2016-02-21
      相关资源
      最近更新 更多