1

我在 SKScene 中有两个不同的固定 SKPhysicsBody。两者之间的唯一区别是它们的 categoryBitMask。一个的 categoryBitMask 为 512,另一个为 1024。

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 的 contactNormal 属性

CGVector c = contact.contactNormal;

不过,我注意到接触向量不一致,我确定这是因为有时 SKPhysicsContact 的 bodyA 是固定体,有时 bodyA 是动态体。

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

我的问题:假设所有其他条件都相同(物理属性等),什么决定了 SKPhysicsContact 中的 bodyA 和 bodyB 是什么?

4

1 回答 1

2

在修补了每个方面的几个方面SKPhysicsBody(质量、摩擦、categoryBitmask 等)之后,我确定SKPhysicsContact.bodyA和之间的确定SKPhysicsContact.bodyB基于SKPhysicsBody 何时添加到场景中

突出差异的示例:

SKPhysicsBody *bulletSKPhysicsBody *building从左边击中。

案例1:如果之前*building被添加到场景 *bullet,则SKPhysicsContact.contactNormalis:(-1,0) 因为SKPhysicsContact.bodyA*building,所以接触向量是从哪里*building接触到的(即左边)

情况2:如果*building在之后添加到场景 *bulletSKPhysicsContact.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;
}
于 2017-01-08T21:49:54.880 回答