2017-01-08 5 views
1

У меня есть два разных фиксированных SKPhysicsBody в SKScene. Единственная разница между ними - их categoryBitMask. Один имеет categoryBitMask 512, другой 1024.Как определить тело и тело B в SKPhysicsContact?

static const u_int32_t kWallCategory = 0x1 << 9;   //512 
static const u_int32_t kStructureCategory = 0x1 << 10; //1024 

В моей программе, у меня есть стандартный контакт обработчик вызывается из -(void)didBeginContact:(SKPhysicsContact *)contact, который начинается:

-(void)handleContact:(SKPhysicsContact*)contact { 
    SKPhysicsBody *bodyA = contact.bodyA; 
    SKPhysicsBody *bodyB = contact.bodyB; 
    int type1 = contact.bodyA.categoryBitMask; 
    int type2 = contact.bodyB.categoryBitMask; 

В моей программе, мне нужно, чтобы определить контактного вектора между динамическим телом и одним из двух неподвижных тел. Для того, чтобы сделать это, я получить доступ к свойству contactNormal в SKPhysicsContact

CGVector c = contact.contactNormal; 

То, что я заметил, однако, в том, что контактные векторы были непоследовательными и я решил это потому, что иногда Боде из SKPhysicsContact был неподвижное тело, иногда bodyA было динамическим телом.

Например, когда пуля (динамическое тело) попадает в здание (неподвижное тело) слева, я хочу, чтобы контактный вектор был (-1,0) каждый раз. В настоящее время контактным вектором является иногда (-1,0) (слева), а иногда (1,0) (справа) все в зависимости от того, какой корпус contact.bodyA есть.

Мой вопрос: учитывая, что все остальное равно (свойства физики и т. Д.), Что определяет, что такое bodyA и что является bodyB в SKPhysicsContact?

ответ

1

После того, как мастерить с несколькими аспектами каждого SKPhysicsBody (массы, трения, categoryBitmask, и т.д.), я установил, что определение между SKPhysicsContact.bodyA и SKPhysicsContact.bodyB основан исключительно о том, когда SKPhysicsBody добавляется к сцене

пример подчеркнуть разницу:

SKPhysicsBody *bullet хитов SKPhysicsBody *building слева.

Случай 1: Если *building был добавлен к сцене , прежде чем*bullet, то есть SKPhysicsContact.contactNormal: (-1,0) Поскольку SKPhysicsContact.bodyA является *building, поэтому контакт вектор , где *building в настоящее время контактирует с (то есть слева).

Случай 2: Если *building был добавлен к сцене после*bullet, то SKPhysicsContact.contactNormal является: (1,0) Поскольку SKPhysicsContact.bodyA теперь *bullet, поэтому контакт вектор , где *bullet идет в контакт с (т.е. справа).

Проблема

Поскольку *bullet и *building объекты добавляются в разное время в моей программе, мне нужно реализовать метод, в котором я всегда знал, что SKPhysicsContact.bodyA и SKPhysicsContact.bodyB были и, что более важно, способ сохранить SKPhysicsContact.contactNormal.

Решение

Определить SKPhysicsBody, что вам нужно, чтобы определить, где столкновения идут из и установить physicsBody.categoryBitMask

static const u_int32_t kProjectileCategory = 0x1 << 1; //Dynamic body 
//Make everything with bitmask > 32 will be set for the fixed bodies 
static const u_int32_t kStructureCategory = 0x1 << 10; //Fixed body 

Затем в контактном обработчика:

-(void)handleContact:(SKPhysicsContact*)contact { 
//bodyA will be the SKPhysicsBody that was added to the SKScene before bodyB 
SKPhysicsBody *bodyA = contact.bodyA; 

//bodyB will be the SKPhysicsBody that was added to the SKScene after bodyA 
SKPhysicsBody *bodyB = contact.bodyB; 

int categoryBitmask1 = contact.bodyA.categoryBitMask; 
int categoryBitmask2 = contact.bodyB.categoryBitMask; 

CGVector v; 

//If the categoryBitmask of bodyA is lower, we will get the contact vector from the Dynamic body, which we don't want 
if (categoryBitmask1 < categoryBitmask2) 
{ 
    //Since we always want the contact vector determined FROM the fixed body (higher category bitmask), we have to get the reciprocal contact vector in the case that bodyA is the dynamic (non-fixed) body 
    v = CGVectorMake(contact.contactNormal.dx * -1, contact.contactNormal.dy * -1); 
} else { 
    //If the categoryBitmask 
    v = contact.contactNormal; 
} 
+1

Это здорово. Ваш вывод о том, что нужно всегда проверять, какое именно тело (при условии, что это важно для того, что делает ваш обработчик контактов), но есть проблема на этом пути: причина всегда проверять не то, что трудно контролировать, какие органы порядка войдите в сцену. Apple не обещает, что тела A и B будут в * любом * детерминированном порядке - вы скорректировали его на порядок создания, но нет никакой гарантии, что это будет одинаково для всех устройств и версий ОС. – rickster

Смежные вопросы