Эффекты Cocos2d резко замедляют FPS и как правильно инициализировать EAGLView

EDIT2: в ответ на ответ ниже я создал другую GameScene для тестирования производительности частоты кадров с 4 спрайтами, анимированными эффектом CCShaky3D. Проблема все еще сохраняется, так как частота кадров все еще составляет около 15 кадров в секунду. Я вставляю код в конце этого вопроса, чтобы облегчить чтение. Я предполагаю, что это связано с тем, что я запускаю более одного CCShaky3D одновременно. Кто-нибудь может запускать несколько эффектов CCShaky3D одновременно без падения частоты кадров?

Я представил Эффекты (руководство по программированию cocos2d ) от cocos2d в своей игре и заметил, что фпс резко тормозит. От 60 кадров в секунду до ~ 10 кадров в секунду после появления спрайта, к которому я применяю эффект.

Сначала я представил их в своей игре, и у меня была проблема с черным фоном (как в сообщении , поэтому сообщение < /а>). Я следовал решению, и проблема была решена.

Я заметил в отладчике, что как только появляется четвертый спрайт, к которому я применяю анимацию, приложение получает предупреждение о памяти. Частота кадров падает, как только второй спрайт, к которому я применяю Эффект, становится видимым. В сцене у меня уже есть 2-3 вражеских спрайта на экране одновременно плюс спрайт игрока, и я предполагаю, что это может быть проблема с памятью. Затем я попытался добавить только один спрайт с анимацией, а оставшиеся 2-3 вражеских спрайта все еще там, и частота кадров падает «всего» до ~ 45 кадров в секунду.

РЕДАКТИРОВАТЬ: когда я не применяю эффект к этим спрайтам, частота кадров не меняется (остается ~60 кадров в секунду).

Я предполагаю, что это связано с тем, как я управляю своей памятью, но прежде чем резко изменить код, я хотел собрать некоторое мнение по этому поводу. Вам удается запустить сцену, например. 2-3 спрайта с эффектом и 4-5 других спрайтов (например, враги и игрок) перемещаются?

Правильная инициализация EAGLView:

Что касается запуска эффектов, мне пришлось изменить инициализацию EAGLView. Я публикую это здесь, так как я думаю, что это может быть обосновано. Я очень не знаком с инициализацией UIViewController и EAGLView, и мне интересно, делаю ли я что-то неправильно, и может ли это повлиять на частоту кадров.

Я изменил пример ShootEmUp из Изучите исходный код главы 8 cocos2d для iPhone и iPad и заметил, что в примере AppDelegate нет экземпляра RootViewController. Вместо этого в Coco2d Cookbook RootViewController используется в AppDelegate, а также в любом шаблоне, который я создаю с помощью Cocos2d. В своем коде я изменил макрос CC_DIRECTOR_INIT(), добавив инициализацию EAGLView, как это было предложено в сообщении 2.

Я нашел это официальное руководство по cocos2d, в котором говорится, что нет необходимо создать UIViewController в приложении cocos2d, что подтверждает подход в примере ShootEmUp (3 ). Поскольку я все еще не знаком с ролями CCDirector, EAGLView и UIViewController, я хотел бы попросить сообщество разъяснить, как они взаимодействуют друг с другом, а также может ли инициализация любого из них повлиять на частоту кадров. Большое спасибо.

РЕДАКТИРОВАТЬ 2. Исходный код, который я использовал для тестирования влияния эффекта CCShaky3D на частоту кадров в секунду:

// Element.h
#import <Foundation/Foundation.h>
#import "cocos2d.h"

@interface Element : CCSprite {

}
+(id) elementWithTypeAndSpawnTimeAndFrameNameAndSpawnPos:(enum ElementsType)type:  (int)time  :(NSString*)frameName :(CGPoint) spawnPosition;
@end


//Implementation of elementWithTypeAndSpawnTimeAndFrameNameAndSpawnPos method.. 
+(id) elementWithTypeAndSpawnTimeAndFrameNameAndSpawnPos:(enum ElementsType)type:  (int)time  :(NSString*)frameName :(CGPoint) spawnPosition;
{
    return [[[self alloc] initWithTypeAndSpawnTimeAndFrameNameAndSpawnPos:type :time :frameName :spawnPosition] autorelease];
}

//TestLayer.h
#import <Foundation/Foundation.h>
#import "cocos2d.h"
@interface TestLayer : CCLayer {

}
+(CCScene *) scene;
@end


//TestLayer.m

#import "TestLayer.h"
#import "Element.h"

@implementation TestLayer


+(CCScene *) scene
{
    // 'scene' is an autorelease object.
    CCScene *scene = [CCScene node];

    // 'layer' is an autorelease object.
    TestLayer *layer = [TestLayer node];

    // add layer as a child to scene
    [scene addChild: layer];

    // return the scene
    return scene;
}

/ on "init" you need to initialize your instance
-(id) init
{
    // always call "super" init
    // Apple recommends to re-assign "self" with the "super" return value
    if( (self=[super init])) {
        CCSpriteFrameCache* frameCache = [CCSpriteFrameCache sharedSpriteFrameCache];
        [frameCache addSpriteFramesWithFile:@"game-art-hd.plist"];

        // ask director the the window size
        CGSize size = [[CCDirector sharedDirector] winSize];

        CCSprite *background = [CCSprite spriteWithFile:@"bg1.png"];
        background.anchorPoint = CGPointMake(0.5f, 0);
        background.position = CGPointMake(size.width/2, 0);
        [self addChild:background];

        Element * element = [Element elementWithTypeAndSpawnTimeAndFrameNameAndSpawnPos:HEARTH :3 :@"star-anim1.png" :CGPointMake(100.0f, 20.0f)];
        element.visible=TRUE;
        id shaky = [CCShaky3D actionWithRange:4 shakeZ:NO grid:ccg(15,10) duration:5];
        [element runAction:shaky ];
        [self addChild:element ];

        element = [Element elementWithTypeAndSpawnTimeAndFrameNameAndSpawnPos:HEARTH :3 :@"star-anim1.png" :CGPointMake(140.0f, 20.0f)];
        id shaky2 = [CCShaky3D actionWithRange:4 shakeZ:NO grid:ccg(15,10) duration:5];

        element.visible=TRUE;
        [element runAction:shaky2 ];
        [self addChild:element ];

        element = [Element elementWithTypeAndSpawnTimeAndFrameNameAndSpawnPos:HEARTH :3 :@"star-anim1.png" :CGPointMake(240.0f, 20.0f)];
        element.visible=TRUE;
        id shaky3 = [CCShaky3D actionWithRange:4 shakeZ:NO grid:ccg(15,10) duration:5];

        [element runAction:shaky3 ];
        [self addChild:element ];


        element = [Element elementWithTypeAndSpawnTimeAndFrameNameAndSpawnPos:HEARTH :3 :@"star-anim1.png" :CGPointMake(340.0f, 20.0f)];
        element.visible=TRUE;
        id shaky4 = [CCShaky3D actionWithRange:4 shakeZ:NO grid:ccg(15,10) duration:5];

        [element runAction:shaky4 ];
        [self addChild:element ];

    }
    return self;
}

person mm24    schedule 16.05.2012    source источник


Ответы (2)


Какой FPS вы получили при запуске на реальном устройстве? Вы должны знать, что симулятор уступает реальным устройствам по существенным факторам. В настоящее время я запускаю приложение с более чем 16 анимированными спрайтами в сцене боя с очень приличной частотой кадров НА УСТРОЙСТВАХ ... но менее 10 кадров в секунду на симуляторе. И да, обратите внимание на это предупреждение о памяти. Вероятно, у вас есть спрайты, которые не освобождаются должным образом. Чтобы подтвердить это, вы должны добавить эту строку в соответствующее место в вашем коде:

    [[CCSpriteFrameCache sharedSpriteFrameCache] removeUnusedSpriteFrames];
    [[CCDirector sharedDirector] purgeCachedData];
    [[CCTextureCache sharedTextureCache] dumpCachedTextureInfo];

и убедитесь, что то, что у вас есть в кеше текстур, соответствует тому, что вы ожидаете. Если это не так, отыщите «сюрпризные» текстуры и убедитесь, что они удалены должным образом.

person YvesLeBorg    schedule 16.05.2012
comment
Привет, спасибо за это. После обеда попробую добавить команду :). Между тем, эти частоты кадров относятся к реальным данным устройства. Я отпишусь вскоре после попытки поиграть с управлением памятью. Спасибо! - person mm24; 16.05.2012
comment
PS: Анимируете ли вы спрайты с помощью Эффектов? Кроме того, могу я спросить вас, как вы обращаетесь со спрайтами? У вас есть класс EnemyCache с массивом или вы добавляете и удаляете их на сцену в зависимости от того, когда они должны появиться? PPS: я пытался использовать ваши команды, и они удаляют данные кеша текстур, которые мне нужны (например, кадры пуль, которые я загрузил в игровой сцене). Мне, вероятно, нужно лучше поработать над управлением памятью, если вы подтвердите, что можете запускать 3D-эффекты для 16 анимированных спрайтов вашего приложения. - person mm24; 16.05.2012
comment
Я добавил EDIT2 с исходным кодом TestLayer, который я создал, чтобы проверить наши предположения. Есть свидетельства того, что одновременного запуска эффекта CCShaky3D более чем на одном CCSprite достаточно, чтобы снизить частоту кадров... если только я не упустил что-то тривиальное в своем тестовом примере. - person mm24; 16.05.2012
comment
К сожалению, не эффекты, я довольно старая шляпа в отношении таких вещей, как производительность, и стараюсь максимально контролировать различные элементы, которые могут на нее повлиять. Я добавляю спрайты «как раз вовремя» и убираю их как можно раньше. Я предпочитаю снова и снова нести затраты на загрузку спрайтов, чем иметь лишний багаж в памяти. Обычно нагрузка возникает в логической «паузе» игры, во время перехода или в каком-либо другом обстоятельстве, которое не будет сдерживающим фактором для игрового процесса. - person YvesLeBorg; 16.05.2012
comment
К сожалению, не эффекты, я довольно старая шляпа в отношении таких вещей, как производительность, и стараюсь максимально контролировать различные элементы, которые могут на нее повлиять. Я добавляю спрайты «как раз вовремя» и убираю их как можно раньше. Я предпочитаю снова и снова нести затраты на загрузку спрайтов, чем иметь лишний багаж в памяти. Обычно нагрузка возникает в логической «паузе» игры, во время перехода или в каком-либо другом обстоятельстве, которое не будет сдерживающим фактором для игрового процесса. - person YvesLeBorg; 16.05.2012
comment
Спасибо. Чтобы лучше понять... если у вас есть шутер, как бы вы справлялись с повторяющимися врагами? Например. четыре экземпляра одних и тех же космических кораблей могут появиться в начале одной игровой сцены и еще десять могут появиться в конце сцены, вы по-прежнему загружаете и выгружаете или вы создаете максимальное количество спрайтов (например, 10) и модифицируете положение и видимость тех вместо освобождения-перераспределения (утилизация) - person mm24; 17.05.2012
comment
PS: я еще не принял ответ, так как хотел бы посмотреть, есть ли у кого-то такая же проблема с производительностью при использовании 3D-эффектов. - person mm24; 17.05.2012
comment
@YvesLesBorg извините, что потратил время, чтобы принять ответ, я нашел его полезным и помог мне рассуждать о FPS и разобраться в проблеме :). Спасибо! - person mm24; 15.06.2012

Я не уверен, что это та же проблема, но после запуска действия CCShaky3D моя частота кадров упала с 60-50 кадров в секунду до 30-20 кадров в секунду.

Мне только что удалось решить эту проблему, создав последовательность действий с CCShaky3D и CCStopGrid. Последний отвечает за восстановление частоты кадров.

person Jon    schedule 24.01.2013
comment
Это было то, что мне было нужно. Спасибо! - person Bart; 12.12.2013