Receiving an error when nodes make contact

痞子三分冷 提交于 2020-01-16 09:07:33

问题


I am currently making a game in which you are a space ship in the middle and there are enemy ships moving towards you and you have to shoot at them to win.

While I was testing the game I saw that I received an error when (it appears to be) two or more enemy ships hit the player ship at the same time. I am not certain if this is what's causing the error but it looks like it when I test it.

I made the game so that whenever enemy players touch the player, the game ends and a function is called to change the game scene. This is where the error is called, whenever the scene is about to change.

"fatal error: unexpectedly found nil while unwrapping an Optional value"

here is the code for the didBegin(contact: SKPhysicsContact)

func didBegin(_ contact: SKPhysicsContact) {

    var BodyOne = SKPhysicsBody()
    var BodyTwo = SKPhysicsBody()


    if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask{
        BodyOne = contact.bodyA
        BodyTwo = contact.bodyB
                }
    else{
        BodyOne = contact.bodyB
        BodyTwo = contact.bodyA
    }


    //SHIPS TOUCH EACH OTHER CHECK
    if BodyOne.categoryBitMask == NumberingPhysics.SpaceShip && BodyTwo.categoryBitMask == NumberingPhysics.LeftV{



        GameOver1()

       BodyTwo.node?.removeFromParent()
       BodyOne.node?.removeFromParent()

    }

    if BodyOne.categoryBitMask == NumberingPhysics.SpaceShip && BodyTwo.categoryBitMask == NumberingPhysics.RightV{

        GameOver1()
        BodyOne.node?.removeFromParent()
        BodyTwo.node?.removeFromParent()


        //more code is under here 

    }

And here is the code of the game changing scene. (which works when 1 enemy touches the player but doesn't seem to when 2 or more makes contact with the player)

func GameOver1(){

    ButtonAudioPlayer.stop()
    removeAllChildren()
    removeAllActions()
    let scene = GameOver(size: self.size)
    let sKView = self.view! as SKView       // <----- error shows here
    sKView.ignoresSiblingOrder = true
    scene.scaleMode = .aspectFill
    sKView.presentScene(scene)


}

Can someone please help me resolve this issue.


回答1:


Your view object is nil, which is peculiar if you are defining GameOver1 inside of the active scene. Move your GameOver1 function to your main scene, and that should fix the issue.

Or, you could make a global variable and assign it to the initial SKView object inside of your GameViewController. This is not a best practice but it will work.

var gView = SKView()

class GameViewController: UIViewController {
  // Stuff..

  if let view = self.view as! SKView? {
      gView = view

Also, you have other potential crash issues in this code.

As KOD said in comments multiple contacts can happen in 1 frame.. but you are killing the node (and thus pb) which means the scheduled .didBegin is going to find nil or some other error and crash.

A better way to do this is to flag the node for removal AFTER the physics step--once contacts are safely handled.

Set their mask to some high-number instead of removing it:

var nodesToKill = SKNode()

override func didBeginContact(/*prams*/) {
  // Stuff...

  BodyB.node!.categoryBitMask = 35 // Or some other number so as 
                                   // to not trigger another contact.
  BodyB.node!.moveToParent(nodesToKill) //moves the node off the scene entirely
}

override func didSimulatePhysics(/*prams*/) { 

  nodesToKill.removeAllChildren() // or do nodesToKill = SKNode() and let ARC take care of it for you
}

Also, you probably want to all of the node removal stuff BEFORE calling GameOver, as that can cause issues as well with trying to do stuff with nodes that no longer exist.

A somewhat contrived way around this (if the above didn't work) is something like this:

var flag_shouldGameOver = false

override func didFinishUpdate() {
  if flag_shouldGameOver == true {
     flag_shouldGameOver = false
     GameOver1()
  }
}


来源:https://stackoverflow.com/questions/44895717/receiving-an-error-when-nodes-make-contact

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!