0

在我的游戏中,我必须在游戏期间更改场景的背景。当我为背景设置新纹理时,游戏会变慢一会儿。为了避免这种情况,我试图异步预加载纹理,然后在主线程上显示它。我就是这样做的:

NSString *filename = [NSString stringWithFormat:@"res/src/level_%i/background.png", [GameLevel sharedGameLevel].currentLevelIndex + 1];
__block CCTexture2D *texture;

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    NSLog(@"FILENAME %@", filename);
    [[CCTextureCache sharedTextureCache] addImage:filename];
    NSLog(@"%@", [CCTextureCache sharedTextureCache]);

    dispatch_async(dispatch_get_main_queue(), ^{

        texture = [[CCTextureCache sharedTextureCache] textureForKey:filename];

        [spareBackground setTexture:texture];

        [dayBackground runAction:[CCSequence actions:fadeOut,[CCCallBlockN actionWithBlock:^(CCNode *node)
        {
            NSLog(@" TEXTURE %@", texture);
            [dayBackground setTexture:texture];
            CCFadeIn *fadeIn = [[[CCFadeIn alloc] initWithDuration:5] autorelease];
            [dayBackground runAction:fadeIn];
        }], nil]];      

    });
});

但是尽管纹理已成功加载,但我总是收到一个空白屏幕而不是背景,它不是nil。如果在主线程上加载纹理而不使用 gcd,则此代码可以正常工作。我错过了什么?

4

2 回答 2

1

我怀疑这CCTextureCache不是线程安全的(并且作为共享对象,它需要是线程安全的才能从另一个线程安全地调用)。

另一方面,Cocos2d 已经提供了异步加载纹理的机制,因此您可以改用它们。这应该是签名:

[[CCTextureCache sharedTextureCache] addImageAsync:filename target:self selector:@selector(textureLoaded:)];
于 2013-02-12T09:05:04.390 回答
0

如果你能负担得起用'空间'换'时间',即你的游戏的内存占用是合理的,在场景开始时预加载两个纹理,在游戏过程中,只需翻转纹理的可见性。

此外,我发现加载 pvr 纹理而不是 png 会运行得更快(即消耗更少的 cpu 我猜)。您可以尝试将其作为第一次尝试 - 希望从用户体验的角度来看“暂停”是可以接受的。

附言。我对性能的任何评论都是基于对真实设备的实际测量和测试。模拟器没用。在花费任何精力进行优化之前,请确保设备上存在此“暂停”。

于 2013-02-12T15:07:19.637 回答