Best way to remove a sprite with vector or layers.

  • koko82
    Likes 1

    Problem Description

    Just running into some trouble with timers and vectors, when I am running an animation or
    deleting a vector or recreating a vector sometimes a clash can happen and cause a crash
    as either animation running or scheduled update. I have done some simple checks 
    getnumberofrunninganimations etc but distrupts the game play flow.

    So wandering if I can pre-create the 3 vector elements and then just addchild and remove
    child and adjust some of the settings (sprite & physics). However when I try create
    all there vectors 

    this->addchild(vector.at(0));
    this->addchild(vector.at(1));
    this->addchild(vector.at(2));

    It errors saying child already added but if I just do one, ie this->addchild(vector.at(0));
    it works fine. But also not sure on the process of removing layer?

    Be helpful to know if

    a) adding and removing vector (pushBack & popBack) is the best way to add and remove sprites
    b) If its better to have 3 vectors established before gameplay and add/remove child elements
    and minipulate elements within vector.
    c) If b is the best way, what specific syntax should I be using with vector elements to add/remove 
    child from layer.

  • Sonar Systems admin
    Likes 0

    First question is why are you’re using Vectors, nothing wrong with it just want to understand what you are trying to achieve.

  • koko82
    Likes 1

    So sprites appear and disappear, but eventually the number of sprites will get larger as levels progress, also making sprites unique by taging them. So thought Vector might be best solution to store sprites. Or should I use something else, should I not use vector, I am new so trying to understand best practise. 

  • koko82
    Likes 1

    the physics body is also stored with sprite..

  • Sonar Systems admin
    Likes 0

    Could you show us more code regarding declaring, initialising and adding them to the vector.

  • koko82
    Likes 1

    in .h
    vector<Sprite*> _Sprites;
    
    init() 
    {
    
    vector<Sprite*> _Sprites;
    
    int random = rand() % 5;
    
    auto sprite = Sprite::create("aSprite.png");
    auto physicsBody = PhysicsBody::createBox(Size(65.0f , 81.0f ), PhysicsMaterial(0.1f, 1.0f, 0.0f));
    sprite->setTag(random);
    sprite->setPosition(cocos2d::Point((60 * random), (50 * random)));
    physicsBody->setDynamic(false);
    sprite->setPhysicsBody(physicsBody);
    
    _Sprites.pushBack(sprite);
    _Sprites.pushBack(sprite);
    _Sprites.pushBack(sprite);
    
    }
    
    AnotherFunction
    {
    this->addchild(_Sprites.at(0));
    this->addchild(_Sprites.at(1));
    this->addchild(_Sprites.at(2));
    }
    

     

  • koko82
    Likes 1

    This crashes in another function

    {
    this->addchild(_Sprites.at(0));
    this->addchild(_Sprites.at(1));
    this->addchild(_Sprites.at(2));
    }

    but this works fine if you only add one.

     

    {
    this->addchild(_Sprites.at(1));
    }

     

  • Sonar Systems admin
    Likes 0

    init() 
    {
    
    vector<Sprite*> _Sprites;
    
    int random = rand() % 5;
    for (int i = 0; i < 3; i++)
    {
    auto sprite = Sprite::create("aSprite.png");
    auto physicsBody = PhysicsBody::createBox(Size(65.0f , 81.0f ), PhysicsMaterial(0.1f, 1.0f, 0.0f));
    sprite->setTag(random);
    sprite->setPosition(cocos2d::Point((60 * random), (50 * random)));
    physicsBody->setDynamic(false);
    sprite->setPhysicsBody(physicsBody);
    
    _Sprites.pushBack(sprite);
    }
    
    }

    Use that code instead as you are only creating a single sprite and adding it. You can only add a sprite once to the scene.

  • koko82
    Likes 0

    But if its mulitple vectors each with a essentially ‘copy’ of the sprite wouldnt it be enough to differenciate it. The code above just loops it rather than manual pushback. So unsure of the difference it would make when adding it.

  • Sonar Systems admin
    Likes 0

    Your are pushing the same sprite, even though you have a vector of sprites they are the same single sprite, hence something like a loop is need.

  • koko82
    Likes 0

    Why would a loop make a difference as it looks esentially same thing? Or would I need to use a copy of those same sprites?

    Wouldnt this differenciate it more if we put (i) on each element?

    init() 
    {
    
    vector<Sprite*> _Sprites;
    
    int random = rand() % 5;
    for (int i = 0; i < 3; i++)
    {
    auto sprite(i) = Sprite::create("aSprite.png");
    auto physicsBody(i) = PhysicsBody::createBox(Size(65.0f , 81.0f ), PhysicsMaterial(0.1f, 1.0f, 0.0f));
    sprite(i)->setTag(random);
    sprite(i)->setPosition(cocos2d::Point((60 * random), (50 * random)));
    physicsBody(i)->setDynamic(false);
    sprite(i)->setPhysicsBody(physicsBody(i));
    
    _Sprites.pushBack(sprite(i));
    }
    
    }

     

  • Sonar Systems admin
    Likes 0

    In each loop iteration it creates a whole new sprite even though the name is the same.

  • koko82
    Likes 1

    The penny dropped :) many thanks for your help! Its working however some problems with random which I need to research.

    Which is the best way of removing from layer then adding again? Do I have to use a method call sprite->retain()?

  • Sonar Systems admin
    Likes 0

    No retain required, use this->removeChild(nodeToBeRemoved); and add using this->addChild(nodeToBeAdded);

  • koko82
    Likes 0

    Also how do you know if a particular element is added to layer?

  • Sonar Systems admin
    Likes 0

    Honestly, don’t know.

Login to reply