我在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
所在的身体。
我的问题:在其他条件相同的情况下(物理属性等)决定什么是bodyA以及什么是SKPhysicsContact中的bodyB?
答案 0 :(得分:1)
在修补每个SKPhysicsBody
的几个方面(质量,摩擦,categoryBitmask等)后,我确定SKPhysicsContact.bodyA
和SKPhysicsContact.bodyB
之间的确定基于 <当SKPhysicsBody添加到场景时,em>仅
突出差异的一个例子:
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;
}