Collision Detection Problem

I needed a time-independent spawn system. So I decided to use collision detection. I added Physics Body to my spawn boxes and added a node to the game screen. When the box contacts the node, a new box is created immediately behind it, and the same process is repeated when the newly formed box contacts the node. However, the collision detection code I wrote does not work properly. Sometimes it doesn’t detect collision. Sometimes it works properly. Sometimes it also doesn’t detect the collision’s re-running after working properly for a while. Where is the problem and how can i solve it?

Codes:

 spawnNode = Node::create();
 spawnNode->setTag(SPAWN_TAG);
 auto spawnBody = PhysicsBody::createBox(Size(1, visibleSize.height), PhysicsMaterial(0, 1, 0));
 spawnBody->setCollisionBitmask(GAME_SPAWN_TRIGGER);
 spawnBody->setContactTestBitmask(true);
 spawnBody->setDynamic(false);
 spawnNode->setPhysicsBody(spawnBody);
 spawnNode->setPosition(Point(visibleSize.width - spawnerSprite->getContentSize().width, visibleSize.height / 2 + origin.y));

    auto buildingBody = PhysicsBody::createBox(this->getContentSize(), PhysicsMaterial(0, 1, 0));
    buildingBody->setCollisionBitmask(BUILDING_SPAWN_TRIGGER);
    buildingBody->setContactTestBitmask(true);
    buildingBody->setDynamic(false);
    this->setPhysicsBody(buildingBody);

bool HelloWorld::onSpawnContactBegin(cocos2d::PhysicsContact &spawnContact)
{
    PhysicsBody* a = spawnContact.getShapeA()->getBody();
    PhysicsBody* b = spawnContact.getShapeB()->getBody();
    if(a->getCollisionBitmask() == BUILDING_SPAWN_TRIGGER && b->getCollisionBitmask() == GAME_SPAWN_TRIGGER || a->getCollisionBitmask() == GAME_SPAWN_TRIGGER && b->getCollisionBitmask() == BUILDING_SPAWN_TRIGGER)
    {
        generateBuildings();
    }

    return true;
}

Show us how you create your listeners for the contact events.

auto spawnContactListener = EventListenerPhysicsContact::create();
    spawnContactListener->onContactBegin = CC_CALLBACK_1(HelloWorld::onSpawnContactBegin, this);
    _eventDispatcher->addEventListenerWithSceneGraphPriority(spawnContactListener, this);

This syntax does not seem correct for an if((A && B) || (C && D))… ie, you need to place each complete boolean inside a parenthesis in the AND OR case… (this honestly should trigger a compile error in some IDEs)

if((a->getCollisionBitmask() == BUILDING_SPAWN_TRIGGER && b->getCollisionBitmask() == GAME_SPAWN_TRIGGER) || (a->getCollisionBitmask() == GAME_SPAWN_TRIGGER && b->getCollisionBitmask() == BUILDING_SPAWN_TRIGGER))

1 Like

I found the mistake, but I have no idea why. Apparently objects are spawn on the left side and not on the right side of the screen.