问题描述
我想在我的 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,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()
}
}