Burundanga
Burundanga

Reputation: 668

How to switch between scenes in Sprite Kit?

What's wrong with my code? Every time I hit the button I'm getting a default grey screen. Button for transition:

override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
    for touch: AnyObject in touches {
    let location = touch.locationInNode(self)
        if self.nodeAtPoint(location) == self.pause {
            var pauseScene = PauseScene(size: self.size)
            scene?.paused = true
            let skView = self.view as SKView!
            skView.ignoresSiblingOrder = true
            pauseScene.scaleMode = .AspectFill
            pauseScene.size = skView.bounds.size
            skView.presentScene(pauseScene)
        }
    }
}

What I have in that scene that don't want to load:

class PauseScene: SKScene {
    let pauseBackground = SKSpriteNode (imageNamed: "pauseBackground")

    override func didMoveToView(view: SKView) {
        self.pauseBackground.anchorPoint = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))
        self.pauseBackground.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))
        self.addChild(pauseBackground)
    }

}

Did I miss something?

Upvotes: 2

Views: 972

Answers (2)

user3069232
user3069232

Reputation: 8995

Here is an updated answer swift 5, iOS 14 Using swiftUI

import SwiftUI import SpriteKit

struct ContentView: View {

@State var switcher = false

var scene: SKScene {
    let scene = GameScene.shared
    scene.size = CGSize(width: 256, height: 256)
    scene.scaleMode = .fill
    scene.backgroundColor = .red
    scene.name = "red"
    return scene
}

var scene2: SKScene {
    let scene2 = GameScene2.shared
    scene2.size = CGSize(width: 256, height: 256)
    scene2.scaleMode = .fill
    scene2.backgroundColor = .blue
    scene2.name = "blue"
    return scene2
}

var body: some View {
  if switcher {
    SpriteView(scene: scene)
        .frame(width: 256, height: 256)
        .ignoresSafeArea()
        .background(Color.red)
        .onAppear {
          scene2.isPaused = true
        }
        .onDisappear {
          scene2.isPaused = false
        }
        
  } else {
    SpriteView(scene: scene2)
        .frame(width: 256, height: 256)
        .ignoresSafeArea()
        .background(Color.blue)
        .onAppear {
          scene.isPaused = true
        }
        .onDisappear {
          scene.isPaused = false
        }
        
  }
  Button {
    withAnimation(.easeInOut(duration: 1.0)) {
      switcher.toggle()
    }
  } label: {
    Text("switch")
  }
}
}

class GameScene: SKScene {

static var shared = GameScene()

override func update(_ currentTime: TimeInterval) {
// Tells your app to perform any app-specific logic to update your scene.
  print("name ",scene!.name)
}
}

Upvotes: 0

Skyler Lauren
Skyler Lauren

Reputation: 3812

It looks like your issue is in didMoveToView: in your PauseScene. You don't want to change your anchor point for self.pauseBackground Normally anchor point is based on 0 to 1. (.5,.5) being the center of the sprite. You are setting it to something much higher than that and if you are setting the position to half the width and hight of the scene I don't see why you would want to change the anchor point at all. Looks like just deleting the line of code should fix the issue.

class PauseScene: SKScene {
let pauseBackground = SKSpriteNode (imageNamed: "pauseBackground")

    override func didMoveToView(view: SKView) {
        self.pauseBackground.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame))
        self.addChild(pauseBackground)
    }
}

Also I see you are changing the size of your scene after you init it. I would just init it with the size you want.

override func touchesBegan(touches: NSSet, withEvent event: UIEvent) {
    for touch: AnyObject in touches {
    let location = touch.locationInNode(self)
        if self.nodeAtPoint(location) == self.pause {
            let skView = self.view as SKView!
            skView.ignoresSiblingOrder = true
            var pauseScene = PauseScene(size: skView.bounds.size)
            scene?.paused = true
            pauseScene.scaleMode = .AspectFill
            skView.presentScene(pauseScene)
        }
    }
}

Hopefully that helps and makes sense.

Upvotes: 1

Related Questions