Обнаружение столкновения не работает, случайная ошибка принудительного развертывания фатальная ошибка - PullRequest
0 голосов
/ 27 октября 2019

Я переделываю ретро игру Астероиды.

У меня есть три типа астероидов: большой, средний и маленький. И я пытаюсь добавить обнаружение попадания на корабль, чтобы когда астероид попадал в космический корабль, астероид удалялся от родителя.

Но это не работает, и я случайно получаю ошибку Fatal Error: Unexpectedly found nil while unwrapping an optional value.

Я получаю ее в случайных местах и ​​не знаю, как ее исправить, но чаще всего в строкахкоторые устанавливают значение isDynamic. (КСТАТИ я насильно разворачиваю их!)

Код для категорий:

    struct PhysicsCategory {
        static let none: UInt32 = 0
        static let bulletCategory: UInt32 = 0x1 << 1
        static let spaceShipCategory: UInt32 = 0x1 << 2
        static let bigAsteroidCategory: UInt32 = 0x1 << 3
        static let mediumAsteroidCategory: UInt32 = 0x1 << 4
        static let smallAsteroidCategory: UInt32 = 0x1 << 5


    }

Это код моего космического корабля:

 override func didMove(to view: SKView) {

        SpaceShip = childNode(withName: "Spaceship") as? SKSpriteNode
        SpaceShip!.physicsBody = SKPhysicsBody(texture: SpaceShip!.texture!, size: CGSize(width: SpaceShip!.size.width, height: SpaceShip!.size.height))
        SpaceShip!.physicsBody!.isDynamic = true

        SpaceShip!.physicsBody!.categoryBitMask = PhysicsCategory.spaceShipCategory
        SpaceShip!.physicsBody!.contactTestBitMask = PhysicsCategory.bigAsteroidCategory | PhysicsCategory.mediumAsteroidCategory | PhysicsCategory.smallAsteroidCategory
        SpaceShip!.physicsBody!.collisionBitMask = PhysicsCategory.none

        self.physicsWorld.gravity = CGVector(dx: 0, dy: 0)
        self.physicsWorld.contactDelegate = self
        self.physicsBody = SKPhysicsBody(edgeLoopFrom: self.frame)


        //This is the code which runs the asteroid functions:
        run(SKAction.repeatForever(
            SKAction.sequence([
                SKAction.run(bigAsteroids),
                SKAction.wait(forDuration: 7.0),
            ])
        ))

        run(SKAction.repeatForever(
           SKAction.sequence([
               SKAction.run(mediumAsteroids),
               SKAction.wait(forDuration: 15.0)
           ])
        ))

        run(SKAction.repeatForever(
          SKAction.sequence([
              SKAction.run(smallAsteroids),
              SKAction.wait(forDuration: 20.0)
          ])
       ))



}

Этоявляется функцией астероида (их три, но все они очень похожи, поэтому я просто покажу одну)

  func bigAsteroids() {
        let bigAsteroid = SKSpriteNode(imageNamed: "Asteroid")

        bigAsteroid.physicsBody = SKPhysicsBody(texture: bigAsteroid.texture!, size: bigAsteroid.texture!.size())

        let yCoordinate = random(lowest: -self.size.height, highest: self.size.height - bigAsteroid.size.height)

        var xCoordinate = -self.size.width - bigAsteroid.size.width/2

        let xCoordinateChooser = arc4random_uniform(2)

        if xCoordinateChooser == 0 {
            xCoordinate = self.size.width - bigAsteroid.size.width/2
        }

        else {
            xCoordinate = -self.size.width - bigAsteroid.size.width/2
        }

        bigAsteroid.physicsBody!.isDynamic = true
        bigAsteroid.physicsBody!.collisionBitMask = PhysicsCategory.none
        bigAsteroid.physicsBody!.categoryBitMask = PhysicsCategory.bigAsteroidCategory

        bigAsteroid.position = CGPoint(x: xCoordinate, y: yCoordinate)

        addChild(bigAsteroid)

        let moveAsteroid = SKAction.moveBy(x: -xCoordinate, y: -yCoordinate, duration: 8.0)
        let spinAsteroid = SKAction.rotate(byAngle: CGFloat.pi * 2, duration: 8.0)
        let asteroidMovement = SKAction.group([moveAsteroid, spinAsteroid])

        bigAsteroid.run(asteroidMovement)

    }

Это код, который проверяет наличие столкновений

func didBegin(_ contact: SKPhysicsContact) {

        let collision: UInt32 = contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask

        if collision == PhysicsCategory.bigAsteroidCategory | PhysicsCategory.bigAsteroidCategory {
            print("big collision")
            contact.bodyA.node?.removeFromParent()
            contact.bodyB.node?.removeFromParent()
        }

        else if collision == PhysicsCategory.mediumAsteroidCategory | PhysicsCategory.mediumAsteroidCategory {
            print("medium collision")
            contact.bodyA.node?.removeFromParent()
            contact.bodyB.node?.removeFromParent()
        }

        else if collision == PhysicsCategory.smallAsteroidCategory | PhysicsCategory.smallAsteroidCategory {
            print("small collision")
            contact.bodyA.node?.removeFromParent()
            contact.bodyB.node?.removeFromParent()
        }


    }

Любая помощь илиРешение приветствуется.

...