Как проверить наличие определенных коллизий в cocos2d-x v3.1? Переполнение стека

Я пытаюсь проверить наличие определенных столкновений между спрайтами с физическими телами. Проблема в том, что я не знаю, как назначить тег для каждого физического тела узла или правильно установить битовую маску для каждого спрайта. Я успешно проверяю наличие столкновений, но это только true или false для всех объектов.

Я следую руководству в документации по cocos2d-x, которое я связал ниже. В нем объясняется, как установить биты маскирования и категории маскирования.

Фильтрация столкновений позволяет предотвратить столкновения между фигурами. Cocos2d-x> поддерживает фильтрацию коллизий, используя битовые маски категорий и групп.

Cocos2d-x поддерживает 32 категории столкновений. Для каждой фигуры вы можете указать, к какой категории она относится. Вы также указываете, с какими другими категориями может сталкиваться эта форма. Это сделано с битами маскировки

Проблема в том, что когда я установил:

sprite1->getPhysicsBody()->setCategoryBitmask(0x02); // 0010
sprite1->getPhysicsBody()->setCollisionBitmask(0x01); // 0001

Там не обнаружение столкновений для этих спрайтов. Но когда я установил:

invaderPhysicsBody->setContactTestBitmask(true);

Там является обнаружение столкновения.

Кто-нибудь знает, как успешно установить битовую маску коллизии или битовую маску категории?

Объекты с возможными столкновениями:

  1. Вектор спрайтов для захватчиков.
  2. Вектор игрока ракеты
  3. Вектор ракет-захватчиков
  4. Спрайт для игрока
  5. Четыре спрайта для щитов

Это моя функция onContactBegin, которая удалит Node после их столкновения. Здесь я должен проверить, какие объекты столкнулись.

bool Gameplay::onContactBegin(PhysicsContact &contact) {
std::cout << "onContactBegin -------> " << std::endl;
player_score += 10;

auto nodeA = contact.getShapeA()->getBody()->getNode();
auto nodeB = contact.getShapeB()->getBody()->getNode();

std::cout << contact.getShapeA()->getTag() << std::endl;

if ((contact.getShapeA()->getCategoryBitmask() & contact.getShapeB()->getCollisionBitmask()) == 0
|| (contact.getShapeB()->getCategoryBitmask() & contact.getShapeA()->getCollisionBitmask()) == 0)
{
std::cout << "Overlap!" << std::endl;
}
nodeA->removeFromParent();
nodeB->removeFromParent();

return true;
}

Вот мой слушатель столкновений:

 // Enable collision listener.
auto contactListener = EventListenerPhysicsContact::create();
contactListener->onContactBegin = CC_CALLBACK_1(Gameplay::onContactBegin, this);
this->getEventDispatcher()->addEventListenerWithSceneGraphPriority(contactListener, this);

Вот как я сейчас создаю и устанавливаю физические тела для своих спрайтов:

int spacing = 0;
// Four Player Shields
for (int i = 0; i < 4; i++) {auto shield = Sprite::create("player_shield.png");

auto shield_x = shield->getContentSize();
auto shield_y = shield->getContentSize();
auto shieldPhysicsBody = PhysicsBody::createBox(Size(shield_x.width,shield_y.height), PHYSICSBODY_MATERIAL_DEFAULT);

shieldPhysicsBody->setContactTestBitmask(true);
shieldPhysicsBody->setDynamic(true);
shieldPhysicsBody->setTag(0);

shield->setPosition(Vec2(200 + spacing, 150));

shield->addComponent(shieldPhysicsBody);
this->addChild(shield);
spacing += 200;
}

Вот руководство, за которым я следовал.

0

Решение

В вашем коде есть большая ошибка. setContactTestBitmask принять int скорее, чем bool, Когда вы звоните shieldPhysicsBody->setContactTestBitmask(true)это на самом деле shieldPhysicsBody->setContactTestBitmask(0x0000001), А также 0x000001 & 0x000010 = 0так что никакое контактное событие не будет инициировано. & Результат categoryBitmask для spriteA и ContactTestBitmask для spriteB определяет, будет ли вызвано событие контакта. Кстати, вообще говоря, вам не нужно проверять контакт вручную, то есть:

if ((contact.getShapeA()->getCategoryBitmask() & contact.getShapeB()->getCollisionBitmask()) == 0
|| (contact.getShapeB()->getCategoryBitmask() & contact.getShapeA()->getCollisionBitmask()) == 0)
{
std::cout << "Overlap!" << std::endl;
}
1

Другие решения

Других решений пока нет …