EDIT2: In response to the answer below I did create a different GameScene for testing the framerate performance with 4 sprites animated by a CCShaky3D effect. The problem still persist as the fps is still around ~15fps. I paste the code at the end of this question to facilitate reading. My assumption is that is due to the fact that I am running more than one CCShaky3D at the same time. Is anyone able to run multiple CCShaky3D effects at the same time without frame rate drop?
I introduced Effects (cocos2d programming guide) from cocos2d in my game and noticed that the FPS drammatically slow down. From 60fps to ~10fps once the sprite on which I apply the effect appear.
I had introduced them in my game at first and had the black background problem (as in post so post). I followed the solution and the problem was solved.
I noticed in the debugger that once the fourth sprite to which I apply the animation appears the Application receives memory warning. The frame rate drops as soon as the second sprite to which I apply the Effect becomes visible. In the scene I have already other 2-3 enemy sprites in the screen at the same time plus the player sprite and I guess this might be a memory issue. I then tried to add only one sprite with animation and the remaining 2-3 enemy sprites are still there and the frame rate drops "only" to ~45 fps.
EDIT: When I don't apply the effect to those sprites the frame rate doesn't change (stays ~60fps).
I guess this is due on how I manage my memory but before changing drammatically the code I wanted to gather some opinion on this. Do you manage to run a scene with eg. 2-3 sprites with an effect and 4-5 other sprite (e.g. enemies and player) moving around?
Initializing EAGLView properly:
As to get the Effects running I had to modify EAGLView initialization I post this here as I think might be ralated. I am very unfamiliar with UIViewController and EAGLView initialization and I am wondering if I am doing something wrong on it and if this could affect the framerate.
I modified the ShootEmUp example from Learn iPhone and iPad cocos2d chapter 8 source code and noticed that in the example's AppDelegate there is no RootViewController instance. Instead in Coco2d Cookbook a RootViewController is used in the AppDelegate as well as in any template that I create using Cocos2d. In my code I modified the CC_DIRECTOR_INIT() macro adding the initialization of EAGLView as suggested in post 2.
I found this official cocos2d guide which says that there is no need to create UIViewController in a cocos2d application which confirms the approach in ShootEmUp example (3). As I am still unfamiliar with the roles of CCDirector, EAGLView and UIViewController I'd like to ask for a clarification to the commmunity on how they interact with each other and also if the initialization of any of those can affect the frame rate. Thanks a lot.
EDIT 2 - Source code that I used for testing the CCShaky3D effect effect on fps performance rate :
// 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;
}