Старайтесь не создавать и не удалять спрайты во время выполнения, т. Е. Стараться избегать этого часто:
[CCSprite spriteWithFile:@"background.png"];
Это выделяет новую память для спрайта, и при создании нового спрайта происходит довольно много событий. И конечно вы выпускаете уже существующие спрайты. Все это не нужно.
В вашем методе redrawGameHUD я не вижу признаков того, почему вы действительно хотите создавать спрайты заново. Спрайты используют одни и те же изображения каждый раз. Так почему бы просто не оставить старые? Если вы не редактировали код до того, как опубликовали его в вопросах, нет необходимости удалять и заново создавать спрайты HUD.
Вы также можете создать атлас текстуры для всех изображений спрайтов HUD. Например, вы можете отобразить все спрайты HUD одним вызовом отрисовки, используя CCSpriteBatchNode. Во-вторых, всякий раз, когда вы хотите назначить новую текстуру существующему спрайту, вы просто изменили бы 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 (CCSprite *entity in [[[GameHUD class] sharedHUD] buildable])
отправит два дополнительных сообщения (class и sharedHUD) для каждого объекта в массиве. Эти дополнительные вызовы могут быстро сложиться, хотя их явно недостаточно для снижения частоты кадров, которое вы испытываете.
Вы также без необходимости сохраняете все спрайты HUD в массиве "buildable". Почему бы не использовать уже существующий дочерний массив, который использует 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 ...
}
}
Опять же, это позволяет избежать ненужного добавления, сохранения, удаления и освобождения объектов в создаваемом массиве. И вы можете быть уверены, что вы случайно не удалите спрайты из иерархии узлов, но не создаете массив или наоборот.
Я хотел бы закончить с предположением: в вашем коде я увидел общую тенденцию, что вы делаете много лишних вещей без необходимости. Я предполагаю, что это так на протяжении всего проекта. Возможно, вы захотите вернуться и спросить себя (лучше: выяснить), какие еще вещи, которые вы выполняете на устройстве, являются довольно ненужными.