2016-03-07 3 views
0

Я пытаюсь проверить конкретные столкновения между спрайтами с физическими телами. Проблема в том, что я не знаю, как назначить либо тег для физического тела каждого узла, либо установить битбакс столкновения правильно для каждого спрайта. Я успешно проверяю наличие коллизий, но это только истина или ложь для всех объектов.Как проверить конкретные столкновения в cocos2d-x v3.1? C++

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

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

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

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

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

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

invaderPhysicsBody->setContactTestBitmask(true);

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

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

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

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

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

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); 

Это, как я в настоящее время создать и установить Physics тела для моих спрайтов:

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; 
    } 

Here is the guide I've been following.

ответ

1

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

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