在我的游戏中,我必须在游戏时间内改变场景的背景。当我为背景设置新纹理时,游戏会减慢一会儿。为了逃避这一点,我试图异步预加载纹理,然后在主线程上显示它。这就是我这样做的方式:
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的情况下在主线程上加载纹理,则此代码可以正常工作。我错过了什么?
答案 0 :(得分:1)
我的怀疑是CCTextureCache
不是线程安全的(并且作为共享对象,它需要是线程安全的才能从另一个线程安全地调用)。
Cocos2d已经提供了异步加载纹理的机制,因此您可以使用它们。这应该是签名:
[[CCTextureCache sharedTextureCache] addImageAsync:filename target:self selector:@selector(textureLoaded:)];
答案 1 :(得分:0)
如果您能够为“时间”交换“空间”,即游戏的内存占用是合理的,则在场景开始时预加载两种纹理,在游戏过程中,只需翻转纹理的可见性。
此外,我发现加载pvr纹理而不是png将运行得相当快(即我猜测消耗更少的CPU)。你可以尝试这是第一次尝试 - 希望从用户体验的角度来看,'暂停'是可以接受的。
PS。我对性能所做的任何评论都是基于实际设备上的实际测量和测试。模拟器没用。在花费任何精力进行优化之前,请确保设备上存在“暂停”。