physicsBody与另一个physicsBody碰撞

时间:2015-12-21 17:29:15

标签: xcode swift sprite-kit

好的,所以我有一个非常具体的问题,我希望我能帮到你。我会附上一张图片来澄清我在谈论的内容。

clarification

redball.physicsBody正在boss.physicsBody之上产生 - 堕落(通过)老板。与whitebar.physicsBody发生碰撞 - 反弹并再次与boss.physicsBody发生碰撞。这一次,我想发起一个事件,当球弹回来撞击老板时会注意到。

目前。老板& Ball共享相同的collisionBitMask,以便它们可以相互通过。当球与杆碰撞时,我试图将ball.physicsBody?.contactTestBitMask = PhysicsCategory.boss.rawValue添加到球上。所以我可以注意到球与球之间的反击方式的碰撞老板。然而,这似乎不起作用。

有没有人能解决这个奇怪的问题?非常感谢一些帮助。

旁注:如果有人能找到一个聪明的标题,请告诉我并编辑它!

编辑:添加代码

enum PhysicsCategory : UInt32 {
  case bar = 1
  case ball = 2
  case boss = 4
  case noCollision = 8
}

class GameScene: SKScene, SKPhysicsContactDelegate {

var score = Int()
var background = SKSpriteNode(imageNamed: "background.png")
var bar = SKSpriteNode(imageNamed: "bar.png")
var boss1 = SKSpriteNode(imageNamed: "boss1.png")

override func didMoveToView(view: SKView) {
    self.scene?.size = CGSize(width: 640, height:1136)
    physicsWorld.contactDelegate = self

    background.position = CGPoint(x: self.frame.width / 2, y: self.frame.height / 2)
    background.zPosition = -20
    self.addChild(background)

    bar.position = CGPoint(x: self.frame.width / 2, y: self.frame.height / 8)
    bar.physicsBody = SKPhysicsBody(rectangleOfSize: CGSize(width: bar.size.width, height: bar.size.height))
    bar.physicsBody?.categoryBitMask = PhysicsCategory.bar.rawValue
    bar.physicsBody?.contactTestBitMask = PhysicsCategory.ball.rawValue
    bar.physicsBody?.collisionBitMask = PhysicsCategory.bar.rawValue
    bar.physicsBody?.affectedByGravity = false
    bar.physicsBody?.dynamic = false
    self.addChild(bar)

    boss1.position = CGPoint(x: self.frame.width, y: self.frame.height - boss1.size.height / 2)
    boss1.physicsBody = SKPhysicsBody(rectangleOfSize: CGSize(width: boss1.size.width, height: boss1.size.height))
    boss1.physicsBody?.categoryBitMask = PhysicsCategory.boss.rawValue
    boss1.physicsBody?.contactTestBitMask = PhysicsCategory.ball.rawValue
    boss1.physicsBody?.collisionBitMask = PhysicsCategory.noCollision.rawValue
    boss1.physicsBody?.affectedByGravity = false
    boss1.physicsBody?.dynamic = false
    boss1.zPosition = 5
    self.addChild(boss1)

    boss1.runAction(SKAction.moveToX(self.frame.width / 2, duration: 1))

    let spawnBallsAction = SKAction.sequence([SKAction.waitForDuration(2), SKAction.runBlock(spawnBalls)])
    self.runAction(SKAction.repeatActionForever(spawnBallsAction))

}

func didBeginContact(contact: SKPhysicsContact) {
    let firstBody : SKPhysicsBody = contact.bodyA
    let secondBody : SKPhysicsBody = contact.bodyB

    if (firstBody.categoryBitMask & PhysicsCategory.bar.rawValue == PhysicsCategory.bar.rawValue &&
        secondBody.categoryBitMask & PhysicsCategory.ball.rawValue == PhysicsCategory.ball.rawValue) {

            CollisionWithBar(firstBody.node as! SKSpriteNode, ball: secondBody.node as! SKSpriteNode)

    }

    if (firstBody.categoryBitMask & PhysicsCategory.ball.rawValue == PhysicsCategory.ball.rawValue &&
        secondBody.categoryBitMask & PhysicsCategory.boss.rawValue == PhysicsCategory.boss.rawValue) {

            CollisionWithBoss(firstBody.node as! SKSpriteNode, boss: secondBody.node as! SKSpriteNode)

    }

}

func CollisionWithBar(bar: SKSpriteNode, ball: SKSpriteNode) {
    ball.physicsBody?.applyImpulse(CGVectorMake(0, 500))
    ball.physicsBody?.contactTestBitMask = PhysicsCategory.boss.rawValue //Trying to solve the problem, aint working
}

func CollisionWithBoss(ball: SKSpriteNode, boss: SKSpriteNode) {
    NSLog("Ball hit the boss")
}


func spawnBalls(){

    let ball = SKSpriteNode(imageNamed: "ball.png")
    let MinValue = self.frame.width / 8
    let MaxValue = self.frame.width - 20
    let SpawnPoint = UInt32(MaxValue - MinValue)
    ball.position = CGPoint(x: CGFloat(arc4random_uniform(SpawnPoint)), y: self.frame.height - 128)
    ball.zPosition = 50

    //Physics
    ball.physicsBody = SKPhysicsBody(circleOfRadius: ball.frame.height / 2)
    ball.physicsBody?.categoryBitMask = PhysicsCategory.ball.rawValue
    ball.physicsBody?.contactTestBitMask = PhysicsCategory.bar.rawValue
    ball.physicsBody?.collisionBitMask = PhysicsCategory.noCollision.rawValue
    ball.physicsBody?.affectedByGravity = true
    ball.physicsBody?.dynamic = true

    self.addChild(ball)
}

1 个答案:

答案 0 :(得分:1)

这是联系方式的完成方式:

创建球后,将联系人类别设置为:(您有)

ball.physicsBody?.contactTestBitMask = PhysicsCategory.bar.rawValue

确保老板联系无人:

boss1.physicsBody?.contactTestBitMask = PhysicsCategory.noCollision.rawValue

然后在联系人上,你想这样做:

func didBeginContact(contact: SKPhysicsContact) {
    let firstBody : SKPhysicsBody = (contact.bodyA.categoryBitMask <= contact.bodyB.categoryBitMask) ? contact.bodyA : contact.bodyB
    let secondBody : SKPhysicsBody = (contact.bodyA.categoryBitMask >= contact.bodyB.categoryBitMask) ? contact.bodyA : contact.bodyB

    if (firstBody.categoryBitMask & PhysicsCategory.bar.rawValue ==  PhysicsCategory.bar.rawValue &&
     secondBody.categoryBitMask & PhysicsCategory.ball.rawValue == PhysicsCategory.ball.rawValue) {
            //This should be inside CollisionWithBar
            ball.physicsBody?.contactTestBitMask = PhysicsCategory.bar.rawValue | PhysicsCategory.boss.rawValue

            //the ball has hit the bar, so lets enable hitting on the boss
            //normally we would only want to do this once, but since this is 
            //tiny, it would be more time to wrap it in ifs and putting guards on it
            boss1.physicsBody?.contactTestBitMask = PhysicsCategory.ball.rawValue
            CollisionWithBar(firstBody.node as! SKSpriteNode, ball: secondBody.node as! SKSpriteNode)

    }

    if (firstBody.categoryBitMask & PhysicsCategory.ball.rawValue == PhysicsCategory.ball.rawValue &&
    secondBody.categoryBitMask & PhysicsCategory.boss.rawValue == PhysicsCategory.boss.rawValue) {
            //This should be inside CollisionWithBoss
            ball.physicsBody?.contactTestBitMask = PhysicsCategory.bar.rawValue

            CollisionWithBoss(firstBody.node as! SKSpriteNode, boss: secondBody.node as! SKSpriteNode)

    }

 }

基本上说,如果球击中横杆,让boss打击,如果球击中boss,禁用boss打击

编辑:当实现多个球时,我们必须改变一些事情

确保老板在创作时接触球:

boss1.physicsBody?.contactTestBitMask = PhysicsCategory.ball.rawValue

现在我们需要创建一个新类别

enum PhysicsCategory : UInt32 {
    case bar = 1
    case ball = 2
    case boss = 4
    case noCollision = 8
    case initialBall = 16
}

首先,将球的类别分配给:

ball.physicsBody?.categoryBitMask = initialBall

然后你的CollissionWithBar将如下所示:

func CollisionWithBar(bar: SKSpriteNode, ball: SKSpriteNode) {
    ball.physicsBody?.applyImpulse(CGVectorMake(0, 500))
    ball.physicsBody?.contactTestBitMask = PhysicsCategory.bar.rawValue | PhysicsCategory.boss.rawValue


    ball.physicsBody?.categoryBitMask = PhysicsCategory.ball.rawValue 
}

你的CollissionWithBolls看起来像这样:

func CollisionWithBoss(ball: SKSpriteNode, boss: SKSpriteNode) {
    ball.physicsBody?.contactTestBitMask = PhysicsCategory.bar.rawValue
}

最后,在联系人上,你想要这样做:

func didBeginContact(contact: SKPhysicsContact) {
    let firstBody : SKPhysicsBody = (contact.bodyA.categoryBitMask <= contact.bodyB.categoryBitMask) ? contact.bodyA : contact.bodyB
    let secondBody : SKPhysicsBody = (contact.bodyA.categoryBitMask >= contact.bodyB.categoryBitMask) ? contact.bodyA : contact.bodyB

    if (firstBody.categoryBitMask & PhysicsCategory.bar.rawValue ==  PhysicsCategory.bar.rawValue &&
     secondBody.categoryBitMask & PhysicsCategory.ball.rawValue == PhysicsCategory.ball.rawValue) {
            CollisionWithBar(firstBody.node as! SKSpriteNode, ball: secondBody.node as! SKSpriteNode)

    }

    if (firstBody.categoryBitMask & PhysicsCategory.ball.rawValue == PhysicsCategory.ball.rawValue &&
    secondBody.categoryBitMask & PhysicsCategory.boss.rawValue == PhysicsCategory.boss.rawValue) {


            CollisionWithBoss(firstBody.node as! SKSpriteNode, boss: secondBody.node as! SKSpriteNode)

    }

 }