【发布时间】:2023-03-16 18:39:02
【问题描述】:
我正在制作一个交互式动画场景。我希望在进入时禁用现场的所有接触。然后,一旦场景中的对象(它们是子类节点)完成旋转/移动,我想重新启用屏幕上的所有触摸以允许交互。我已使用此代码禁用用户交互:
override func didMove(to view: SKView) {
setupNodes()
view?.isUserInteractionEnabled = false
spinLocations()
}
这是场景文件中 spinLocations 的代码:
func spinLocations() {
var allLocationArrays = [[String : CGPoint]]()
var previousArray = hiddenLocationPositions
for _ in 0...SearchConstant.numSpins {
let freshArray = generateNewLocationArray(previous: previousArray)
allLocationArrays.append(freshArray)
previousArray = freshArray
}
for (item, _) in hiddenLocationPositions {
let node = fgNode.childNode(withName: item) as! LocationNode
node.spin(position: allLocationArrays) // this is function below
}
hiddenLocationPositions = previousArray
}
这是节点类中动画的代码:
func spin(position: [[String : CGPoint]]) {
var allActions = [SKAction]()
for array in position {
let action = SKAction.move(to: array[self.name!]!, duration: 2.0)
allActions.append(action)
}
let allActionsSeq = SKAction.sequence(allActions)
self.run(SKAction.sequence([SKAction.wait(forDuration: 5.0), allActionsSeq, SKAction.run {
self.position = position[position.count - 1][self.name!]!
},]))
}
这是从此类将触摸传回主场景的代码:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
guard let parent = self.parent else { return }
}
如您所见,此处未禁用触摸。
我不想在runBlock 中添加“waitForDuration”SKAction 来更改上一个操作后的视图状态;我希望程序确定动画何时完成执行,然后重新启用触摸。
为了做到这一点,我认为使用完成处理程序可能会起作用,但它只会立即重新启用触摸(例如,处理处理程序旋转会导致再次检测到触摸)。以前,我也尝试禁用runBlock 中的视图,但当然,这是即时运行的。在不使用“waitForDuration”的情况下,如何确保在动画之后重新检测到触摸?
【问题讨论】:
-
所以这段代码来自另一个类而不是场景,对吧?
-
“didMoveToView”来自现场;旋转功能来自一个节点类,它将所有的触摸都传递回场景。
-
是的,对不起,我说得不准确,我只是想问一下 spin() 方法,因为它看起来像是来自其他类。我只需要知道您当前的设置以便为您编写一些代码。我还要再问一件事……你说,节点passes 接触到了场景。你的意思是,你在那个自定义节点上有
userInteractionEnabled = false? -
我刚刚在上面添加了更多信息以使其清楚。节点是触控式的——设置在上面。谢谢!
-
查看我的答案。它是您的代码的简化版本,但逻辑是相同的。您运行您的序列,然后运行完成块以重新启用触摸。只需在一个空项目中尝试代码...
标签: swift sprite-kit skaction