SpriteKit:解开时意外找到零,无法实现多个菜单场景
我试图用2个按钮作为初始场景来呈现菜单:play
,credits
。当单击play
时,我想用4个按钮呈现另一个菜单场景:tutorial
,easy
,hard
,back
。
该策略只是将按钮创建为SKSpriteNode
对象并处理touchesBegan
函数中的点击。
在我的menuScene.sks
文件中,我正确放置并命名了我的节点。在这里,你可以检查menuScene.swift
文件链接到了这一幕:SpriteKit:解开时意外找到零,无法实现多个菜单场景
import SpriteKit
class menuScene: SKScene {
var playButton:SKSpriteNode!
var creditsButton:SKSpriteNode!
override func didMove(to view: SKView) {
playButton = self.childNode(withName: "playButton") as! SKSpriteNode
creditsButton = self.childNode(withName: "creditsButton") as! SKSpriteNode
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
// transition is defined in Helper.swift
let touch = touches.first
if let location = touch?.location(in: self){
let nodesArray = self.nodes(at: location)
if nodesArray.first?.name == "playButton" {
let nextScene = difScene(size: self.size)
self.view?.presentScene(nextScene, transition: transition)
} else if nodesArray.first?.name == "creditsButton" {
let nextScene = creditsScene(size: self.size)
self.view?.presentScene(nextScene, transition: transition)
}
}
}
}
当我运行,menuScene呈现没有问题。但是,当我触摸play
按钮时,出现错误,它来自下一个场景:difScene
。 在这里你可以找到difScene.swift
:
import SpriteKit
class difScene: SKScene {
var tutButton:SKSpriteNode!
var easyButton:SKSpriteNode!
var hardButton:SKSpriteNode!
var backButton:SKSpriteNode!
override func didMove(to view: SKView) {
tutButton = self.childNode(withName: "tutButton") as! SKSpriteNode // error
easyButton = self.childNode(withName: "easyButton") as! SKSpriteNode
hardButton = self.childNode(withName: "hardButton") as! SKSpriteNode
backButton = self.childNode(withName: "backButton") as! SKSpriteNode
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let transition = SKTransition.push(with: .down, duration: 0.2)
let touch = touches.first
if let location = touch?.location(in: self){
let nodesArray = self.nodes(at: location)
if nodesArray.first?.name == "tutButton" {
let nextScene = GameScene(size: self.size)
self.view?.presentScene(nextScene, transition: transition)
}
if nodesArray.first?.name == "easyButton" {
let nextScene = difScene(size: self.size)
self.view?.presentScene(nextScene, transition: transition)
}
if nodesArray.first?.name == "hardButton" {
let nextScene = difScene(size: self.size)
self.view?.presentScene(nextScene, transition: transition)
}
if nodesArray.first?.name == "backButton" {
let nextScene = menuScene(size: self.size)
self.view?.presentScene(nextScene, transition: transition)
}
}
}
}
在情况下,它可能是有用的,这是我GameViewController.swift
:
import UIKit
import SpriteKit
import GameplayKit
class GameViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
if let scene = GKScene(fileNamed: "menuScene") {
// Get the SKScene from the loaded GKScene
if let sceneNode = scene.rootNode as! menuScene? {
// Set the scale mode to scale to fit the window
sceneNode.scaleMode = .aspectFill
// Present the scene
if let view = self.view as! SKView? {
view.presentScene(sceneNode)
view.ignoresSiblingOrder = true
view.showsFPS = false
view.showsNodeCount = false
}
}
}
}
override var shouldAutorotate: Bool {
return true
}
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
if UIDevice.current.userInterfaceIdiom == .phone {
return .allButUpsideDown
} else {
return .all
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Release any cached data, images, etc that aren't in use.
}
override var prefersStatusBarHidden: Bool {
return true
}
}
我得到的错误是:
Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value
我知道这是不是一个唯一的错误。我有Google,看过教程,并尝试从其他*线程获得解决方案,但未能克服此问题。
的错误是在这条线
tutButton = self.childNode(withName: "tutButton") as! SKSpriteNode // error
,因为有一个名为“tutButton”无子节点,所以迫使它转换成一SKSpriteNode
导致错误。
当按下播放按钮,可以调用此代码:
let nextScene = difScene(size: self.size)
self.view?.presentScene(nextScene, transition: transition)
这初始化一个新difScene
,并提出它,进而调用代码上方时崩溃行。
对于difScene
,您是否有对应的sks
文件?在didMove
中添加您引用的四个按钮?
如果是这样,你需要像你这样为你的菜单中的场景与sks
文件初始化difScene
:
let scene = GKScene(fileNamed: "difScene")
如果没有,您需要创建这四个按钮节点并将它们添加作为孩子以编程方式进入你的场景。
旁注:在斯威夫特,惯例是名称以大写字母类型。您的menuScene
应该是MenuScene
,而您的difScene
应该是DifScene
。这会让其他人更容易阅读和理解你的代码。
对不起,这是我Java时代的习惯......我有相应的difScene.sks文件,并放置所有按钮。我到底应该在GameViewController中初始化我的difScene? –
@CevatMertDökümcü你可以在当前的位置初始化它('let nextScene = difScene(size:self.size)'),但是你需要用'fileNamed'而不是'size'调用初始化器。 – nathan
噢好吧我应该怎么做初始化后调整大小?我曾尝试使用“nextScene?.size = self.size”,但它不起作用。我目前正在成功进入difScene,但它比预期更大 –