performance problem using particles

Hi there,

I’m developing a game with cocos2dx and I use particles when player collides with other objects. For example, the player is running and he has to get the coins in the level, so when player collides with any coin I want to throw some particles effect.
What is the best way to do it? I use the next code and I notice some performance problems when the particles are comming up.
The activateParticles function is called when the player collides with a coin sprite.

`void GamePlayLayer::activateParticles(int tagObject, CCPoint position)
{
switch (tagObject) {
case COIN:

        m_emitter = CCParticleSystemQuad::create("BigGoldCoinPickupParticle01.plist");
        m_emitter->setPosition(position);
        this->addChild(m_emitter);

        break;

    default:
        break;
}

}`

Thank you in advance!

Yep, the particle system does give a big performance hit especially on older hardware. Considering what you are using it for I would suggest just writing your own routine and use a bunch of sprites.

Gav T wrote:

Yep, the particle system does give a big performance hit especially on older hardware. Considering what you are using it for I would suggest just writing your own routine and use a bunch of sprites.

Could you tell us what is “your own routine” and why performance gains with a bunch of sprites

Well,
My game is a Cocos2dx with box2d. Any of you knows if there is performance problem when using system particles in a project like this?

Do you know any way to have no performance problems or do I have to use a bunch of sprites?

Thanks!

Could you tell us what is “your own routine” and why performance gains with a bunch of sprites

Well OK.

First, take a look at the particle system, trace into it in the debugger and you’ll see how much code is actually running.

By “a bunch of sprite” I would suggest something like the routine below which is what I use when my Orb explodes in Arrow Mania (see videos on youtube).
This routine, called for each sprite will throw the sprite across the screen with a bit of artificial gravity, spinning it too…. you could add opacity so it fades
out as it moves, or any other effect. Have ten of these sprites going in different directions and you’ll end up with a nice effect.

Note I use my own floats and the delta value to do my movements and animations, I’m old school and just don’t want to use the CCAnimation class in Cocos2D-X but you can if you want to (it is very good, I just don’t).

The code for one/two pieces of my Orb exploding being as follows:-

Setup values (use different X Y values for different initial directions).

        float m_fVal[6];

        memset(&m_fVal, 0, sizeof(float)*6);
        m_fVal[0] = -5;          // X speed
        m_fVal[1] = 7.5;         // Y speed
        m_fVal[2] = 0.05;        // X decelerate speed start val, slows/decreases to 0
        m_fVal[3] = 0.2;         // Y decelerate speed start value, ends up at -8 max
        m_fVal[4] = -15;          // Rotation

The code that you call each frame to move the sprite. The sprites position is the “CCPoint m_Pos”. m_sprMain is the sprite.

        m_Pos.x += m_fVal[0]*delta;
        m_Pos.y += m_fVal[1]*delta;
        //m_pVal.x -= m_fVal[0]*delta;
        //m_pVal.y += m_fVal[1]*delta;

        if( m_fVal[0] > 0 )
        {
            m_fVal[0] -= m_fVal[2]*delta;
            if( m_fVal[0] < 0 )
                m_fVal[0] = 0;
        }
        if( m_fVal[0] < 0 )
        {
            m_fVal[0] += m_fVal[2]*delta;
            if( m_fVal[0] > 0 )
                m_fVal[0] = 0;
        }
        if( m_fVal[1] > -8 )
        {
            m_fVal[1] -= m_fVal[3]*delta;
            if( m_fVal[1] < -8 )
                m_fVal[1] = -8;
        }

        m_fVal[5] += m_fVal[4]*delta;
        m_sprMain->setRotation(m_fVal[5]);
        m_sprMain->setPosition( m_Pos);

        // Note is you have a child sprite of the main sprite and position it opposite of that one (i.e. one 
        // goes left in an arc, one goes right in an arc), then you can do 1 position calculation for two sprites 
        // saving time. Use the two lines below to position your child sprite. And uncomment the two m_pVal 
        // lines above (m_pVal is a CCPoint too). 
        //m_sprChild->setPosition(m_pVal);
        //m_sprChild->setRotation(-m_fVal[5]);

        if(  )
            ;
        break;

So, compare that to the code that gets run for the particle system and you’ll see its just a fraction of it.

Hope that helps.

*edit - forgot to paste in initial values for m_fVal[2] m_fVal[3] above.

Hi!
finally i get working with no performance problems.
this is my code:

void GamePlayLayer::activateParticles(int tagObject, CCPoint position)
{

switch (tagObject) {
case COIN:
Current_m_emitter = coinsParticlesSystemContainer[particleSystemIndex];
Current_m_emitter~~>setPosition;
Current_m_emitter~~>resetSystem();
particleSystemIndex ++;
if(particleSystemIndex==MAX_SYSTEM_PARTICLES_COINS)particleSystemIndex =0;
break;
default:
break;
}
}

void GamePlayLayer::initParticlesSystems()
{
batchNode = new CCParticleBatchNode();
batchNode~~>initWithTexture;
addChild;
particleSystemIndex = 0;
for
{
Coins_m_emitter = CCParticleSystemQuad::create;
Coins_m_emitter~~>setPosition(CCPointZero);
Coins_m_emitter~~>stopSystem;
coinsParticlesSystemContainer.push_back;
batchNode~~>setTexture(Coins_m_emitter~~>getTexture);
batchNode~~>addChild(Coins_m_emitter);
}
}

The idea is to initilize some “CCParticlesSystemQuad” at the begining and saving them in a vector, then, when you have the collision you can call to resetSystem.

Hope that helps.

Thanks!

Hi Roger,

I have used your method saving some particles into a vector and it works fine. Now my doubt:

I have created the vector with the particles in a static class and it is accessed from my game class, it works fine except if the game goes to background and comes to foreground later, the particles are not showed never and when they should be showed the framerate goes down.

Does anyone have this problem? Does anyone have some clue why it is happening?

This is happening in Android.

Thank you