SwiftyJD SwiftyJD - 2 months ago 11
Swift Question

Spritekit - Scene created in .sks file is blank when transitioning from another scene

I have a main menu scene where when a button is pressed it should transition to another scene. It appears to transition properly but when it's done transitioning the 2nd scene is blank. I put breakpoints in the 2nd scene's didMove function and it appears to be running properly. I know the 2nd scene works properly when directly opened from the GameViewController. I'm not sure why it's blank when transitioning from another scene. Here is my current code:

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


This is the scene transitioning to:

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


}

Answer

You are calling the wrong init method to load your pool scene. The way you do it is when you do not use the Xcode visual level editor. Like your GameViewController, you need to init scenes that reference .sks files like so.

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

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

or in a slightly cleaner way

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

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

"fileNamed:..." is the name of the .sks file for your PoolScene, which you usually give the exact same name as the corresponding .swift file. Use guard or if let because it will return an optional.

As a small tip, make use of swifts type inference to make your code a bit nicer like in my example.

Hope this helps

Comments