2017-01-08 25 views
1

我在SKScene中有两个不同的固定SKPhysicsBody。两者之间唯一的区别是他们的categoryBitMask。其中有512 categoryBitMask,其他1024SKPhysicsContact中bodyA和bodyB是如何确定的?

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; 

在我的计划,我需要确定动态物体与两个固定物体之一之间的接触矢量。为了做到这一点,我访问SKPhysicsContact

CGVector c = contact.contactNormal; 

我注意到什么的contactNormal财产,虽然是接触载体是不一致的,我确定这是因为有时SKPhysicsContact的bodyA是定身,有时bodyA是动态的身体。

例如,当子弹(动体)从左侧撞击建筑物(固定体)时,我希望每次接触向量为(-1,0)。目前,接触矢量有时是(-1,0)(从左边),有时是(1,0)(从右边),全部取决于哪个主体contact.bodyA是。

我的问题:给定所有其他条件相同(物理属性等)什么决定什么是bodyA和什么是bodyB在SKPhysicsContact?

回答

1

每个SKPhysicsBody(质量,​​摩擦,categoryBitmask等)的几个方面修修补补之后,我确定,SKPhysicsContact.bodyASKPhysicsContact.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.bodyASKPhysicsContact.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

这非常棒。你的结论是,应该总是测试哪个主体是哪个主体(假设它对你的联系处理程序来说很重要),但是一直存在一个问题:总是测试的原因并不是控制什么顺序主体进入该场景。苹果公司并未承诺机构A和B将以*任何确定性顺序 - 您已将其与创建顺序关联起来,但无法保证在所有设备和操作系统版本中都是相同的。 – rickster

相关问题