在 SwiftUI 视图中显示粒子发射器

Display particle emitter in SwiftUI View

尝试使用 SKScene 在视图中显示粒子发射器 spritekit 文件。

当前代码

struct ContentView: View {
 
    var scene: SKScene {
            let scene = SKScene(fileNamed: "magicSparkles")!
            scene.size = CGSize(width: 400, height: 400)
            scene.scaleMode = .fill
            return scene
        }
    
    var body: some View {
        VStack {
            Text("Hello, World!")
                .padding()
            SpriteView(scene: scene)
                       .frame(width: 400, height: 400)
                       .edgesIgnoringSafeArea(.all)
        }
    }
}

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

每当我尝试这样做时,模拟器都会抛出错误。

Moodie2 WatchKit Extension crashed due to an uncaught exception NSInvalidArgumentException. Reason: -[SKEmitterNode setScaleMode:]: unrecognized selector sent to instance 0x600003e981c0.

尝试不使用 SKScene(fileNamed: "magicSparkles"),将 SKScene 替换为 SKEmitterNode。不确定代码的其余部分是否 运行 正确

我对这个问题有部分答案,虽然它有一个我一直无法在手表上解决的问题。我在 iOS 设备上将 Spritekit 与 SwiftUI 结合使用,但从未在 watchOS 上使用过。我了解到的第一件事是 func didMove() 在 watchOS 上不存在,所以你必须使用 func sceneDidLoad() 来实现。以下代码将在手表上放置一个发射器:

import SwiftUI
import SpriteKit

struct ContentView: View {
    var scene = EmitterScene()

    var body: some View {
        GeometryReader { geometry in
       SpriteView(scene: scene)

         
        }
    }
}

class EmitterScene: SKScene {
    
    override func sceneDidLoad() {
        if let emitter = SKEmitterNode(fileNamed: "magicSparkles"){
            emitter.position = CGPoint(x: frame.width / 2, y: frame.height / 2)
            emitter.zPosition = -1
            addChild(emitter)
        }
    }
}

我遇到的问题是发射器粒子显示不正确。它们太大了,你必须调整发射器以使其足够密集以使其定期显示,但它们似乎被放大到与表盘本身几乎相同的大小。我不知道如何解决这个问题。

所以有两件事:

  1. SpriteKit 内容不显示在 Xcode 预览中,仅在模拟器应用程序或设备上显示,供参考!
  2. 您只需继续将粒子添加到 SpriteKit 场景并将其放置在您的视图中,而不仅仅是一个发射器。

代码(忽略花形):


import SwiftUI
import SpriteKit

struct flowerhshape: Shape {
    func path(in rect: CGRect) -> Path {
        var path = Path()
                let width = rect.size.width
                let height = rect.size.height
                path.move(to: CGPoint(x: 0, y: 0.66071*height))
                path.addCurve(to: CGPoint(x: 0.19416*width, y: 0.83929*height), control1: CGPoint(x: 0, y: 0.75929*height), control2: CGPoint(x: 0.08698*width, y: 0.83929*height))
                path.addCurve(to: CGPoint(x: 0.30444*width, y: 0.80786*height), control1: CGPoint(x: 0.23532*width, y: 0.83929*height), control2: CGPoint(x: 0.2726*width, y: 0.82786*height))
                path.addLine(to: CGPoint(x: 0.30288*width, y: 0.82143*height))
                path.addCurve(to: CGPoint(x: 0.49704*width, y: height), control1: CGPoint(x: 0.30288*width, y: 0.92*height), control2: CGPoint(x: 0.38987*width, y: height))
                path.addCurve(to: CGPoint(x: 0.6912*width, y: 0.82143*height), control1: CGPoint(x: 0.60422*width, y: height), control2: CGPoint(x: 0.6912*width, y: 0.92*height))
                path.addLine(to: CGPoint(x: 0.68965*width, y: 0.80786*height))
                path.addCurve(to: CGPoint(x: 0.79993*width, y: 0.83929*height), control1: CGPoint(x: 0.72071*width, y: 0.82786*height), control2: CGPoint(x: 0.75876*width, y: 0.83929*height))
                path.addCurve(to: CGPoint(x: 0.99409*width, y: 0.66071*height), control1: CGPoint(x: 0.9071*width, y: 0.83929*height), control2: CGPoint(x: 0.99409*width, y: 0.75929*height))
                path.addCurve(to: CGPoint(x: 0.88302*width, y: 0.5*height), control1: CGPoint(x: 0.99409*width, y: 0.58929*height), control2: CGPoint(x: 0.94826*width, y: 0.52857*height))
                path.addCurve(to: CGPoint(x: 0.99409*width, y: 0.33929*height), control1: CGPoint(x: 0.94826*width, y: 0.47143*height), control2: CGPoint(x: 0.99409*width, y: 0.41071*height))
                path.addCurve(to: CGPoint(x: 0.79993*width, y: 0.16071*height), control1: CGPoint(x: 0.99409*width, y: 0.24071*height), control2: CGPoint(x: 0.9071*width, y: 0.16071*height))
                path.addCurve(to: CGPoint(x: 0.68965*width, y: 0.19214*height), control1: CGPoint(x: 0.75876*width, y: 0.16071*height), control2: CGPoint(x: 0.72149*width, y: 0.17214*height))
                path.addLine(to: CGPoint(x: 0.6912*width, y: 0.17857*height))
                path.addCurve(to: CGPoint(x: 0.49704*width, y: 0), control1: CGPoint(x: 0.6912*width, y: 0.08*height), control2: CGPoint(x: 0.60422*width, y: 0))
                path.addCurve(to: CGPoint(x: 0.30288*width, y: 0.17857*height), control1: CGPoint(x: 0.38987*width, y: 0), control2: CGPoint(x: 0.30288*width, y: 0.08*height))
                path.addLine(to: CGPoint(x: 0.30444*width, y: 0.19214*height))
                path.addCurve(to: CGPoint(x: 0.19416*width, y: 0.16071*height), control1: CGPoint(x: 0.27337*width, y: 0.17214*height), control2: CGPoint(x: 0.23532*width, y: 0.16071*height))
                path.addCurve(to: CGPoint(x: 0, y: 0.33929*height), control1: CGPoint(x: 0.08698*width, y: 0.16071*height), control2: CGPoint(x: 0, y: 0.24071*height))
                path.addCurve(to: CGPoint(x: 0.11106*width, y: 0.5*height), control1: CGPoint(x: 0, y: 0.41071*height), control2: CGPoint(x: 0.04582*width, y: 0.47143*height))
                path.addCurve(to: CGPoint(x: 0, y: 0.66071*height), control1: CGPoint(x: 0.04582*width, y: 0.52857*height), control2: CGPoint(x: 0, y: 0.58929*height))
                path.closeSubpath()
                path.move(to: CGPoint(x: 0.6912*width, y: 0.5*height))
                path.addCurve(to: CGPoint(x: 0.49704*width, y: 0.32143*height), control1: CGPoint(x: 0.6912*width, y: 0.40143*height), control2: CGPoint(x: 0.60422*width, y: 0.32143*height))
                path.addCurve(to: CGPoint(x: 0.30288*width, y: 0.5*height), control1: CGPoint(x: 0.38987*width, y: 0.32143*height), control2: CGPoint(x: 0.30288*width, y: 0.40143*height))
                path.addCurve(to: CGPoint(x: 0.49704*width, y: 0.67857*height), control1: CGPoint(x: 0.30288*width, y: 0.59857*height), control2: CGPoint(x: 0.38987*width, y: 0.67857*height))
                path.addCurve(to: CGPoint(x: 0.6912*width, y: 0.5*height), control1: CGPoint(x: 0.60422*width, y: 0.67857*height), control2: CGPoint(x: 0.6912*width, y: 0.59857*height))
                path.closeSubpath()
                return path
    }
}



struct ContentView: View {
    
    var scene: SKScene {
        let scene = SKScene(fileNamed: "MyScene")!
        scene.scaleMode = .resizeFill
        return scene
    }

    var body: some View {
            
        VStack (alignment: .center, spacing: 4) {
            SpriteView(scene: scene)
            .aspectRatio(contentMode: .fill)
            .frame(width: 120, height: 120, alignment: .top)
            .rotationEffect(.degrees(180))
//            .withAnimation(Animation.linear(duration: 1).repeatForever())
            .clipShape(flowerhshape())
           
            Text("Honor thy error as a hidden intention")
                .font(.caption2)
                .multilineTextAlignment(.center)
                .fixedSize(horizontal: false, vertical: true)
                .frame(alignment: .top)
                
        }
        .padding(.top, 12.0)
        .frame(alignment: .bottom)

    }
    
}

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