0

I am creating a game using cocos2dx 2.1.4. Its FPS drops continuously , and never recover. Please find the details as follows

Background about the way I am doing things:- Its game about scrolling down some shapes, each shape is made up of some square blocks.I have 7 kind of blocks. All loaded in a Sprite Sheet and using these blocks from this sprite sheet I create a shape. A level file is consist of these shapes. I load two levels at the same time one onscreen and another off screen to make it seamless scrolling. For loading two levels at the same time I used two different CCSprite game batch nodes as :-

  CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile("56blackglow.plist");
_gameBatchNode1 = CCSpriteBatchNode::create("56blackglow.png", 200);
_gameBatchNode1->retain();
this->addChild(_gameBatchNode1,kForeground);

_gameBatchNode2= CCSpriteBatchNode::create("56blackglow.png", 200);
   _gameBatchNode2->retain();
    this->addChild(_gameBatchNode2,kForeground);

The problem I am facing is that as I keep on playing the game frame rate drops continuously , from 60 fps till 10 fps and never recovers or might recover in near future , as I observed for 20 minutes but its too much time to wait.

My observations:-

1> I used Time profiler it shows maximum time is in draw() calls. Also if I play game very fast the peak of time increases in track, that should be fine as I am giving more work to do, but once a peak is attained it remains approximately at that height only, even if I leave the game Idle. Is it normal ? According to me it should have returned to its normal peak once the current work is done.

2> Some where I thought its happening because I used two batch nodes and removing its children on a user touch immediately might causing it slow but then after removing the children it should run normal. to give an idea is it ok to remove 10 children from batch node immediately ? some guys say its very slow process. Just to check if this causing problem , I did :-

Instead of removing them I just set visibility of the children to false.But still FPS drops and never recovers.

Please share your thoughts on this.

Eklavyaa
  • 370
  • 5
  • 17

2 Answers2

0

Though SpriteBatchNodes are generally quite good for drawing a lot of elements efficiently, I think there are best used for static/not-so-dynamic elements. In your case, if you have a lot of elements which go out of the screen but are still alive the draw() function will have to make some checks, thus hogging your performance (even if you set isVisible(false); explicitly, it still nedds to be checked).

In your case I think it would be better if you simply added new shapes outside of screen via some time-based function, and if they scroll outside of view simply remove them from scene, without using batchNodes.

Losiowaty
  • 7,911
  • 2
  • 32
  • 47
  • I am on it , so i will be adding the blocks using CCSprite::create(). also does FPS drops if memory leaks? Is there any relation between two? – Eklavyaa Oct 22 '13 at 09:46
  • I just realised,whole idea of using the batch node was to scroll all shapes at same time with just batch node scroll, If I don't use batch node then I will have to scroll each of the shapes individually which is tedious. So I have to use batch node, to check your suggestion I will have to change lots of code. – Eklavyaa Oct 22 '13 at 10:01
  • Well, you can add them to a separate CCLayer, and scroll this one. But then it would be tedious to calculate correct position to spawn your elements. Have you considered using CCMoveTo/CCMoveBy? Plus, writing your own update function to move your blocks is not such a hard task, Plus, you will have time control, which will enable you to give same experience for different FPS. – Losiowaty Oct 22 '13 at 10:06
0

Just found that with every touch, I am adding 8 new sprites to the layer, and its adding every time I touch . So with time I am giving more and more work to do. This is the problem

Actually I wanted to replace the sprite at 8 places with a touch, the way I was doing every time :-

_colorBottom1=CCSprite::createWithSpriteFrameName(png[0]);
    this->addChild(_colorBottom1,kForeground);
    _colorBottom1->setPosition(ccp((_colorPanelLeftPad)*_blockWidth,_blockWidth));

It was causing this sprite to be added with every touch.

but it should have been (Replace the texture instead of creating the Sprite again):-

CCSpriteFrame *frame1=CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(png0);
_colorBottom1->setDisplayFrame(frame1);
Eklavyaa
  • 370
  • 5
  • 17