SpriteKit 和 SwiftUI。 GameScene 功能无法通过 UI 按钮工作

SpriteKit and SwiftUI. GameScene func not working from UI button

我在 SwiftUI 视图中显示了一个 SKScene。 尝试使用SwiftUI按钮通过简单的功能将Spritenode添加到场景中。

如果我 运行 来自 GameScene 的函数当然可以正常工作。

但是,如果我尝试从 SwiftUI 按钮访问该功能,则没有任何反应。函数 运行s(Print"image tapped" 正在调试中 window)但是 Sprite 没有出现。

为什么会这样,我该如何解决?

我的代码

import SwiftUI
import SpriteKit

class GameScene: SKScene {
    override func didMove(to view: SKView) {
        
        
        physicsBody = SKPhysicsBody(edgeLoopFrom: frame)
        //ball()
        
    }
    
    func ball() {
        
        let ball = SKShapeNode(circleOfRadius: 30)
        ball.position = CGPoint(x: 100, y: 100)
        ball.fillColor = .blue
        self.addChild(ball)
    }
}

struct ContentView: View {
    
    var scene: SKScene {
        let scene = GameScene()
        scene.size = CGSize(width: 800, height: 930)
        scene.scaleMode = .fill
        scene.backgroundColor = .red
        
        return scene
    }
    
    var body: some View {
        VStack {
            HStack {
                Button {
                    let makeBall = GameScene()
                    makeBall.ball()
                            print("Image tapped!")
                        } label: {
                            Image("playButton")
                                
                    }
                
                Button {
                            print("Image tapped!")
                        } label: {
                            Image("pauseButton")
                               
                    }
                
                
            }
            SpriteView(scene: scene)
                .frame(width: 800, height: 930, alignment: .center)
            
        }
        
        
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

两个问题:

  1. 您的 scene 是计算出来的 属性,因此您每次 尝试在 SpriteView 中使用它时都会重新创建场景
  2. 当您尝试添加球时,您正在创建一个 场景。这应该添加到 current 场景,而不是新实例。

scene改为:

let scene: GameScene = {
    let scene = GameScene()
    scene.size = CGSize(width: 800, height: 930)
    scene.scaleMode = .fill
    scene.backgroundColor = .red

    return scene
}()

并将暂停按钮上的动作更改为:

scene.ball()
print("Image tapped!")

旁注:对于这样的固定场景大小,您必须小心 - 由于场景大小太大,您只能在 iPad 屏幕上真正看到 play/pause 按钮。请考虑将其保持在特定的宽高比,然后使其适应屏幕。