SpriteKit - 确定A方碰撞的A方

时间:2015-01-07 22:51:03

标签: ios collision-detection sprite

因此对于我正在研究的App,我有两个立方体碰撞。我以标准方式检查这个。该应用程序告诉我他们何时在我的“didBeginContact”方法中发生碰撞。

-(void)didBeginContact:(SKPhysicsContact *)contact {
    if (contact.bodyA.categoryBitMask == WALL_CATEGORY && contact.bodyB.categoryBitMask == CHARACTER_CATEGORY) {
        CGPoint point = contact.contactPoint;
    }
}

所以我知道碰撞发生在哪里,但因为它是两个正方形,所以它可以在包括角落在内的任何一点。那么我该如何检查左/右/上/下的碰撞?

编辑:正确答案:可能不是最干净的方法,但它有效。希望它能帮助将来的某个人。

m_lNode = [SKNode node];
m_lNode.position = CGPointMake(-(CHARACTER_SIZE / 2), 0);
m_lNode.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(1, m_character.size.height)];
m_lNode.physicsBody.allowsRotation = NO;
m_lNode.physicsBody.usesPreciseCollisionDetection = YES;
m_lNode.physicsBody.categoryBitMask = CHARACTER_L_CATEGORY;

m_rNode = [SKNode node];
m_rNode.position = CGPointMake((CHARACTER_SIZE / 2), 0);
m_rNode.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(1, m_character.size.height)];
m_rNode.physicsBody.allowsRotation = NO;
m_rNode.physicsBody.usesPreciseCollisionDetection = YES;
m_rNode.physicsBody.categoryBitMask = CHARACTER_R_CATEGORY;

m_tNode = [SKNode node];
m_tNode.position = CGPointMake(0, (CHARACTER_SIZE / 2));
m_tNode.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(m_character.size.width , 1)];
m_tNode.physicsBody.allowsRotation = NO;
m_tNode.physicsBody.usesPreciseCollisionDetection = YES;
m_tNode.physicsBody.categoryBitMask = CHARACTER_T_CATEGORY;

m_bNode = [SKNode node];
m_bNode.position = CGPointMake(0, -(CHARACTER_SIZE / 2));
m_bNode.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:CGSizeMake(m_character.size.width, 1)];
m_bNode.physicsBody.allowsRotation = NO;
m_bNode.physicsBody.usesPreciseCollisionDetection = YES;
m_bNode.physicsBody.categoryBitMask = CHARACTER_B_CATEGORY;

[m_character addChild:m_tNode];
[m_character addChild:m_bNode];
[m_character addChild:m_lNode];
[m_character addChild:m_rNode];

-(void)didBeginContact:(SKPhysicsContact *)contact {
    if (contact.bodyA.categoryBitMask == WALL_CATEGORY) {
        switch (contact.bodyB.categoryBitMask) {
            case CHARACTER_T_CATEGORY:
                NSLog(@"Top");
                m_isHitTop = true;
                break;
            case CHARACTER_B_CATEGORY:
                NSLog(@"Bottom");
                m_isHitBottom = true;
                break;
            case CHARACTER_L_CATEGORY:
                NSLog(@"Left");
                m_isHitLeft = true;
                break;
            case CHARACTER_R_CATEGORY:
                NSLog(@"Right");
                m_isHitRight = true;
                break;
        }
    }
}

添加了一些相关代码。这是我的代码,所以除了其他东西之外还有变量,但你应该能够弄明白。

2 个答案:

答案 0 :(得分:4)

我认为确定您的联系方式(顶部,左侧,底部,右侧)涉及哪一方的最佳方法是:

  • 计算向上,向下,向左和向右两侧的居中十字留下的点(例如,如果你有一个平方的精灵..)

enter image description here

let halfWidth = self.frame.width/2
let halfHeight = self.frame.height/2
let down = CGPointMake(self.frame.origin.x+halfWidth,self.frame.origin.y)
let up = CGPointMake(self.frame.origin.x+halfWidth,self.frame.origin.y+self.frame.size.height)
let left = CGPointMake(self.frame.origin.x,self.frame.origin.y+halfHeight)
let right = CGPointMake(self.frame.origin.x+self.frame.size.width,self.frame.origin.y+halfHeight)
  • 计算contactPoint与各点之间的距离(向上,向左,向右和向下

这个小功能可以实现这一步:

func getDistance(p1:CGPoint,p2:CGPoint)->CGFloat {
    let xDist = (p2.x - p1.x)
    let yDist = (p2.y - p1.y)
    return CGFloat(sqrt((xDist * xDist) + (yDist * yDist)))
}

之后,计算出的最低距离所涉及的点是最靠近contactPoint的侧点。

此方法的优点是什么

  1. 你不会画僵尸或幽灵节点和相关的物理身体
  2. 此方法也适用于动态可变CGPath,而不仅仅是 知道矩形边界
  3. 快速,几行代码,如果你添加其他几行,你可以 能够确定对角线并使你更精确 算法

答案 1 :(得分:3)

最简单的方法是在正方形的顶部,左侧,右侧和底部添加子精灵。将物理实体添加到那些物理实体中,然后就可以知道物体碰撞的位置。我建议首先尝试使用此方法,除非屏幕上有很多方块。

如果你在屏幕上有大量的方格而你担心表现。然后可以使用contact.contactPoint并将该点转换为方坐标。给定正方形的中心点,正方形旋转的角度和该点,您应该能够分辨出正方形碰撞的位置。这需要一些数学......当第一个可能就是你真正需要的时候,我害怕写出那种解决方案。