我正在制作一个游戏,你在中间是一艘太空飞船,有敌舰向你移动,你必须向他们射击才能获胜。
当我在测试游戏时,我看到当两艘或更多敌舰同时击中玩家船时,我收到了一个错误。我不确定这是否是导致错误的原因,但是当我测试它时它看起来就好了。
我制作游戏,以便每当敌方玩家触摸玩家时,游戏结束并调用一个函数来改变游戏场景。无论何时场景即将发生变化,都会调用此错误。
“致命错误:在解开可选值时意外发现nil”
这里是didBegin的代码(联系方式: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个或更多玩家与玩家接触时似乎不起作用)
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)
}
有人可以帮我解决这个问题。
答案 0 :(得分:2)
您的视图对象为nil,如果您在活动场景中定义GameOver1,这是很奇怪的。将GameOver1功能移动到主场景,这应解决问题。
或者,您可以创建一个全局变量并将其分配给GameViewController内的初始SKView对象。这不是最佳做法,但可行。
var gView = SKView()
class GameViewController: UIViewController {
// Stuff..
if let view = self.view as! SKView? {
gView = view
此外,此代码中还有其他潜在的崩溃问题。
正如KOD在评论中所说的那样,多个联系人可以在1帧中发生..但是你正在杀死节点(因此pb),这意味着预定的.didBegin
将会找到nil
或其他一些错误和崩溃。
更好的方法是在物理步骤之后标记要删除的节点 - 一旦安全处理联系人。
将他们的面具设置为某个高数字,而不是删除它:
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之前删除所有节点,因为这会导致尝试使用不再存在的节点时出现问题。
一种有点人为的方法(如果以上没有工作)是这样的:
var flag_shouldGameOver = false
override func didFinishUpdate() {
if flag_shouldGameOver == true {
flag_shouldGameOver = false
GameOver1()
}
}