节点建立联系时收到错误 [英] Receiving an error when nodes make contact

查看:12
本文介绍了节点建立联系时收到错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在制作一个游戏,在游戏中你是一艘太空船,在中间有敌舰向你移动,你必须向它们射击才能获胜.

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.

致命错误:在展开可选值时意外发现 nil"

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

这里是 didBegin(联系人:SKPhysicsContact)的代码

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 

    }

这是改变游戏场景的代码.(当 1 个敌人接触玩家时有效,但当 2 个或更多敌人与玩家接触时似乎无效)

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.

推荐答案

您的视图对象为 nil,如果您在活动场景中定义 GameOver1,这很奇怪.将 GameOver1 函数移至主场景,这应该可以解决问题.

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.

或者,您可以创建一个全局变量并将其分配给 GameViewController 内的初始 SKView 对象.这不是最佳做法,但它会起作用.

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.

正如 KOD 在评论中所说,多个联系人可能会在 1 帧中发生.. 但是您正在杀死节点(因此 pb),这意味着预定的 .didBegin 将找到 nil 或其他一些错误和崩溃.

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
}

此外,您可能希望在调用 GameOver 之前删除所有节点,因为这可能会导致尝试对不再存在的节点执行操作时出现问题.

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()
  }
}

这篇关于节点建立联系时收到错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆