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的情況下在主線程上加載紋理,此代碼工作得很好。我錯過了什麼?

+0

是你所有的NSLogs到最後一個顯示預期結果? – sergio 2013-02-12 09:00:56

+0

和'sparebackground'與'dayBackground'有什麼關係?你想做什麼?都是分配產生黑色紋理? – sergio 2013-02-12 09:02:50

+0

@sergio所有NSLogs顯示我期望看到的。 spareBackground恰好位於dayBackground底下。是的,這兩者都是空白 – 2013-02-12 09:05:14

回答

1

我的懷疑是CCTextureCache不是線程安全的(並且它是一個共享對象,它需要線程安全以便從另一個線程安全地調用)。

另一方面,Cocos2d已經提供了異步加載紋理的機制,因此您可以使用它們代替。這應該是簽名:

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

不幸的是addImageAsync減緩主線程 – 2013-02-12 10:26:48

+0

可能要正確管理緩存...... – 2013-02-12 10:53:18

+1

@Andrey Chernukha:好吧,你在同一個CPU上運行的任務與主線程的運行會減慢主線程的速度。如果你看看'addImageAsync'的實現,你會發現它只是將圖像加載到一個單獨的線程中(但它是以線程安全的方式進行的)。沒有理由相信創建CGD線程會有很大的不同(除了處理線程安全性的成本之外)。 – sergio 2013-02-12 11:25:45

0

如果你能負擔得起交易的「時間」「空間」,也就是你的遊戲內存佔用量是合理的,在現場開始預加載兩種紋理,並在遊戲過程中,只是翻轉紋理的可見性。

另外,我發現加載pvr紋理而不是png的運行速度會更快(即消耗更少的CPU)。你可以嘗試這種嘗試 - 希望從用戶體驗的角度來看「暫停」是可以接受的。

ps。我對性能的任何評論都是基於真實設備上的實際測量和測試。模擬器沒用。在花費精力進行優化之前,請確保設備上存在「暫停」。