特定のスプライトすべて削除する
最近 Cocos2d-x で2Dゲームを作ってます。
スプライトに名前つけて追加したあと、その名前のスプライトを検索して削除する時にハマったのでメモです(Cocos2d-x のバージョンは3.3です)。
まずはダメなコードから
bool HalloWorldScene::init() { // nameという名前で大量にスプライトを追加する for (int i = 0; i < 100; i++) { auto sprite = Sprite::create("hoge.png"); this->addChild(sprite, 0, "hoge"); } // タッチイベント auto listener = EventListenerTouchOneByOne::create(); listener->onTouchBegan = CC_CALLBACK_2(HelloWorld::onTouchBegan, this); auto dip = this->getEventDispatcher(); dip->addEventListenerWithSceneGraphPriority(listener, this); dip->setPriority(listener, 0); } bool HelloWorld::onTouchBegan(Touch* touch, Event* event) { // だめ。たまに消えないスプライトがある for (auto node : this->getChildren()) { if (node->getName() == "hoge") { node->removeFromParent(); } } // 以下もダメ this->enumerateChildren("hoge", [](Node *node) -> bool { node->removeFromParent(); return false; }); return true; }
以下がうまく行ったコードです(initの処理は同じなので省略してます)。
bool HelloWorld::onTouchBegan(Touch* touch, Event* event) { // nameという名前のスプライトを検索する this->enumerateChildren("hoge", [](Node *node) -> bool { // スプライトを削除するアクション auto action = RemoveSelf::create(); node->runAction(action); return false; }); return true; }
RemoveSelf アクションは結構使いどころが多くて重宝してます。その他にも特定のアクションを実行されてからスプライトを削除する時なんかに使ってます。例えばこんな感じです。
bool HelloWorld::onTouchBegan(Touch* touch, Event* event) { auto sprite = Sprite::create("hoge.png"); this->addChild(sprite, 0, "hoge"); auto moveTo = MoveTo::create(1, Vec2(100, 100)); auto seq = Sequence::create(moveTo, RemoveSelf::create(), NULL); sprite->runAction(seq); }
パーティクルを作成するときなんかに使えます。