SwiftUI 按钮点击重置 SpriteKit 动画 - 这是一个错误吗?
SwiftUI button taps reset SpriteKit animations - is this a bug?
我想在我的 SwiftUI 应用程序中使用动画背景。我通过使用 SpriteKit GameScene 作为我的背景,并使用 SKActions 逐渐淡入和淡出不同的图像来实现这一点。
但是,我注意到当我点击我的 SwiftUI 应用程序中的任何按钮时,它会完全重置动画。
这是一个错误吗?有人知道解决这个问题的方法吗?
这是我的 SwiftUI 的简化版本 ContentView.swift:
struct ContentView: View {
var scene: SKScene {
let scene = GameScene()
scene.size = CGSize(width: 1125, height: 2436)
scene.scaleMode = .fill
return scene
}
var body: some View {
SpriteView(scene: scene)
.frame(width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height)
.ignoresSafeArea()
}
}
这是我用来设置背景动画的代码:
// Animations
let fadeOutAnimation: SKAction = SKAction.fadeOut(withDuration: 5)
let fadeInAnimation: SKAction = SKAction.fadeIn(withDuration: 5)
let wait5Animation: SKAction = SKAction.wait(forDuration: 5)
let wait10Animation:SKAction = SKAction.wait(forDuration: 10)
let wait20Animation:SKAction = SKAction.wait(forDuration: 20)
// Repeating Background Actions
let firstRepeatingSequence = SKAction.repeatForever(SKAction.sequence([fadeOutAnimation, wait20Animation, fadeInAnimation]))
let secondRepeatingSequence = SKAction.repeatForever(SKAction.sequence([fadeOutAnimation, wait10Animation, fadeInAnimation, wait10Animation]))
let thirdRepeatingSequence = SKAction.repeatForever(SKAction.sequence([fadeOutAnimation, fadeInAnimation, wait20Animation]))
//Access bg sprites
let bg1 = SKSpriteNode(imageNamed: "blue1")
bg1.anchorPoint = CGPoint(x: 0, y: 0)
let bg2 = SKSpriteNode(imageNamed: "red1")
bg2.anchorPoint = CGPoint(x: 0, y: 0)
let bg3 = SKSpriteNode(imageNamed: "green1")
bg3.anchorPoint = CGPoint(x: 0, y: 0)
self.addChild(bg1)
self.addChild(bg2)
self.addChild(bg3)
// Run Background forever
bg3.run(firstRepeatingSequence)
bg2.run(SKAction.sequence([wait5Animation, secondRepeatingSequence]))
bg1.run(SKAction.sequence([wait10Animation, thirdRepeatingSequence]))
我相信它正在重绘视图,当它这样做时,它正在重新初始化您的场景。使您的场景成为 @State 变量并在 init 方法中对其进行初始化。
struct ContentView: View {
@State var scene = GameScene()
init() {
scene.size = CGSize(width: 1125, height: 2436)
scene.scaleMode = .fill
}
var body: some View {
SpriteView(scene: scene)
.frame(width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height)
.ignoresSafeArea()
}
}
我想在我的 SwiftUI 应用程序中使用动画背景。我通过使用 SpriteKit GameScene 作为我的背景,并使用 SKActions 逐渐淡入和淡出不同的图像来实现这一点。
但是,我注意到当我点击我的 SwiftUI 应用程序中的任何按钮时,它会完全重置动画。
这是一个错误吗?有人知道解决这个问题的方法吗?
这是我的 SwiftUI 的简化版本 ContentView.swift:
struct ContentView: View {
var scene: SKScene {
let scene = GameScene()
scene.size = CGSize(width: 1125, height: 2436)
scene.scaleMode = .fill
return scene
}
var body: some View {
SpriteView(scene: scene)
.frame(width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height)
.ignoresSafeArea()
}
}
这是我用来设置背景动画的代码:
// Animations
let fadeOutAnimation: SKAction = SKAction.fadeOut(withDuration: 5)
let fadeInAnimation: SKAction = SKAction.fadeIn(withDuration: 5)
let wait5Animation: SKAction = SKAction.wait(forDuration: 5)
let wait10Animation:SKAction = SKAction.wait(forDuration: 10)
let wait20Animation:SKAction = SKAction.wait(forDuration: 20)
// Repeating Background Actions
let firstRepeatingSequence = SKAction.repeatForever(SKAction.sequence([fadeOutAnimation, wait20Animation, fadeInAnimation]))
let secondRepeatingSequence = SKAction.repeatForever(SKAction.sequence([fadeOutAnimation, wait10Animation, fadeInAnimation, wait10Animation]))
let thirdRepeatingSequence = SKAction.repeatForever(SKAction.sequence([fadeOutAnimation, fadeInAnimation, wait20Animation]))
//Access bg sprites
let bg1 = SKSpriteNode(imageNamed: "blue1")
bg1.anchorPoint = CGPoint(x: 0, y: 0)
let bg2 = SKSpriteNode(imageNamed: "red1")
bg2.anchorPoint = CGPoint(x: 0, y: 0)
let bg3 = SKSpriteNode(imageNamed: "green1")
bg3.anchorPoint = CGPoint(x: 0, y: 0)
self.addChild(bg1)
self.addChild(bg2)
self.addChild(bg3)
// Run Background forever
bg3.run(firstRepeatingSequence)
bg2.run(SKAction.sequence([wait5Animation, secondRepeatingSequence]))
bg1.run(SKAction.sequence([wait10Animation, thirdRepeatingSequence]))
我相信它正在重绘视图,当它这样做时,它正在重新初始化您的场景。使您的场景成为 @State 变量并在 init 方法中对其进行初始化。
struct ContentView: View {
@State var scene = GameScene()
init() {
scene.size = CGSize(width: 1125, height: 2436)
scene.scaleMode = .fill
}
var body: some View {
SpriteView(scene: scene)
.frame(width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height)
.ignoresSafeArea()
}
}