Swift 3 (SpriteKit): 停止永远循环的 SKAction 有延迟
Swift 3 (SpriteKit): Stopping a forever looping SKAction has a delay
我一直在努力做一个永远的 运行ning SKAction,我可以随时停止。我是这样做的:
override func didMove(to view: SKView) {
run(SKAction.repeatForever (
SKAction.sequence ([
SKAction.run(drawFrame),
SKAction.wait(forDuration: 0.01),
])), withKey: "frameDrawing"
)
}
然后在 drawFrame 函数中,我像这样停止 SKAction:
func drawFrame() {
//(code)
if stop {
removeAction(forKey: "frameDrawing")
}
}
出于某种原因,SKAction 仅在停止变为真后 运行 3 或 4 次时才停止。我希望它在 stop 设置为 true 时立即停止,而不是在重复 3 或 4 次之后。
如果有人知道如何解决这个问题,请告诉我,因为我已经尝试了很多方法,但他们从未解决过这个问题。谢谢!
编辑:这是我的代码:
var drawingFrame = SKAction()
class GameScene: SKScene, SKPhysicsContactDelegate {
override func didMove(to view: SKView) {
drawingFrame = SKAction.repeatForever (
SKAction.sequence ([
SKAction.run(drawFrame),
SKAction.wait(forDuration: 0.03),
]))
run(drawingFrame)
}
func drawFrame() {
//(code)
if stop {
drawingFrame.speed = 0.0
}
}
如果您想知道为什么我一开始就将 SKAction drawingFrame 设置为空 SKAction,那是因为我需要在两个函数之前定义 SKAction。否则,不会为这两个函数定义它。
为遇到同样问题的任何人编辑:我已经用我自己的想法和@appzYourLife 的解决方案解决了这个问题。每次都有效的最有效方法是仅 运行 如果 stop 等于 false 的代码。但是,请确保停止程序的 if 语句在该括号之外,以便 SKAction 最终停止。这是工作代码:
var drawingFrame = SKAction()
class GameScene: SKScene, SKPhysicsContactDelegate {
override func didMove(to view: SKView) {
drawingFrame = SKAction.repeatForever (
SKAction.sequence ([
SKAction.run(drawFrame),
SKAction.wait(forDuration: 0.03),
]))
run(drawingFrame)
}
func drawFrame() {
if stop = false {
//(code)
}
if stop {
removeAllActions()
}
}
如果您愿意,可以对 stop = false 语句使用 if else 语句。
尝试创建对 SKAction 的引用,并在您希望它停止时对其调用速度更改(至 0.0)。这两者都比查找操作名称然后将其删除要快。但是在 0.01 时,您已经以快于帧速率 (0.01666) 的速度重复它,因此无论您停止得有多好,您总是会至少获得一次额外的动作迭代。
类似于:
let myAction = SKAction.repeatForever (
SKAction.sequence ([
SKAction.run(drawFrame),
SKAction.wait(forDuration: 0.01),
]))
//when you want to run it
run(myAction)
// when you want to stop it:
myAction.speed = 0.0
您可以删除当前节点上的所有操作运行。这不仅会立即删除序列动作,还会立即删除嵌入的动作。
func drawFrame() {
if stop {
removeAllActions()
}
}
我没有确切的解释为什么 drawFrame() 目前被多次调用(但我会尝试发现 :D)...无论如何,试试这个代码:
import SpriteKit
class GameScene: SKScene, SKPhysicsContactDelegate {
var stop = false
override func didMove(to view: SKView) {
run(SKAction.repeatForever (
SKAction.sequence ([
SKAction.run({[unowned self] in
if self.stop {
self.action(forKey: "frameDrawing")?.speed = 0.0
}else{
self.drawFrame()
}
}),
SKAction.wait(forDuration:0.03),
])), withKey: "frameDrawing"
)
}
func drawFrame() {
//(code)
print("drawFrame")
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
stop = !stop
print(stop ? "stopped": "running")
if !stop {
self.action(forKey: "frameDrawing")?.speed = 1.0
}
}
}
使用 touchesBegan 切换暂停模式。
我一直在努力做一个永远的 运行ning SKAction,我可以随时停止。我是这样做的:
override func didMove(to view: SKView) {
run(SKAction.repeatForever (
SKAction.sequence ([
SKAction.run(drawFrame),
SKAction.wait(forDuration: 0.01),
])), withKey: "frameDrawing"
)
}
然后在 drawFrame 函数中,我像这样停止 SKAction:
func drawFrame() {
//(code)
if stop {
removeAction(forKey: "frameDrawing")
}
}
出于某种原因,SKAction 仅在停止变为真后 运行 3 或 4 次时才停止。我希望它在 stop 设置为 true 时立即停止,而不是在重复 3 或 4 次之后。
如果有人知道如何解决这个问题,请告诉我,因为我已经尝试了很多方法,但他们从未解决过这个问题。谢谢!
编辑:这是我的代码:
var drawingFrame = SKAction()
class GameScene: SKScene, SKPhysicsContactDelegate {
override func didMove(to view: SKView) {
drawingFrame = SKAction.repeatForever (
SKAction.sequence ([
SKAction.run(drawFrame),
SKAction.wait(forDuration: 0.03),
]))
run(drawingFrame)
}
func drawFrame() {
//(code)
if stop {
drawingFrame.speed = 0.0
}
}
如果您想知道为什么我一开始就将 SKAction drawingFrame 设置为空 SKAction,那是因为我需要在两个函数之前定义 SKAction。否则,不会为这两个函数定义它。
为遇到同样问题的任何人编辑:我已经用我自己的想法和@appzYourLife 的解决方案解决了这个问题。每次都有效的最有效方法是仅 运行 如果 stop 等于 false 的代码。但是,请确保停止程序的 if 语句在该括号之外,以便 SKAction 最终停止。这是工作代码:
var drawingFrame = SKAction()
class GameScene: SKScene, SKPhysicsContactDelegate {
override func didMove(to view: SKView) {
drawingFrame = SKAction.repeatForever (
SKAction.sequence ([
SKAction.run(drawFrame),
SKAction.wait(forDuration: 0.03),
]))
run(drawingFrame)
}
func drawFrame() {
if stop = false {
//(code)
}
if stop {
removeAllActions()
}
}
如果您愿意,可以对 stop = false 语句使用 if else 语句。
尝试创建对 SKAction 的引用,并在您希望它停止时对其调用速度更改(至 0.0)。这两者都比查找操作名称然后将其删除要快。但是在 0.01 时,您已经以快于帧速率 (0.01666) 的速度重复它,因此无论您停止得有多好,您总是会至少获得一次额外的动作迭代。
类似于:
let myAction = SKAction.repeatForever (
SKAction.sequence ([
SKAction.run(drawFrame),
SKAction.wait(forDuration: 0.01),
]))
//when you want to run it
run(myAction)
// when you want to stop it:
myAction.speed = 0.0
您可以删除当前节点上的所有操作运行。这不仅会立即删除序列动作,还会立即删除嵌入的动作。
func drawFrame() {
if stop {
removeAllActions()
}
}
我没有确切的解释为什么 drawFrame() 目前被多次调用(但我会尝试发现 :D)...无论如何,试试这个代码:
import SpriteKit
class GameScene: SKScene, SKPhysicsContactDelegate {
var stop = false
override func didMove(to view: SKView) {
run(SKAction.repeatForever (
SKAction.sequence ([
SKAction.run({[unowned self] in
if self.stop {
self.action(forKey: "frameDrawing")?.speed = 0.0
}else{
self.drawFrame()
}
}),
SKAction.wait(forDuration:0.03),
])), withKey: "frameDrawing"
)
}
func drawFrame() {
//(code)
print("drawFrame")
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
super.touchesBegan(touches, with: event)
stop = !stop
print(stop ? "stopped": "running")
if !stop {
self.action(forKey: "frameDrawing")?.speed = 1.0
}
}
}
使用 touchesBegan 切换暂停模式。