Search code examples
iphoneioscocos2d-iphoneframe-rateccsprite

FPS (Frames per second) drop when many objects created


I'm making my first game based on Ray Wenderlich's tutorial. When I try to add 50 enemies to the screen in total. The fps drops to around 45 per second instead of 60. Could you guys tell me why?

-(void)createObjectOfType:(GameObjectType)objectType
           withHealth:(int)initialHealth 
           atLocation:(CGPoint)spawnLocation 
           withZValue:(int)ZValue               {

if (objectType == kEnemyTypeEvil) {

    Evil *evil = [[Evil alloc] initWithSpriteFrameName:@"evil_1.png"];
    [evil setCharacterHealth:initialHealth];
    [evil setPosition:spawnLocation];
    [objectBatchNode addChild:evil z:ZValue tag:kEvilTagValue];
    [evil setDelegate:self];
    [evil release];
}
else if (objectType == kEnemyTypeGhost){

    Ghost *ghost = [[Banana alloc] initWithSpriteFrameName:@"Ghost.png"];
    [ghost setCharacterHealth:initialHealth];
    [ghost setPosition:spawnLocation];
    [objectBatchNode addChild:ghost z:ZValue tag:kGhostTagValue];
    [ghost setDelegate:self];
    [ghost release];
}
}

And then the following method will be scheduled at a 0.5s interval to add the enemies to the screen one by one. The maximum number of enemies in the screen is 50, which is far from a lot (I guess).

-(void)addStage1Enemies{
CGSize levelSize = [[GameManager sharedGameManager] getDimensionOfCurrentScene];
int spawnIndex = arc4random() % 4;
float spawnXpos;
float spawnYpos;

if (spawnIndex == 0){
    spawnXpos= arc4random() % (int)(levelSize.width+30.0f) - 15.0f;
    spawnYpos= levelSize.height +15.0f;
}
else if (spawnIndex == 1){
    spawnXpos= levelSize.width + 15.0f;
    spawnYpos= arc4random() % (int)(levelSize.height+30.0f) - 15.0f;
}
else if (spawnIndex == 2){
    spawnXpos= arc4random() % (int)(levelSize.width+30.0f) - 15.0f;
    spawnYpos= -15.0f;
}
else if (spawnIndex ==3){
    spawnXpos = -15.0f;
    spawnYpos = arc4random() % (int)(levelSize.width+30.0f) - 15.0f;
}


int enemyEliminated = [GameManager sharedGameManager].killCount;

if (enemyEliminated <50) {
    if (evilCount<50) {
        [self createObjectOfType:kEnemyTypeEvil
                      withHealth:kEvilHealth
                      atLocation:ccp(spawnXpos,spawnYpos)
                      withZValue:10];
    }
    evilCount++;
}
else if (enemyEliminated <100) {
    evilCount=0;
    if (ghostCount<50) {
        [self createObjectOfType:kEnemyTypeGhost
                      withHealth:kGhostHealth
                      atLocation:ccp(spawnXpos,spawnYpos)
                      withZValue:10];
    }
    ghostCount++;
}



}

Also, the enemies will perform CCMoveTo repeatedly from position to random position. What is the possible reason that causes the drop of the frame rate? And how can I get around with this problem?

I would like to solve this as soon as possible. Thank you very very very much in advance!

------edited-------

I'm running this on an iPhone 4 device.

I have a 1960*1280 pixels large sprite as my background.

Basically in the update loop, I'm updating the all the objects from each of the spritesheets into arrays. Will this be the problem updating all the objects on each frame? But in my case I have only 50 enemies.

CCArray *listOfGameObjects = [objectBatchNode children];
CCArray *listOfGameObjects2 = [objectBatchNode_2 children];
CCArray *listOfGameObjects3 = [objectBatchNode_3 children];
CCArray *listOfBosses = [bossesBatchNode children];
CCArray *listOfBosses2 = [bossesBatchNode_2 children];
CCArray *listOfBosses3 = [bossesBatchNode_3 children];
CCArray *listOfBosses4 = [bossesBatchNode_4 children];


for (GameCharacter *tempChar in listOfGameObjects){
    [tempChar updateStateWithDeltaTime:deltaTime andListOfGameObjects:listOfGameObjects];

}

for (GameCharacter *tempChar in listOfGameObjects2){
    [tempChar update2StateWithDeltaTime:deltaTime andListOfGameObjects:listOfGameObjects2];

}
for (GameCharacter *tempChar in listOfGameObjects3){
    [tempChar update3StateWithDeltaTime:deltaTime andListOfGameObjects:listOfGameObjects3];

}

for (GameCharacter *tempChar in listOfBosses){
    [tempChar updateBossesStateWithDeltaTime:deltaTime andListOfGameObjects:listOfBosses];

}
for (GameCharacter *tempChar in listOfBosses2){
    [tempChar updateBosses2StateWithDeltaTime:deltaTime andListOfGameObjects:listOfBosses2];

}
for (GameCharacter *tempChar in listOfBosses3){
    [tempChar updateBosses3StateWithDeltaTime:deltaTime andListOfGameObjects:listOfBosses3];

}
for (GameCharacter *tempChar in listOfBosses4){
    [tempChar updateBosses4StateWithDeltaTime:deltaTime andListOfGameObjects:listOfBosses4];

}

does this help much?

Thank you guys!!!


Solution

  • Does the FPS go down to 45 forever? Or does it just stutter for a while when adding the enemies? If the later is the case, you might want to create them at the beginning of the scene and them show them or not accordingly.

    I would have to see what you are doing inside all of those updateBossesStateWithDeltaTime to know if it that.

    Try removing part of the code until you know if that was it. For example, strip your enemies class out of everything but the init code (create them, add their sprite to the scene) and see if with just that you get your fps down.

    If just adding them reduce the fps like that, you should try to use spritesheets (if you are not doing so already).

    The huge background could be taking a toll on the fps, try removing it too without touching anything else, to see if that is the cause.