SpriteKit 帧周期中何时调用触摸事件?

Posted

技术标签:

【中文标题】SpriteKit 帧周期中何时调用触摸事件?【英文标题】:When are touch events called in the SpriteKit frame-cycle? 【发布时间】:2021-12-19 04:46:48 【问题描述】:

在 SpriteKit 场景中,系统会自动调用许多方法,您可以在游戏场景中覆盖它们以实现自定义行为。例如:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) 
    for t in touches  self.touchDown(atPoint: t.location(in: self)) 


override func update(_ currentTime: TimeInterval) 
    // Called before each frame is rendered


override func didFinishUpdate() 
    // Do some stuff immediately before rendering

Apple's documentation for SpriteKit 有这个有用的图表,它显示了在每一帧中调用这些方法的顺序:

但是,此讨论不包括任何触摸事件,例如touchesBegan(_:with:)。我试图弄清楚这些触摸事件相对于 SpriteKit 帧周期中的其他事件在什么时候被调用。我找不到任何给出答案的 Apple 文档。

我能找到的唯一提及是在上面链接的文档中,它说:

场景的update(_:)方法被调用,时间已经过去了 在模拟中。这是实施您自己的主要场所 游戏内模拟,包括输入处理、人工智能、 游戏脚本和其他类似的游戏逻辑。通常,你使用这个 对节点进行更改或在节点上运行操作的方法。

虽然它说update(_:) 方法是实现输入处理的地方,但这似乎有点误导,因为在ios 上使用像touchesBegan(_:with:) 这样的触摸事件方法来捕获触摸输入是常见的做法。 SKScene 继承了这些触摸方法作为UIResponder 的子类(SKScene > SKEffectNode > SKNode > UIResponder)。但我正在尝试确定何时按照场景的帧周期事件的顺序调用这些方法。当您尝试在场景的帧周期内以特定顺序发生某些与触摸相关的事情时,了解这一点非常重要。

我的猜测是在帧周期开始时调用触摸方法,就在调用update(_:) 方法之前。但我正在寻找一个比我的直觉更明确的答案。

【问题讨论】:

【参考方案1】:

经过一些实验,我确定触摸事件是在didFinishUpdate() 之后、update(_:) 之前调用的。

import SpriteKit

class GameScene: SKScene 
    var frameCount = 0
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) 
        print("in touchesBegan, frame count is \(frameCount)")
    
    
    override func update(_ currentTime: TimeInterval) 
        frameCount += 1
        print("in update, preparing frame \(frameCount)")
    
    
    override func didFinishUpdate() 
        print("in didFinishUpdate, frame count is \(frameCount)")
    

当我运行此代码然后触摸屏幕时,控制台打印的内容如下:

您可以看到触摸事件仍在打印与上次更新时相同的帧计数值。下一条运行的打印消息来自 update(_:) 方法,其中包含更新的帧计数值。

现在,这并不能告诉我们 touchesBegan(_:with:) 方法是在 SpriteKit 帧周期结束时调用的,还是在帧周期开始时调用的。我们只知道它是在调用didFinishUpdate()update(_:) 之间的某个地方调用的。但这个答案对于大多数用途来说应该足够精确。

我会进一步说,假设在帧循环开始时调用触摸方法是非常安全的。在循环结束时调用它们是没有意义的,因为那时我们不能使用它们来做任何有用的事情,因为我们不能在循环的那个时候运行任何代码。在帧循环开始时调用触摸事件是最有意义的,这样我们就可以在update(_:) 方法(或其他帧循环方法之一)中使用它们。

【讨论】:

以上是关于SpriteKit 帧周期中何时调用触摸事件?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 SceneKit 的渲染队列中处理触摸事件

Corona 中的触摸事件何时有“取消”阶段?

quick-cocos2d-x游戏开发13——节点生命周期事件,帧事件等其他事件

SpriteKit:如何检测从节点外部开始的节点上的触摸

SKView bounds.size 在触摸事件时反转(Sprite Kit)

SpriteKit 中的触摸持续时间