SKAction 仅在睡眠后或 运行 调试器时运行

SKAction only runs after sleep or while running debugger

我正在尝试使用 SpriteKit 制作一个暂停菜单,当玩家继续游戏时,它会动画(移动)出屏幕。

我创建了一个 SKAction 并且 运行 它开始时是这样的:

let duration = TimeInterval(0.5)
let moveAction = SKAction.move(to: CGPoint(x: 0, y: 495) , duration: 
duration)
pauseScroll?.run(moveAction) 

pauseScroll 初始化为:

weak var pauseScroll: SKSpriteNode?

override init(size: CGSize) {
  ...
  let pauseScene = SKScene(fileNamed: "PauseMenu")!
  pauseScroll = pauseScene.childNode(withName: "PauseScroll") as? 
  SKSpriteNode
  pauseScroll?.position = CGPoint(x: 0, y: 495)
  pauseScroll?.zPosition = 1000
  pauseScroll?.move(toParent: self)
}

我在这里所做的是将另一个 spritekit.scene 文件中的 pauseScroll UI 布置为实际的 GameScene,其中所有 运行 都是在代码中完成的。然后我将它带过来并通过调用 .move(toParent: self).

将它添加到 GameScene

问题是我可以很好地引用 pauseScroll,我可以修改它,例如改变它的位置,给它一个物理体和碰撞掩码,在 pauseScroll 中包含的节点上注册点击等等。看起来除了 运行 SKActions 之外的所有内容。

我正在 运行 同时为其他 SKSpriteNode 设置 SKActions,它们工作正常,当然它们的初始化不同,因为它们都是在 .init 中的代码中设置的,例如:

var background: SKSpriteNode!

override init(size: CGSize) {
  ...
  background = SKSpriteNode(imageNamed: "GameBackground")
  background.size = size
  addChild(background)
}

然后我以与在触摸开始时做任何其他事情相同的方式为它们制作动画:

let colorAction = SKAction.colorize(withColorBlendFactor: 0.4, 
duration: duration)
background?.run(colorAction)

有趣的是,如果我 运行 sleep(1) 在函数的其他任何地方,其中 SKAction 在 pauseScroll 上 运行;然后滚动动画并按原样向上移出屏幕。因此,这似乎是一个竞争条件,但我不知道它在等待什么。

当打印 pauseScroll 和 moveAction 的值时,无论我是否睡眠 (1),我都会得到相同的结果。

这是正在发生的错误:

如果我将 sleep(1) 添加到 touches begin 中的任何位置,那么会发生同样的事情,只是整个应用程序会等待 1 秒,然后滚动会按预期向上移动到屏幕顶部。

如有必要,我很乐意提供更多代码。

当您使用 .move(toParent: self) 将 children 移动到新的 parent 时,尝试将每个 child 上的 isPaused 设置为 false。我怀疑当您从场景中加载它们时,所有 children 都暂停了,并且当场景首次出现时,SpriteKit 可能会自动将 isPaused 设置为 false。

tempScene.children.forEach() { child in
            child.isPaused = false
            child.move(toParent: newParentNode)
}

尝试在父级的 init() 方法中设置 isPaused

将其视为 UIView - 如果父级设置为隐藏,则子视图(无论是否隐藏)都不会显示。

我运行遇到这个问题,将"isPaused"设置为false解决了这个问题,我发现不需要为所有子节点设置,而只需要为子节点移动到的父节点。

例如,如果我有带有三个子精灵节点的 sprite1,并且我想让 sprite2 成为这三个子精灵节点的新父节点,那么在使用 move(toParent) 之后,只需将 sprite2 的 isPaused 设置为 false。

这就是我为解决问题所做的全部工作。这似乎表明,通过设计,接收父项及其子项的操作在使用 move(toParent) 时会自动暂停。