调用转换方法时,SKScene返回nil

时间:2016-06-10 22:54:05

标签: swift skscene

在我的小Xcode项目中,我试图在触摸我的SKLabelNode时转换场景,它呈现下一个场景。出于某些原因,在我的场景转换方法中,它使我将其存储为可选项。并且可选返回false。我的文件名是正确的,引用中没有语法错误会导致问题,这是我的代码。当我单击我的SKLabelNode时,运行它的ios平台识别触摸然后应用程序崩溃,在控制台中说可选值返回为nil。我怎么能解决这个问题?感谢

import SpriteKit

class GameScene: SKScene {

let next = SKScene(fileNamed: "nextScene")

override func didMoveToView(view: SKView) {


    let backgroundimage = SKSpriteNode(imageNamed: "ipbg")
    backgroundimage.size = CGSize(width: self.frame.size.width, height: self.frame.size.height)
    backgroundimage.position = CGPoint(x: self.frame.size.width / 2, y: self.frame.size.height / 2)
    addChild(backgroundimage)

    let playButton = SKLabelNode(fontNamed: "")
    playButton.name = "play"
    playButton.position = CGPoint(x: self.frame.size.width / 2, y: self.frame.size.height / 2 + 100)
    playButton.text = "Play"

    let wait = SKAction.waitForDuration(2)
    let run = SKAction.runBlock({


        let randomNumber = Int(arc4random_uniform(UInt32(4)))

        switch(randomNumber){

        case (0):

            playButton.fontColor = UIColor.blueColor()

        case 1:

            playButton.fontColor = UIColor.yellowColor()

        case 2:

            playButton.fontColor = UIColor.purpleColor()

        case 3:

            playButton.fontColor = UIColor.orangeColor()

        default: print("default")


        }

    })

    addChild(playButton)
    var repeatActionForever = SKAction.repeatActionForever(SKAction.sequence([wait, run]))
    runAction(repeatActionForever)
}

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {

    let trans = SKTransition.crossFadeWithDuration(1)
    let touch = touches.first! as UITouch
    let touchLocation = touch.locationInNode(self)
    let touchedNode = nodeAtPoint(touchLocation)

    if touchedNode.name == "play"{


        scene!.view?.presentScene(next!, transition: trans)

        }

    }
}

func update(currentTime: CFTimeInterval) {
    /* Called before each frame is rendered */
}

2 个答案:

答案 0 :(得分:0)

您发布的代码未编译,因此很难找到错误。

但是,我会尝试使用以下

替换touchesBegan方法
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {

    let trans = SKTransition.crossFadeWithDuration(1)
    let touch = touches.first! as UITouch
    let touchLocation = touch.locationInNode(self)
    let touchedNode = nodeAtPoint(touchLocation)

    if touchedNode.name == "play"{
        guard let nextScene = SKScene(fileNamed: "nextScene")
            else { fatalError("Could not load nextScene") }
        self.view?.presentScene(nextScene, transition: trans)
    }
}

答案 1 :(得分:0)

没有必要将场景存储为属性,只需将其添加到touches started方法中即可。

此外,您应该为每个场景创建相应的swift文件和类,而不是尝试使用通用SKScene对象初始化.sks文件。行...(fileNamed:“nextScene”)查找.sks文件(Xcode可视化级别编辑器文件),如果您尚未创建,则您的属性将为零。

要使其发挥作用,请执行以下操作:

首先确保您创建了一个名为NextScene的.sks文件(右键单击项目中的文件 - &gt; New - &gt; Resource - &gt; SpriteKit Scene)

其次创建一个新的swift文件并创建一个名为NextScene的新类

 class NextScene: SKScene { 

 }

比触摸标签功能中的加载代码看起来像这样。

  override func touchesBegan... {
       ...

       if let nextScene = NextScene(fileNamed: "NextScene") //actually init the corresponding class with the corresponding .sks file
       /// scene presenting code
      }

   }

正如您所提到的,您的scene属性返回一个可选项,因为您指定的fileNamed(.sks文件)可能不存在,因此请检查它是否存在。一般来说,如上所述安全解包或GameViewController中的默认加载代码更好的做法,而不仅仅是强行打开!

如果你不使用视觉水平编辑器而不仅仅是创建你的场景类而忽略创建.sks文件并像这样加载你的场景

 let nextScene = NextScene(size: self.size) // use current scene size
  /// scene presenting code

注意:您的文件名应以大写字母

开头