缓存大型纹理图集,用于swift和spritekit中的动画

时间:2015-04-07 19:22:30

标签: sprite-kit

我无法缓存大型纹理图集(几乎完整的2048x2048)并将其用于animatewithtextures。它最初落后于第一次加载。之后就可以了。使用我的所有其他地图集,我只需将它们放在一个单例中,然后使用以下链接中的方法将它们保存起来:https://www.codeandweb.com/blog/2013/09/23/spritekit-animations-and-textureatlases self.atlas = [SKTextureAtlas atlasNamed:SPRITES_ATLAS_NAME]

好像它正在加载然后在内存中卸载纹理图集。还有其他人经历过这个吗? 使用Swift 1.2,SpriteKit,Texture Packer

3 个答案:

答案 0 :(得分:1)

我最终找到了解决方案。您所要做的就是在运行时将一个项目添加到场景中,以确保它解压缩图集。我写了一个函数来对atlas / texture控制器中的所有地图集执行此操作。 Apple表示没有内置功能来执行此操作,预加载功能不会执行解压缩。

答案 1 :(得分:0)

通过在GameTextures类中使用Singleton模式,您可能只是让self.explosionAtlas不会被初始化两次。但我认为你实际上并没有预加载纹理。你必须先预先加载它们,然后像​​@sangony指向那样坚持引用它们,防止它们被释放。像self.explosionAtlas这样的存储引用不会自动将纹理从该图集预加载到内存中。您可以通过查看手动将纹理预加载到数组中的内存消耗或使用+ preloadTextureAtlases:withCompletionHandler:vs像self.atlas = [SKTextureAtlas atlasNamed...]

这样的方法来查看调试导航器中的内容

我要做的一件事就是完全删除与该动画相关的代码,以便在呈现场景时看看app是否在开始时滞后。只是为了确定问题所在。

同时检查你的timePerFrame参数......不要设置得太低......如果你只使用39张图片进行一次爆炸,我认为你应该尝试使用少量帧并将timePerFrame参数设置为更高的值。我爆炸了10张图片,timePerFrame设置为0.06,看起来仍然很棒。你当然知道设备内存有限...... iPhone 4s有512兆字节的RAM内存,但是当内存消耗大约为200-250 MB时会崩溃。所以要小心大动画/纹理,因为纹理消耗了应用程序的大部分内存。 Check this out

要计算内存中的图像数量,您可以阅读here

请注意,如果您决定放弃当前动画,可以使用SKEmitterNode进行大爆炸,但我仍然认为您没有正确缓存纹理,并且在调用动画之前它们还没有准备好(以及您使用的是小型timePerFrame间隔,如0.033或类似的东西)。

希望这会带你到某个地方。

答案 2 :(得分:0)

如果您使用单身人士存储所有动画,我建议您记住这些示例进行组织。

单例头文件

-(void)loadPlayer0Atlas;
@property (strong) SKTextureAtlas *player0Atlas;
@property (strong) SKAction *player0_walk;
@property (strong) SKAction *player0_jump;
@property (strong) SKAction *player0_shoot;

单身实施文件

-(void)loadPlayer0Atlas {
    if(self.player0Atlas == nil) {
        NSLog(@"loading player0AtlasLoaded");
        self.player0Atlas = [SKTextureAtlas atlasNamed:PLAYER0ATLAS_ATLAS_NAME];
        [SKTextureAtlas preloadTextureAtlases:[NSArray arrayWithObject:self.player0Atlas] withCompletionHandler:^{
            [self loadPlayer0Assets];
        }];
    } else {
        NSLog(@"no load needed for player0AtlasLoaded");
        [[NSNotificationCenter defaultCenter]postNotificationName:@"player0AtlasLoaded" object:self];
    }
}

-(void)loadPlayer0Assets {
    self.player0_walk = [SKAction repeatActionForever:[SKAction animateWithTextures:PLAYER0ATLAS_ANIM_WALK timePerFrame:0.1]];
    self.player0_jump = [SKAction animateWithTextures:PLAYER0ATLAS_ANIM_JUMP timePerFrame:0.05];
    self.player0_shoot = [SKAction repeatActionForever:[SKAction animateWithTextures:PLAYER0ATLAS_ANIM_SHOOT timePerFrame:0.1]];
    [[NSNotificationCenter defaultCenter]postNotificationName:@"player0AtlasLoaded" object:self];
}

强类属性会引用您的地图集和动画。您可以调用loadPlayer0Atlas方法来加载地图集和动画。加载后,会发送一条NSNotification消息,让您知道(例如)GameScene。

您可以像这样调用动画:

[playerNode runAction:[singleton player0_walk] withKey:@"animation"];