从SwiftUI中调用SpriteKit方法

lymgl2op  于 5个月前  发布在  Swift
关注(0)|答案(1)|浏览(41)

我想调用一个在SpriteKit类中定义的方法,这个类有一个SwiftUI按钮。我在这个类上使用了@Observable宏,在SwiftUI中使用了@State作为类示例。
一些类属性是可访问的,但不是我想使用的方法。调用它会引发3个编译器错误:

  • 无法调用非函数类型“Binding”的值
  • 引用下标“subscript(dynamicMember:)”需要 Package “Binding”
  • 类型“SKScene”的值没有使用根类型“SKScene”的键路径的动态成员“resetToInitialConditions”

使用@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()
    }
}

odopli94

odopli941#

您已将@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))

相关问题