Не обнаруживает столкновения - SpriteKit - Swift - PullRequest
0 голосов
/ 13 марта 2020

Я пытаюсь обнаружить столкновение между двумя объектами, но это работает только несколько раз. Большую часть времени это не работает. Может быть, вы можете помочь мне понять, что я делаю неправильно.

    static let soldier: UInt32 = 0x1 << 4
    static let enemy: UInt32 = 0x1 << 5

Функция установки физики тела для земли, солдата и врага:

 func addPhysicsBody(to sprite: SKSpriteNode, with name: String) {

    let centerPoint = CGPoint(x:sprite.size.width / 2 - (sprite.size.width * sprite.anchorPoint.x), y:sprite.size.height / 2 - (sprite.size.height * sprite.anchorPoint.y))
    sprite.physicsBody = SKPhysicsBody(rectangleOf: sprite.size, center: centerPoint)
    sprite.physicsBody?.allowsRotation = false
    sprite.physicsBody?.affectedByGravity = true
    sprite.physicsBody?.restitution = 0.0
    sprite.physicsBody?.friction = 0

    if name.contains(GameConstants.StringConstants.soldierName) {
        sprite.physicsBody?.categoryBitMask = GameConstants.PhysicsCategories.soldier
        sprite.physicsBody?.contactTestBitMask = GameConstants.PhysicsCategories.enemy
        sprite.physicsBody?.collisionBitMask = GameConstants.PhysicsCategories.ground
        sprite.physicsBody?.isDynamic = true

    } else if name.contains(GameConstants.StringConstants.enemyName) {
        sprite.physicsBody?.categoryBitMask = GameConstants.PhysicsCategories.enemy
        sprite.physicsBody?.contactTestBitMask = GameConstants.PhysicsCategories.soldier
        sprite.physicsBody?.collisionBitMask = GameConstants.PhysicsCategories.ground
        sprite.physicsBody?.isDynamic = true

    } else if name == GameConstants.StringConstants.groundName {
        sprite.physicsBody?.affectedByGravity = false
        sprite.physicsBody?.categoryBitMask = GameConstants.PhysicsCategories.ground
        sprite.physicsBody?.isDynamic = false
    }
}

генерация солдата и Враг и перемещая его:

func generateASoldier() {
    let soldier = SKSpriteNode(texture: SKTexture(image: UIImage(named: "0\(GameConstants.StringConstants.idlePrefixKey)0")!), color: UIColor.darkGray, size: self.frame.size)
    soldier.size = CGSize(width: castle.frame.size.height/4, height: castle.frame.size.height/4)
    soldier.name = "\(GameConstants.StringConstants.soldierName)\(soldierCounter)"
    soldierCounter+=1
    addPhysicsBody(to: soldier, with: soldier.name!)
    soldier.position = CGPoint(x: frame.minX-soldier.size.width*2, y: frame.midY/1.1)
    soldier.zPosition = GameConstants.ZPositions.playerZ

    addChild(soldier)

    isMovingSoldier.append(true)
    moveSoldier(soldier: soldier, index: isMovingSoldier.count-1)
}

func moveSoldier(soldier: SKSpriteNode, index: Int) {

    soldier.physicsBody?.applyImpulse(CGVector(dx: charactersSpeed, dy: 0))

    DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: {
        if self.isMovingSoldier[index] {
            self.moveSoldier(soldier: soldier, index: index)
        }
    })
}


func generateAnEnemy() {
    let enemy = SKSpriteNode(texture: SKTexture(image: UIImage(named: "1\(GameConstants.StringConstants.idlePrefixKey)0")!), color: UIColor.darkGray, size: self.frame.size)
    enemy.size = CGSize(width: -castle.frame.size.height/4, height: castle.frame.size.height/4)
    enemy.name = "\(GameConstants.StringConstants.enemyName)\(enemyCounter)"
    enemyCounter+=1
    addPhysicsBody(to: enemy, with: enemy.name!)
    enemy.position = CGPoint(x: frame.maxX-enemy.size.width*2, y: frame.midY/1.1)
    enemy.zPosition = GameConstants.ZPositions.playerZ

    addChild(enemy)

    isMovingEnemy.append(true)
    moveEnemy(enemy: enemy, index: isMovingEnemy.count-1)
}

func moveEnemy(enemy: SKSpriteNode, index: Int) {

    enemy.physicsBody?.applyImpulse(CGVector(dx: -charactersSpeed, dy: 0))

    DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: {
        if self.isMovingEnemy[index] {
            self.moveEnemy(enemy: enemy, index: index)
        }
    })
}

создание земли:

func generateGround() {

    ground = SKSpriteNode(color: .white, size: CGSize(width: frame.maxX*3, height: UIScreen.main.bounds.size.height/2.435))
    ground.name = GameConstants.StringConstants.groundName
    addPhysicsBody(to: ground, with: ground.name!)
    ground.zPosition = GameConstants.ZPositions.playerZ
    ground.position = CGPoint(x: frame.midX, y: frame.minY)
    self.addChild(ground)
}

Использование этого кода func didBegin(_ contact: SKPhysicsContact) вызывается случайное количество раз, и я пытаюсь убедиться, что это будет вызывается каждый раз, когда солдат и враг сталкиваются

Редактировать:
Я обнаружил, что проблема заключается в обнаружении столкновения с помощью функции applyImpulse. Используя гравитацию, он обнаруживает столкновение

...