我想使用 SwiftUI 按钮调用 SpriteKit 类中定义的方法。我在类上使用
@Observable
宏,并在 SwiftUI 内的类实例上使用 @State
。
一些类属性是可以访问的,但不是我想要使用的方法。调用它会抛出 3 个编译器错误:
使用
@Bindable
代替 @State
并不能解决问题。
我错过了什么?
SwiftUI 代码:
import SwiftUI
import SpriteKit
struct ActionReplay: View {
@State var myActionScene: SKScene = ActionScene(size: CGSize(width: 1000, height: 1000))
var body: some View {
ZStack {
SpriteView(scene: myActionScene, debugOptions: [.showsFPS, .showsNodeCount])
.ignoresSafeArea()
VStack {
Spacer()
HStack {
Button(action: {
myActionScene.resetToInitialConditions() // Errors here
}, label: {
Text("Reset")
})
.buttonStyle(.bordered)
}
}
}
}
}
数据和SpriteKit:
struct InitialConditions {
var position: CGPoint = .zero
var rotation: CGFloat = 5
var velocity: CGVector = CGVector(dx: 0, dy: 0)
var angularVelocity: CGFloat = 0
}
@Observable class ActionScene: SKScene {
var initialConditions = InitialConditions()
var baseObject: SKSpriteNode!
var ground: SKSpriteNode!
override init(size: CGSize) {
super.init(size: size)
self.scaleMode = .resizeFill
self.anchorPoint = CGPoint(x: 0.5, y: 0.5)
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func didMove(to view: SKView) {
backgroundColor = .white
createObjects()
}
func createObjects() {
baseObject = SKSpriteNode(color: .red, size: CGSize(width: 60, height: 60))
baseObject.anchorPoint = CGPoint(x: 0.5, y: 0.5)
baseObject.position = initialConditions.position
baseObject.zRotation = initialConditions.rotation
baseObject.physicsBody = SKPhysicsBody(rectangleOf: baseObject.size)
baseObject.physicsBody?.restitution = 1.1
baseObject.physicsBody?.linearDamping = 0
addChild(baseObject)
ground = SKSpriteNode(color: .darkGray, size: CGSize(width: 370, height: 10))
ground.position = CGPoint(x: .zero, y: -300)
ground.physicsBody = SKPhysicsBody(rectangleOf: ground.size)
ground.physicsBody?.affectedByGravity = false
ground.physicsBody?.isDynamic = false
addChild(ground)
}
func resetToInitialConditions() {
baseObject.physicsBody?.velocity = initialConditions.velocity
baseObject.physicsBody?.angularVelocity = initialConditions.angularVelocity
baseObject.position = initialConditions.position
baseObject.zRotation = initialConditions.rotation
}
// Testing the method I want to call
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
resetToInitialConditions()
}
}
您已将
@State
定义为:
@State var myActionScene: SKScene = ActionScene(size: CGSize(width: 1000, height: 1000))
这告诉编译器
myActionScene
是一个SKScene
。但是,实际上,您有一个 SKScene
的 子类,称为
ActionScene
。
因为你告诉编译器它实际上只是一个
SKScene
(从技术上讲,它是 ActionScene
的超类),它认为唯一可用的方法/属性是在 SKScene
上定义的方法/属性。如果您想访问 ActionScene
上定义的内容,您必须告诉编译器它是什么:
@State var myActionScene: ActionScene = ActionScene(size: CGSize(width: 1000, height: 1000))
或者,编译器甚至会为你推断类型:
@State var myActionScene = ActionScene(size: CGSize(width: 1000, height: 1000))