【问题标题】:Spritekit - Scene created in .sks file is blank when transitioning from another sceneSpritekit - 从另一个场景转换时,在 .sks 文件中创建的场景是空白的
【发布时间】:2016-09-26 23:48:45
【问题描述】:

我有一个主菜单场景,当按下按钮时它应该转换到另一个场景。它似乎可以正确过渡,但是当它完成过渡时,第二个场景是空白的。我在第二个场景的 didMove 函数中设置了断点,它似乎运行正常。我知道从 GameViewController 直接打开第二个场景时可以正常工作。我不确定为什么从另一个场景过渡时它是空白的。这是我当前的代码:

class StartScene: SKScene {

  var playButton = SKSpriteNode()
  let playButtonTex = SKTexture(imageNamed: "BlueRoundedButton")

  override func didMove(to view: SKView) {

    playButton = SKSpriteNode(texture: playButtonTex)
    playButton.size = CGSize(width: 200, height: 50)
    playButton.position = CGPoint(x: frame.midX, y: frame.midY)
    self.addChild(playButton)
  }

  override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    if let touch = touches.first {
      let pos = touch.location(in: self)
      let node = self.atPoint(pos)

      if node == playButton {
        if let view = view {
          let transition:SKTransition = SKTransition.fade(withDuration: 1)
          let scene:SKScene = PoolScene(size: self.size)
          self.view?.presentScene(scene, transition: transition)
        }
      }
    }
  }
}

这是过渡到的场景:

class PoolScene: SKScene, SKPhysicsContactDelegate {

  var ballPoke : SKSpriteNode?
  var ballBlue : SKSpriteNode?
  var ballOrange : SKSpriteNode?


  override func didMove(to view: SKView) {

    let borderBody = SKPhysicsBody(edgeLoopFrom: self.frame)
    borderBody.friction = 0
    self.physicsBody = borderBody

    self.physicsWorld.gravity = CGVector(dx: 0, dy: 0)
    physicsWorld.contactDelegate = self

    ballBlue = childNode(withName: blueBallName) as? SKSpriteNode
    ballOrange = childNode(withName: orangeBallName) as? SKSpriteNode
    ballPoke = childNode(withName: pokeBallName) as? SKSpriteNode


    ballBlue?.physicsBody?.categoryBitMask = blueBallCategory
    ballOrange?.physicsBody?.categoryBitMask = orangeBallCategory
    ballPoke?.physicsBody?.categoryBitMask = pokeBallCategory
    borderBody.categoryBitMask = borderCategory


  }

【问题讨论】:

  • 您在初始化场景中指定大小,而不是 sks 文件的名称。 let scene:SKScene = PoolScene(size: self.size) --> 用名字 init 覆盖 size
  • 尝试减少你的代码,你可以简化你的if语句,if node == playButton ,let view = view { 如果是Swift 3.0,如果是if let view = view where node == playbutton

标签: ios swift sprite-kit skspritenode skscene


【解决方案1】:

您调用了错误的 init 方法来加载您的 PoolScene。您这样做的方式是在您不使用 Xcode 可视化关卡编辑器时使用。 与您的 GameViewController 一样,您需要使用相应 .sks 文件的引用来初始化场景。

 if node == playButton {
     if let view = view {
        let transition = SKTransition.fade(withDuration: 1)

         if let scene = PoolScene(fileNamed: "PoolScene") {
              view.presentScene(scene, transition: transition)
         }
      }
  }

或者更简洁的方式

  if node == playButton {
     let transition = SKTransition.fade(withDuration: 1)

     if let scene = PoolScene(fileNamed: "PoolScene") {
         view?.presentScene(scene, transition: transition)    
      }
  }

"fileNamed:..." 是 PoolScene 的 .sks 文件的名称,通常与 .swift 文件的名称完全相同。使用 guard 或 if let 因为它会返回一个可选值。

作为一个小技巧,利用 swifts 类型推断使您的代码更漂亮,就像我的示例中一样。

希望对你有帮助

【讨论】:

  • 仅供参考,如果您将代码插入他的代码中,由于视图是本地的并且不再是可选的,并且您没有使用 self.view,它会中断?
  • 这是从 1 个 SKScene 到另一个 SKScene 的代码。我从不使用 self ,除非我也有。是的,没有看到他已经在展开视图。在这种情况下应该只是查看。我会更新我的答案。
  • 我知道,但是看OP代码,他有if let view = view
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多