I am trying to use the isPaused:
argument in the
All relevant code is in ContentView.swift.
class GameScene: SKScene {
private let label = SKLabelNode(text: "Time Elapsed:\n0")
private var lastUpdateTime : TimeInterval = 0
override func didMove(to view: SKView) {
addChild(label)
}
override func update(_ currentTime: TimeInterval) {
if (self.lastUpdateTime == 0) {
self.lastUpdateTime = currentTime
}
let seconds = Int(currentTime - lastUpdateTime)
label.text = "Time Elapsed:\n\(seconds)"
label.numberOfLines = 2
}
}
struct ContentView: View {
@State private var showingLevelChooser = false
var scene: SKScene {
let scene = GameScene()
scene.size = CGSize(width: 300, height: 400)
scene.anchorPoint = CGPoint(x: 0.5, y: 0.5)
scene.scaleMode = .fill
return scene
}
var body: some View {
ZStack {
SpriteView(scene: scene, isPaused: showingLevelChooser)
.ignoresSafeArea()
VStack {
Button("Level Chooser") {
showingLevelChooser.toggle()
}
Spacer()
}
}
.sheet(isPresented: $showingLevelChooser) {
VStack {
Button("Cancel") {
showingLevelChooser.toggle()
}
Text("Level Chooser")
}
}
}
}
CodePudding user response:
There are two issues to take care of here. The first is that you want to have a reference to your SKScene
that will stick around. Making it a computed property of the View
will not work (as you're experiencing) because the View
is transitive and every time it gets reloaded, you'll get a new SKScene
.
There are multiple acceptable solutions to this, but I chose to encapsulate the SKScene
in an ObservableObject
that you can hold a reference to via StateObject
. You could even experiment with making the SKScene
an ObservableObject
itself (not shown here).
Secondly, your logic for determine/showing the "pause" on screen was going to be a little tough to accurately see, because it always just displayed the elapsed time -- there was no logic involved to not count the time during the pause. I replaced it with a simple counter that shows the number of updates. That way, you can clearly tell that the scene has indeed been paused (and doesn't update).
class SceneStore : ObservableObject {
var scene = GameScene()
init() {
scene.size = CGSize(width: 300, height: 400)
scene.anchorPoint = CGPoint(x: 0.5, y: 0.5)
scene.scaleMode = .fill
}
}
class GameScene: SKScene {
private let label = SKLabelNode(text: "Updates: 0")
private var updates = 0
override func didMove(to view: SKView) {
addChild(label)
}
override func update(_ currentTime: TimeInterval) {
updates = 1
label.text = "Updates: \(updates)"
label.numberOfLines = 2
}
}
struct ContentView: View {
@State private var showingLevelChooser = false
@StateObject private var sceneStore = SceneStore()
var body: some View {
ZStack {
SpriteView(scene: sceneStore.scene, isPaused: showingLevelChooser)
.ignoresSafeArea()
VStack {
Button("Level Chooser") {
showingLevelChooser.toggle()
}
Spacer()
}
}
.sheet(isPresented: $showingLevelChooser) {
VStack {
Button("Cancel") {
showingLevelChooser.toggle()
}
Text("Level Chooser")
}
}
}
}