Search code examples
c++cocos2d-x

Schedulling respawn returns error in collision detection


I'm trying to schedule a sprite respawn at each 2 seconds and I also have a method that verifies every frame for a collision between the sprite that is generate at each 2 seconds, and the player sprite. But I'm getting an error, because the sprite that is respawned is removed after running all screen. If I don't remove it, the collision detection method works, otherwise no.

This is the error message that I get:

EXD_BAD_ACCESS

This is the method that verifies the collision:

void HelloWorld::collisionMiniBarrier(float dt)
{

    CCSprite *pPlayer = (CCSprite*)getChildByTag(kPlayer);
    CCSprite *pMiniBarrier = (CCSprite*)getChildByTag(kMiniBarrier);
    CCRect playerRect   = CCRectMake(pPlayer->getPositionX(),pPlayer->getPositionY(),100,100);
    CCRect tankRect     = CCRectMake(pMiniBarrier->getPositionX(),pMiniBarrier->getPositionY(),100,100);

    if(playerRect.intersectsRect(tankRect))
    {
        CCLog ("Hallalua");
    }
    else
    {
        CCLog("Not Intersected");
    }

}

This is how I'm generating the sprite respawned every 2 seconds:

void HelloWorld::addMiniBarrier(float dt) {
    CCLog("game state %d", gameState);
    Y1 = visibleSize.height*.7;
    Y2 = visibleSize.height*.5;
    Y3 = visibleSize.height*.3;
    X1 = visibleSize.width*.25;
    float Y;


    int randPos = rand() % 3 +1;

    if (randPos == 1) {
        Y = Y1;
    } else if (randPos == 2) {
        Y = Y2;
    } else if (randPos == 3) {
        Y = Y3;
    }

    if (gameState == 1) {

        miniBarrier = Sprite::create("hero-1.png");
        miniBarrier->setPosition(Point(visibleSize.width + miniBarrier->getContentSize().width, Y));
        miniBarrier->setTag(kMiniBarrier);


        this->addChild(miniBarrier, 1, kMiniBarrier);

        float x1 = miniBarrier->getContentSize().width;



        // Create the actions

        auto actions = Sequence::create(
                    MoveTo::create(2, Point(-x1, Y)),
                    RemoveSelf::create(),
                                        NULL);
        miniBarrier->runAction(actions);


    }

}

And this is how I'm schedulling these selectors:

  this->schedule(schedule_selector(HelloWorld::addMiniBarrier),2 );
    this->schedule(schedule_selector(HelloWorld::collisionMiniBarrier) );

Solution

  • Here you have scheduled addMiniBarrier for 2 seconds and collisionMiniBarrier get calls each time. Sprite removes itself after it's actions. So there won't be any view which has tag of kMiniBarrier for certain interval of time. So when you collect child using tag just make sure whether it is NULL or not

    if (pMiniBarrier) { // Your collision detect code. }