Is there a bug with ParticleSystem in 2.0.2?

Hello cocos2d-x guys,

I’m a beginner from WeiFang China and am now learning a tutorial with a Chinese version at http://mssyy2010.blog.51cto.com/4595971/847000 (the corresponding English version being at http://www.raywenderlich.com/4787/how-to-make-a-catapult-shooting-game-with-cocos2d-and-box2d-part-2). I found an ‘Assertion failed’ when I run the Particle system related part of code in the demo. Long to see your help. The details is:

I’m now using the version 2.0.2 of cocos2d-x. Obviously, the demo shown above in C++ is based upon an old release of cocos2d-x, so I updated it in most parts with the newly-recommended stuff in 2.0.2. However, I still come up with the above ‘assertion’ error thrown out. Here is the related code:

`void HelloWorld::tick( float dt )
{
//It is recommended that a fixed time step is used with Box2D for stability
//of the simulation, however, we are using a variable time step here.
//You need to make an informed choice, the following URL is useful
//http://gafferongames.com/game-physics/fix-your-timestep/

int velocityIterations = 8;
int positionIterations = 1;

// Instruct the world to perform a single step of simulation. It is
// generally best to keep the time step and iterations fixed.
m_world->Step(dt, velocityIterations, positionIterations);

//Iterate over the bodies in the physics world
for (b2Body* b = m_world->GetBodyList(); b; b = b->GetNext())
{
    if (b->GetUserData() != NULL) {
        //Synchronize the AtlasSprites position and rotation with the corresponding body
        CCSprite* myActor = (CCSprite*)b->GetUserData();
        myActor->setPosition( CCPointMake( b->GetPosition().x * PTM_RATIO, b->GetPosition().y * PTM_RATIO) );
        myActor->setRotation( -1 * CC_RADIANS_TO_DEGREES(b->GetAngle()) );
    }   
}

// Arm is being released.
if (m_bReleasingArm && m_bulletJoint)
{
    // Check if the arm reached the end so we can return the limits
    if (m_armJoint->GetJointAngle() <= CC_DEGREES_TO_RADIANS(10))
    {
        m_bReleasingArm = false;

        // Destroy joint so the bullet will be free
        m_world->DestroyJoint(m_bulletJoint);
        m_bulletJoint = NULL;

        runAction(CCSequence::actions(CCDelayTime::actionWithDuration(5.0f),
                                      CCCallFunc::actionWithTarget(this, callfunc_selector(HelloWorld::resetBullet)),NULL));
    }
}

// Bullet is moving.
if (m_bulletBody && m_bulletJoint == NULL)
{
    b2Vec2 position = m_bulletBody->GetPosition();
    CCPoint myPosition = getPosition();
    CCSize screenSize = CCDirector::sharedDirector()->getWinSize();

    // Move the camera.
    if (position.x > screenSize.width / 2.0f / PTM_RATIO)
    {
        myPosition.x = -MIN(screenSize.width * 2.0f - screenSize.width, position.x * PTM_RATIO - screenSize.width / 2.0f);
        //getPosition().x = myPosition.x;
        setPosition(myPosition);
        getChildByTag(kTagTileMap)->setPosition(ccp(CCDirector::sharedDirector()->getWinSize().width - 20-myPosition.x, 20));
    }
}

// Check for impacts
std::set<b2Body*>::iterator pos;
for(pos = m_contactListener->contacts.begin(); 
    pos != m_contactListener->contacts.end(); ++pos)
{
    b2Body *body = *pos;

    CCNode *contactNode = (CCNode*)body->GetUserData();
    CCPoint position = contactNode->getPosition();

    removeChild(contactNode, true);
    m_world->DestroyBody(body);

    std::vector<b2Body*>::iterator iter;
    for(iter = m_vectorTargets->begin() ; iter != m_vectorTargets->end() ; ++iter)
    {
        if(*iter == body)
        {
            m_vectorTargets->erase(iter);
            break;
        }
    }

    std::vector<b2Body*>::iterator it;
    for(it = m_vectorEnemies->begin() ; it!=m_vectorEnemies->end() ; ++it)
    {
        if(*it == body)
        {
            m_vectorEnemies->erase(it);
            break;
        }
    }
   // [targets removeObject:[NSValue valueWithPointer:body]];
   // [enemies removeObject:[NSValue valueWithPointer:body]];

    CCParticleSun* explosion = CCParticleSun::create();
  •   explosion->initWithTotalParticles(100);
    
  •   explosion->setTexture(CCTextureCache::sharedTextureCache()->addImage("fire.png"));
    
      explosion->setAutoRemoveOnFinish(true);
    
      explosion->setStartSize(10.0f);
      explosion->setSpeed(70.0f);
      explosion->setAnchorPoint(ccp(0.5f,0.5f));
      explosion->setPosition(position);
      explosion->setDuration(1.0f);
      explosion->retain();
      addChild(explosion, 11);
      explosion->release(); 
    

    }

    // remove everything from the set
    m_contactListener->contacts.clear();
    }
    `

Now, every time when the above code executed to this line:

explosion->initWithTotalParticles(100);

the following exception would be thrown out:

Assertion failed!
Program:…
File:e:……2d….cpp
Line: 447
Expression: pHashElement~~>entry~~>markedForDeletion

For infomation on how your program can cause an assertion failure,……

So, when I pressed “Retry” to track the debug or even re-debug the code, I found preceding error thrown when the above initWithTotalParticles method was invoked. And further, I pressed F11 to track into the method I come to ‘bool CCParticleSystem::initWithTotalParticles(unsigned int numberOfParticles)’. In this method, when ‘this->scheduleUpdateWithPriority(1);’ was executed, the above exception would be triggered!

I googled many times with several keywords but found nearly nothing that can help (I even changed the number of particle to a very small number the same story still took place), so I come here for help. Thanks in advance!

Best regards,

Could you upload the demo which based on cocos2dx 2.0.2 ?

Hello,

I am also seeing strange errors in 2.0.2 with CCParticleSun, and code based off RayWenderlich’s catapult shooter tutorial.

I am executing:
@ CCParticleSun* explosion = CCParticleSun::node();
explosion~~>setTexture~~>addImage);
explosion~~>initWithTotalParticles;
explosion~~>setAutoRemoveOnFinish(true);
explosion~~>setStartSize;
explosion~~>setSpeed(70.0f);
explosion~~>setAnchorPoint);
explosion~~>setPosition(0, 0);//contactNode~~>getSprite~~>getPosition);
explosion~~>setDuration;
explosion~~>retain();
addChild(explosion, 11);
explosion~~>release;@
an error is thrown at “initWithTotalParticles(20)”~~ this was initially 200, but fearing out of memory errors I adjusted it down. Still seeing the same problem.

The stack trace is:
msvcr100d.dll!_wassert(const wchar_t * expr, const wchar_t * filename, unsigned int lineno) Line 325 C
libcocos2d.dll!cocos2d::CCScheduler::scheduleUpdateForTarget(cocos2d::CCObject * pTarget, int nPriority, bool bPaused) Line 447 + 0x29 bytes C*+
libcocos2d.dll!cocos2d::CCNode::scheduleUpdateWithPriority Line 920 C*+
libcocos2d.dll!cocos2d::CCParticleSystem::initWithTotalParticles(unsigned int numberOfParticles) Line 391 C*+
libcocos2d.dll!cocos2d::CCParticleSystemQuad::initWithTotalParticles Line 51* 0xc bytes C*+
libcocos2d.dll!cocos2d::CCParticleSun::initWithTotalParticles Line 175* 0xc bytes C++
Is there a solution?

Would it help if I upgraded to a newer version of cocos2d-x, or are there still problems with the ParticleSystem?