如何在cocos2d中预加载资产?

时间:2013-09-04 22:28:44

标签: iphone ios objective-c cocos2d-iphone

我的游戏在启动时略有“眨眼”,因为我试图在appDidFinishLoading中加载大量游戏资源(几个CCScenes和纹理)。我发现尝试异步加载纹理或CCScenes会导致绘图问题(纹理只是一个黑色方块)。在cocos2d中初始化游戏资产(不仅仅是纹理)的正确方法是什么?

1 个答案:

答案 0 :(得分:0)

为了将来阅读本文的任何人的利益,有一件事可能让您感到困惑:[CCTextureCache addImage:filename]如果将其放在异步线程中则不起作用。相反,您必须使用[CCTextureCache addImageAsync:target:selector]。它阻止我暂时找到正确的解决方案:制作一个“加载”CCScene,它只在初始化函数中添加与启动图像匹配的背景图像。然后,在onEnter中,使用NSOperationQueue执行加载。 NSOperationQueue很好,因为您可以在操作之间分配依赖关系,并使用完成块来满足您的需要(更新进度条等)。这是一篇有用的文章:http://nshipster.com/nsoperation/

示例实施:

-(void)onEnter
{
    [super onEnter];

    NSOperationQueue *queue = [NSOperationQueue new];

    NSInvocationOperation *operation1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(loadTextures) object:nil];
    NSInvocationOperation *operation2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(loadAudio)    object:nil];
    NSInvocationOperation *operation3 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(displayGame)  object:nil];

    [operation3 addDependency:operation1];
    [operation3 addDependency:operation2];

    [queue addOperation:operation1];
    [queue addOperation:operation2];
    [queue addOperation:operation3];
}

最后,要注意的一件事是:当您以这种方式异步加载资源时,您可能会有一些“空白”纹理。确保在此类操作中初始化的任何场景都在前一个操作中缓存了其纹理。此外,由于某些原因,如果您使用如下方法声明纯色精灵,则必须使用已异步缓存的虚拟纹理(类似白色1x1 png),否则它将无效。

+(CCSprite *)createCCSpriteWithColor:(ccColor3B)color andSize:(CGSize)size
{   
    CCSprite *sprite = [CCSprite node]; // Does not work asynchronously
    CCSprite *sprite = [CCSprite spriteWithFile:@"blank.png"]; // Works asynchronously, if texture has been cached asynchronously

    [sprite setTextureRect:CGRectMake(0, 0, size.width, size.height)];
    [sprite setColor:color];
    return sprite;
}