如果用户将手指从精灵工具包中的按钮上移开,如何停止按钮动作?
How to stop button action if user moves their finger off the button in sprite kit?
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first
let positionInScene = touch!.location(in: self)
let touchedNode = self.atPoint(positionInScene)
if let name = touchedNode.name {
if name == "leftbutton" {
print("left button stopped")
touchedNode.run(buttonStoppedPressAction)
player?.removeAllActions()
}
if name == "rightbutton" {
print("right button stopped")
touchedNode.run(buttonStoppedPressAction)
player?.removeAllActions()
}
}
}
这里我有代码,当用户从按钮上抬起手指时,它会停止操作,但前提是他们在按钮内抬起手指。因此,如果他们按下它并开始将手指移动到屏幕上的其他位置,同时连续按下按钮,则不会停止执行其代码。感谢您的帮助。
本质上,您应该检查触地时的触摸位置,并与触地时的位置进行比较。如果触摸不再位于您的按钮区域,您将取消所有效果。
不过,首先要说明一点。看起来您正在 SKScene 级别处理按钮逻辑,这是教程经常告诉您要做的。但是,这可能不是最好的方法。这里的风险,除了 SKScene 的混乱之外,还来自处理多个 objects 以及它们对触摸事件的反应,以及多点触摸(如果允许)带来的额外复杂性。
几年前,当我开始使用 SpriteKit 时,我觉得这是一个巨大的痛苦。所以我制作了一个按钮 class 来独立处理所有触摸逻辑(并在需要发生某些事情时将信号发送回 parent)。好处:没有不必要的混乱,没有区分 objects 的麻烦,能够确定多点触控限额 per-node。
我在 class 中做的是在触摸之前查看触摸是否没有离开按钮,我存储按钮区域的大小(作为 object 的参数) 并触摸其中的位置。简单简单。
事实上,Apple 不仅默认提供基本的 SKButton class,这一直让我感到困惑。无论如何,我想你可能需要考虑一下。至少对我来说,它每天节省了很多时间。我已经发布了多个具有相同自定义按钮的成功应用 class。
编辑:下面是我的准系统按钮 class。
import SpriteKit
class Button: SKNode {
private var background: SKSpriteNode?
private var icon: SKNode?
private var tapAction: () -> Void = {}
override init() {
super.init()
isUserInteractionEnabled = true
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
isUserInteractionEnabled = true
}
// MARK: Switches
public func switchButtonBackground(buttonBackgroundSize: CGSize, buttonBackgroundColor: SKColor) {
background = SKSpriteNode(color: buttonBackgroundColor, size: buttonBackgroundSize)
addChild(background!)
}
public func switchButtonIcon(_ buttonIcon: SKNode) {
if icon != nil {
icon = nil
}
icon = buttonIcon
addChild(icon!)
}
public func switchButtonTapAction(_ buttonTapAction: @escaping () -> Void) {
tapAction = buttonTapAction
}
// MARK: Touch events
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
tapAction()
}
}
然后创建按钮 object,首先启动它,使用大小和颜色为其分配背景,然后为其分配图标,在点击时为 运行 分配功能,最后将其作为 child 添加到场景中。
let icon = SKNode()
let size = CGSize(width: 20.0, height: 20.0)
let button = Button()
button.switchButtonBackground(buttonBackgroundSize: size, buttonBackgroundColor: .clear)
button.switchButtonIcon(icon)
button.switchButtonTapAction(buttonPressed)
addChild(button)
背景定义按钮的触摸区域,您可以为其设置颜色或将其确定为.clear。该图标应该在按钮顶部包含您想要的任何文本或图像。只需将它们打包到一个 SKNode 中就可以了。如果你想运行一个带有参数的函数作为点击动作,你可以只做一个代码块。
希望对您有所帮助!如果您需要任何进一步的帮助,请联系我:)。
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first
let positionInScene = touch!.location(in: self)
let touchedNode = self.atPoint(positionInScene)
if let name = touchedNode.name {
if name == "leftbutton" {
print("left button stopped")
touchedNode.run(buttonStoppedPressAction)
player?.removeAllActions()
}
if name == "rightbutton" {
print("right button stopped")
touchedNode.run(buttonStoppedPressAction)
player?.removeAllActions()
}
}
}
这里我有代码,当用户从按钮上抬起手指时,它会停止操作,但前提是他们在按钮内抬起手指。因此,如果他们按下它并开始将手指移动到屏幕上的其他位置,同时连续按下按钮,则不会停止执行其代码。感谢您的帮助。
本质上,您应该检查触地时的触摸位置,并与触地时的位置进行比较。如果触摸不再位于您的按钮区域,您将取消所有效果。
不过,首先要说明一点。看起来您正在 SKScene 级别处理按钮逻辑,这是教程经常告诉您要做的。但是,这可能不是最好的方法。这里的风险,除了 SKScene 的混乱之外,还来自处理多个 objects 以及它们对触摸事件的反应,以及多点触摸(如果允许)带来的额外复杂性。
几年前,当我开始使用 SpriteKit 时,我觉得这是一个巨大的痛苦。所以我制作了一个按钮 class 来独立处理所有触摸逻辑(并在需要发生某些事情时将信号发送回 parent)。好处:没有不必要的混乱,没有区分 objects 的麻烦,能够确定多点触控限额 per-node。
我在 class 中做的是在触摸之前查看触摸是否没有离开按钮,我存储按钮区域的大小(作为 object 的参数) 并触摸其中的位置。简单简单。
事实上,Apple 不仅默认提供基本的 SKButton class,这一直让我感到困惑。无论如何,我想你可能需要考虑一下。至少对我来说,它每天节省了很多时间。我已经发布了多个具有相同自定义按钮的成功应用 class。
编辑:下面是我的准系统按钮 class。
import SpriteKit
class Button: SKNode {
private var background: SKSpriteNode?
private var icon: SKNode?
private var tapAction: () -> Void = {}
override init() {
super.init()
isUserInteractionEnabled = true
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
isUserInteractionEnabled = true
}
// MARK: Switches
public func switchButtonBackground(buttonBackgroundSize: CGSize, buttonBackgroundColor: SKColor) {
background = SKSpriteNode(color: buttonBackgroundColor, size: buttonBackgroundSize)
addChild(background!)
}
public func switchButtonIcon(_ buttonIcon: SKNode) {
if icon != nil {
icon = nil
}
icon = buttonIcon
addChild(icon!)
}
public func switchButtonTapAction(_ buttonTapAction: @escaping () -> Void) {
tapAction = buttonTapAction
}
// MARK: Touch events
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
tapAction()
}
}
然后创建按钮 object,首先启动它,使用大小和颜色为其分配背景,然后为其分配图标,在点击时为 运行 分配功能,最后将其作为 child 添加到场景中。
let icon = SKNode()
let size = CGSize(width: 20.0, height: 20.0)
let button = Button()
button.switchButtonBackground(buttonBackgroundSize: size, buttonBackgroundColor: .clear)
button.switchButtonIcon(icon)
button.switchButtonTapAction(buttonPressed)
addChild(button)
背景定义按钮的触摸区域,您可以为其设置颜色或将其确定为.clear。该图标应该在按钮顶部包含您想要的任何文本或图像。只需将它们打包到一个 SKNode 中就可以了。如果你想运行一个带有参数的函数作为点击动作,你可以只做一个代码块。
希望对您有所帮助!如果您需要任何进一步的帮助,请联系我:)。