2011-10-31 74 views
0

我目前正在建設一個遊戲的iPhone與cocos2d的,並有以下問題:重繪GameHUD多次引起cocos2d的幀速率下降顯著

我有一個名爲GameHUD一個單類顯示HUD在眼前當前級別的場景。偶爾我想要重畫HUD,所以它會根據當前的遊戲狀態而改變。問題在於我更頻繁地重繪HUD,幀速率下降得越多。

我猜我沒有發佈一些資源,但無法弄清楚我必須發佈哪些資源。 (我對內存管理非常陌生......我明白我必須釋放由以下關鍵字之一創建的對象:「new」,「alloc」,「copy」或「retain」。但cocos2d主要生成autorelease對象,爲此我不能手動釋放他們..糾正我,如果我錯了;))

//static, so it can be called from other classes 
+(void)redrawGameHUD{ 

CGSize winSize = [CCDirector sharedDirector].winSize; 

//get reference to background-sprite 
CCSprite *background = [[[GameHUD class] sharedHUD] towerBackground]; 

//remove the child from the HUD, if it exists 
[[[GameHUD class] sharedHUD] removeChild:background cleanup:YES]; 

//create sprite containing the background-image 
background = [CCSprite spriteWithFile:@"background.png"]; 

//add background image to HUD 
[[[GameHUD class] sharedHUD] addChild:background]; 

//load images that should be displayed into an array 
NSArray *images = [NSArray arrayWithObjects:@"image1.png", @"image2.png", @"image3.png", @"image4.png", nil]; 

//remove sprites from HUD before drawing them again. 
//the "buildable" array contains all those already drawn sprites 
for (CCSprite *entity in [[[GameHUD class] sharedHUD] buildable]) { 
    [[[GameHUD class] sharedHUD] removeChild:entity cleanup:YES]; 
} 
[[[[GameHUD class] sharedHUD] buildable] removeAllObjects]; 

//loop over sprites, initialize them and add them to the HUD 
for(int i = 0; i < images.count; ++i) { 

    NSString *image = [images objectAtIndex:i]; 
    CCSprite *sprite = [CCSprite spriteWithFile:image]; 

    //add sprite to HUD and memorize them in the "buildable" array 
    [[[GameHUD class] sharedHUD] addChild:sprite]; 
    [[[[GameHUD class] sharedHUD] buildable] addObject:sprite]; 
} 

}

所以每次調用此方法時,幀速率下降一點點,停下來..有人可以告訴我,我做錯了什麼?謝謝。

+0

您每次重繪時都使用不同的圖片嗎?你能解釋一下你正在試圖對HUD做什麼嗎?重繪時發生了什麼變化? – AbhinavVinay

回答

2

儘量不要創建並在運行時移除精靈,即儘量避免經常這樣做:

[CCSprite spriteWithFile:@"background.png"]; 

這爲這個精靈分配新的內存,當你創建一個新的精靈時,會在幕後發生一些事情。當然你會釋放已經存在的精靈。所有這些都是不必要的。

在你的redrawGameHUD方法中,我看不出爲什麼你實際上想要重新創建精靈。精靈每次都使用相同的圖像。那麼爲什麼不保留舊的呢?除非您在將問題發佈到問題中之前編輯了代碼,否則無需刪除並重新創建HUD精靈。

您也可能想要爲所有HUD精靈圖像創建紋理地圖集。首先,您可以使用CCSpriteBatchNode通過一次繪製調用渲染所有HUD精靈。其次,無論何時您想要爲現有的精靈分配一個新的紋理,您只需更改該精靈的CCSpriteFrame,而不是拋棄該精靈並重新創建它。

別的東西,困擾着我,你繼續寫這本:

[[[GameHUD class] sharedHUD] addChild:sprite]; 

首先,這是一樣的書寫以下,消息類是完全沒有必要(使我不知道,你拿起這事呢?):

[[GameHUD sharedHUD] addChild:sprite]; 

而且因爲你在做這多次,你應該保持GameHUD的臨時本地副本,這又去掉一些不必要的Objective-C消息:

GameHUD* gameHUD = [GameHUD sharedHUD]; 
// from now on use gameHUD instead of [GameHUD sharedHUD] 
[gameHUD addChild:sprite]; 

這是特別好的建議for循環,因爲這樣做:

for (CCSprite *entity in [[[GameHUD class] sharedHUD] buildable]) 

將爲可建陣列中的每個實體發送兩個額外消息(類和sharedHUD)。這些額外的電話可以快速加起來,儘管它們肯定不足以降低您正在經歷的幀速下降。

你也不必要把所有的「可建」數組中的HUD精靈。爲什麼不使用cocos2d使用的已經存在的子數組?只需添加每個HUD精靈是「可建」同一個標籤,例如123

[gameHUD addChild:sprite z:0 tag:123]; 

如果你需要做一些與所有的「可建」精靈那麼你可以遍歷孩子是這樣的:

CCNode* node; 
CCARRAY_FOREACH([gameHUD children], node) 
{ 
    if (node.tag == 123) 
    { 
     CCSprite* buildable = (CCSprite*)node; 
     // do stuff with buildable sprite ... 
    } 
} 

再次,這避免了不必要的添加,保留,移除和釋放可構建數組中的對象。你可以確定你不會意外地從節點層次結構中刪除精靈,但不會從可建立的數組中刪除精靈,反之亦然。

我想用一個假設得出結論:在你的代碼,我看到你在做不必要的許多額外的東西的總體趨勢。所以我猜這是整個項目的情況。您可能想要回過頭去問問自己(更好:瞭解)您有什麼其他事情可以讓設備執行這些操作,而這些操作是不必要的。

+0

謝謝,這是一些偉大的建議!我意識到在代碼部分(可能還有整個項目)還有很多需要改進的地方。我不記得我在哪裏獲得[GameHUD類]調用..我想我認爲它是唯一訪問從它的類內的靜態方法..偉大的想法與標籤,沒有想到他們在這種情況下.. – dschihejns

0

我90%確定你在iPhone模擬器上測試了這個,對嗎?

如果你是,那麼請記住,你不能在模擬器上正確地剖析OpenGL應用程序。性能變化太大。

在真實設備上進行測試並再次檢查幀頻。

如果不是,那麼你在其他地方有問題。在這種方法中完成所有的處理都是微不足道的,除非你的圖像是5000x5000像素或東西..