如果用户将手指从精灵工具包中的按钮上移开,如何停止按钮动作?

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 中就可以了。如果你想运行一个带有参数的函数作为点击动作,你可以只做一个代码块。

希望对您有所帮助!如果您需要任何进一步的帮助,请联系我:)。