Почему мои объекты SpriteKit неправильно сталкиваются? - PullRequest
0 голосов
/ 19 июня 2019

Я пытаюсь изучить SpriteKit, следуя этому руководству

Все работало нормально, пока я не хотел добавить еще одно столкновение между двумя различными объектами.У меня есть вражеские узлы, игрок (космический корабль), снаряды и метеоры, враги падают, и вы стреляете в них с корабля снарядами и избегаете метеоры.Я попытался настроить структуру категории физики, установить правильные категории физики для каждого узла и создать функции столкновения.

Проблема в том, что метеоры запускают функцию, которая должна происходить, когда метеоры попадают в характер космического корабля.когда они били и врагов, я пытался что-то менять, и столкновения просто смешивались, но я никогда не смогу сделать это правильно.Я просто хочу, чтобы снаряды поразили вражеские корабли, а метеоры повредили корабль игроков.

Вот что я сделал:

struct PhysicsCategory {
static let none      : UInt32 = 0
static let all       : UInt32 = UInt32.max
static let monster   : UInt32 = 0x2       // 1
static let projectile: UInt32 = 0x3      // 2
static let spaceship   : UInt32 = 0x4
static let meteor : UInt32 = 0x5
static let edge : UInt32 = 0x6
} 

Космический корабль:

  spaceship.physicsBody = SKPhysicsBody(rectangleOf: spaceship.size) // 1
    spaceship.physicsBody?.isDynamic = true // 2
    spaceship.physicsBody?.categoryBitMask = PhysicsCategory.spaceship // 3
    spaceship.physicsBody?.contactTestBitMask = PhysicsCategory.meteor// 4
    spaceship.physicsBody?.collisionBitMask = PhysicsCategory.none // 5

Enemy:

 monster.physicsBody = SKPhysicsBody(rectangleOf: monster.size) // 1
    monster.physicsBody?.isDynamic = true // 2
    monster.physicsBody?.categoryBitMask = PhysicsCategory.monster // 3
    monster.physicsBody?.contactTestBitMask = PhysicsCategory.projectile // 4
    monster.physicsBody?.collisionBitMask = PhysicsCategory.none // 5

Снаряд:

 projectile.physicsBody = SKPhysicsBody(rectangleOf: projectile.size)
    projectile.physicsBody?.isDynamic = true
    projectile.physicsBody?.categoryBitMask = PhysicsCategory.projectile
    projectile.physicsBody?.contactTestBitMask = PhysicsCategory.monster
    projectile.physicsBody?.collisionBitMask = PhysicsCategory.none
    projectile.physicsBody?.usesPreciseCollisionDetection = true

Метеор:

   monster.physicsBody = SKPhysicsBody(rectangleOf: monster.size) // 1
    monster.physicsBody?.isDynamic = true // 2
    monster.physicsBody?.categoryBitMask = PhysicsCategory.meteor // 3
    monster.physicsBody?.contactTestBitMask = PhysicsCategory.none // 4
    monster.physicsBody?.collisionBitMask = PhysicsCategory.none// 5

Наконец, физические функции:

  func projectileDidCollideWithMonster(projectile: SKSpriteNode, monster: SKSpriteNode) {
    print("Hit")
    run(SKAction.playSoundFileNamed("Dull-Impact-Hit.wav", waitForCompletion: false))

    hits += 1
    scoreLabel.text = "Score: \(hits)/25"
    if hits == 25 {
        self.removeAction(forKey: "addMonster")
        self.scoreLabel.text = "Victory!"
    }
    monster.removeAction(forKey: "spaceshipMoving")
    monster.run(SKAction.animate(with: explosionAnimation,
                                 timePerFrame: 0.1,
                                 resize: false,
                                 restore: true))
    monster.run(SKAction.animate(with: explosionAnimation,
                                 timePerFrame: 0.1,
                                 resize: false,
                                 restore: true)) {
                                    monster.removeFromParent()
    }
    projectile.removeFromParent()

}

func meteorDidCollideWithSpaceship(meteor: SKSpriteNode, spaceship: SKSpriteNode) {
    print("Ouch")
    run(SKAction.playSoundFileNamed("Dull-Impact-Hit.wav", waitForCompletion: false))

    health -= 1
    healthLabel.text = String(health)
    print("health" + String(health))
    if health == 0 {
    scoreLabel.text = "You died!"
    healthLabel.text = "☠"
    self.view?.isUserInteractionEnabled = false
    self.spaceship.removeFromParent()
    }
}
}

  extension GameScene: SKPhysicsContactDelegate {
func didBegin(_ contact: SKPhysicsContact) {

    // 1
    var firstBody: SKPhysicsBody
    var secondBody: SKPhysicsBody
    if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
        firstBody = contact.bodyA
        secondBody = contact.bodyB
    } else {
        firstBody = contact.bodyB
        secondBody = contact.bodyA
    }

    // 2
    if ((firstBody.categoryBitMask & PhysicsCategory.monster != 0) &&
        (secondBody.categoryBitMask & PhysicsCategory.projectile != 0)) {
        if let monster = firstBody.node as? SKSpriteNode,
            let projectile = secondBody.node as? SKSpriteNode {
            projectileDidCollideWithMonster(projectile: projectile, monster: monster)
        }
    }
   if ((firstBody.categoryBitMask & PhysicsCategory.spaceship != 0 ) &&
        (secondBody.categoryBitMask & PhysicsCategory.meteor != 0 )) {
        if let meteor = firstBody.node as? SKSpriteNode,
            let spaceship = secondBody.node as? SKSpriteNode {
            meteorDidCollideWithSpaceship(meteor: meteor, spaceship: spaceship)
        }
    }
}

}

Как я могу получить предполагаемое поведение?Спасибо.

...