无法显示异步加载的纹理

时间:2013-02-12 08:43:04

标签: iphone ios objective-c cocos2d-iphone grand-central-dispatch

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

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的情况下在主线程上加载纹理,则此代码可以正常工作。我错过了什么?

2 个答案:

答案 0 :(得分:1)

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

另一方面,

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

[[CCTextureCache sharedTextureCache] addImageAsync:filename target:self selector:@selector(textureLoaded:)];

答案 1 :(得分:0)

如果您能够为“时间”交换“空间”,即游戏的内存占用是合理的,则在场景开始时预加载两种纹理,在游戏过程中,只需翻转纹理的可见性。

此外,我发现加载pvr纹理而不是png将运行得相当快(即我猜测消耗更少的CPU)。你可以尝试这是第一次尝试 - 希望从用户体验的角度来看,'暂停'是可以接受的。

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