Hi, the physics contact begin callback’s contact shape is the same object with the objects were created several times.
If you want to see what’s happening, look at the gif at the end of this topic
Missile class will get numbered name when they create.
class Missile : public cocos2d:Node
{
....
}
Missile::Missile()
{
static int num;
log("missile Num %d", num);
autorelease();
setName("Missile" + std::to_string(num++));
}
It sets bitmask. It also contacts map, zombie, zombie_pool.
int bitmask = GameObjectBitmask::MAP |
GameObjectBitmask::ZOMBIE |
GameObjectBitmask::ZOMBIE_POOL;
physicsBody->setCategoryBitmask(GameObjectBitmask::MISSILE);
physicsBody->setCollisionBitmask(bitmask);
physicsBody->setContactTestBitmask(bitmask);
Every missile has a contact event. This event belongs to the missile. When the missile hits the map, it generates smoke effect and destroys self by removing from the parent.
void Missile::CreateContactEvent()
{
auto contactListener = EventListenerPhysicsContact::create();
contactListener->onContactBegin = [this](PhysicsContact & contact)->bool
{
auto nodeA{ contact.getShapeA()->getBody()->getNode() };
auto nodeB{ contact.getShapeB()->getBody()->getNode() };
log("This : %s", this->getName().c_str());
log("nodeA : %s", nodeA->getName().c_str());
log("nodeB : %s", nodeB->getName().c_str());
log("Missile Contact Position : %f, %f", this->getPosition().x, this->getPosition().y);
SmokeEffect* smokeEffect{ new SmokeEffect{} };
smokeEffect->CreateSprite();
smokeEffect->CreateAnimation();
smokeEffect->setPosition(this->getPosition());
this->getParent()->addChild(smokeEffect);
this->removeFromParent();
return true;
};
_eventDispatcher->addEventListenerWithSceneGraphPriority(contactListener, this);
}
I added mouse down event to fire the missile in missile’s parent node. It works well.
void GameMode::InitMouseEvent()
{
auto ms_listener = EventListenerMouse::create();
ms_listener->onMouseDown = [this](EventMouse::Event* event)
{
EventMouse* em = dynamic_cast<EventMouse*>(event);
this->FireTheMissile();
};
...
}
Fire the missile function. It allocates new Missile and creates sprite, physics body, contactevent(above code), and set direction, add it to parent. So it will move automatically.
void GameMode::FireTheMissile()
{
Missile* missile{ new Missile{} };
missile->CreateMissileSprite("BlueMissile.png");
missile->CreatePhysicsBody("BlueMissile");
missile->CreateContactEvent();
missile->setPosition(tank->getPosition());
missile->SetDirection(tank->GetAimDirection());
missile->SetVelocity(500.0f);
addChild(missile);
}
So when I mouse-clicked several times, the missiles will be created and move automatically.
When the first missile contacts edge boxed map, it generates the smoke and will be destroyed. But it also generates other missiles’ smokes which are not yet contacted edge box. And also destorys that time.
I have tried to log the missile number, contact shapes’ name, and position.
This : Missile4
nodeA : BattleMap
nodeB : Missile0
Missile Contact Position : 1191.531494, 83.866493
This : Missile3
nodeA : BattleMap
nodeB : Missile0
Missile Contact Position : 1283.183838, 82.511803
This : Missile2
nodeA : BattleMap
nodeB : Missile0
Missile Contact Position : 1358.172119, 81.403419
This : Missile1
nodeA : BattleMap
nodeB : Missile0
Missile Contact Position : 1441.492554, 80.171883
This : Missile0
nodeA : BattleMap
nodeB : Missile0
Missile Contact Position : 1516.480957, 79.063499
The contact shape’s name is not correct. I cloned contact listener, but it also failed.
Do I miss some concept of physics event?
gif for missile contacting map.