Spritekit 和 swiftui,以更好的方式改变场景

Spritekit and swiftui, change scene a better way

我写了这几行简单的代码来使用 SpriteKit 在 Swiftui 中的 2 个场景之间切换,我试图了解是否有一种(更好的)不同的方式来使用按钮从一个场景切换到另一个场景。

struct ContentView: View {
    @StateObject var firstscene = FirstScene()
    @StateObject var secondscene = SecondScene()
    @State var changeScene = false
    var body: some View {
        ZStack{
            
            if changeScene {
                SpriteView(scene: firstscene)
            } else {
                SpriteView(scene: secondscene)
            }
            
            Button {
                changeScene.toggle()
            } label: {
                Text("Change")
            }
        }
    }
}

// 使用 SKscene

的子 class 创建的 2 SKScene

class FirstScene: SKScene, ObservableObject {
    let firstScene = SKScene(fileNamed: "FirstScene")
    override func didMove(to view: SKView) {
        scene?.view?.presentScene(firstScene)
    }
    
}
class SecondScene: SKScene, ObservableObject {
    let secondScene = SKScene(fileNamed: "SecondScene")
    override func didMove(to view: SKView) {
        scene?.view?.presentScene(secondScene)
    }
}


现在我的疑问是,我正在使用 var changeScene 更改 contentView 中的 SpriteView,是否可以使用另一种方法以其他方式完成相同的事情?

愿意接受任何建议,我会尝试理解这个框架。

谢谢

您正在使用标准的视图切换方式。您可以像这样清理代码:

struct ContentView: View {
    @State var changeScene = false
    var body: some View {
        ZStack{
                SpriteView(scene: (changeScene ? FirstScene() : SecondScene())) // this is a terniary operator 
        
            Button {
                changeScene.toggle()
            } label: {
                Text("Change")
            }
        }
    }
}

新视图不需要是@StateObjects。您可以直接在您的视图中调用视图类型。

注意:我不在电脑旁,所以没有测试。

iOS14,Swift5

这是经过测试的,来自这篇文章。

https://betterprogramming.pub/build-a-game-of-chess-with-spritekit-3229c23bdba0

进口SwiftUI 导入 SpriteKit

struct ContentView: View {

@State var switcher = false

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

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

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