swift skscene 触摸并按住除了触摸之外的其他动作

swift skscene touch and hold other action than just touching

所以我最近用 sprite kit 制作了一个 swift 游戏,现在我卡住了。 我有一个角色选择屏幕,如果你按住角色,我想显示角色的描述,但如果你只是触摸它,你就会选择它并玩它。我已经有了 play/show 描述的代码。我只需要知道什么时候调用相应的函数,以及如何区分节点是被按住还是刚被触摸。

提前致谢

因此,这是使用 SKActions 的方法...此外,还有另一种使用 SKAction 的方法,但我无法真正向您展示所有可能性 :) 不管怎样,这是执行您想要的操作的代码:

import SpriteKit
import GameplayKit

class GameScene: SKScene {

    let kLongPressDelayActionKey = "longPressDelay"
    let kLongPressStartedActionKey = "longPressStarted"
    let kStoppingLongPressActionKey = "stoppingLongPressActionKey"

    let desc = SKSpriteNode(color: .white, size: CGSize(width: 150, height: 150))
    let button = SKSpriteNode(color: .purple, size: CGSize(width: 150, height: 150))
    let other = SKSpriteNode(color: .yellow, size: CGSize(width: 150, height: 150))
    override func didMove(to view: SKView) {

        addChild(desc)
        addChild(button)
        addChild(other)

        button.position.y = -160
        button.name = "button"
        desc.alpha = 0.0
        desc.name = "description"
        other.name = "other"
        other.alpha = 0.0
        other.position.y = -320

    }

    private func singleTap(onNode:SKNode){

        other.alpha = other.alpha == 0.0 ? 1.0 : 0.0
    }

    private func startLongPress(withDuration duration:TimeInterval){

        //How long does it take before long press is fired
        //If user moves his finger of the screen within this delay, the single tap will be fired
        let delay = SKAction.wait(forDuration: duration)

        let completion = SKAction.run({
        [unowned self] in

             self.desc.removeAction(forKey: self.kLongPressDelayActionKey)
             self.desc.run(SKAction.fadeIn(withDuration: 0.5), withKey: self.kLongPressStartedActionKey)
        })

        self.desc.run(SKAction.sequence([delay,completion]), withKey: kLongPressDelayActionKey)

    }

    private func stopLongPress(){

        //Fire single tap and stop long press
        if desc.action(forKey: kLongPressDelayActionKey) != nil{

            desc.removeAction(forKey: kLongPressDelayActionKey)
            self.singleTap(onNode: self.other)
        //or just stop the long press
        }else{

            desc.removeAction(forKey: kLongPressStartedActionKey)

            //Start fade out action if it isn't already started
            if desc.action(forKey: kStoppingLongPressActionKey) == nil {
                desc.run(SKAction.fadeOut(withDuration: 0.2), withKey: kStoppingLongPressActionKey)
            }
        }
    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {

        //To stop the long press if we slide a finger of the button
        if let touch = touches.first {

            let location = touch.location(in: self)

            if !button.contains(location) {

              stopLongPress()

            }

        }
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

        if let touch = touches.first {

            let location = touch.location(in: self)

            if button.contains(location) {
                print("Button tapped")

                startLongPress( withDuration: 1)
            }
        }
    }

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {

       stopLongPress()
    }
}

您可以 运行 代码,您会看到如果点击紫色按钮,会弹出一个黄色框。如果您再次点击它,它将隐藏。此外,如果您将手指放在紫色框上 1 秒钟,一个白色框会淡入。当您松开手指时,它会淡出。另外,我已经实现了 touchesMoved,所以如果你在蓝色框消失时滑动紫色按钮的手指,它也会淡出。

所以在这个例子中,我融合了长按和单击。单击被认为是所有不是长按的东西。例如,如果用户按住手指 0.01 秒,或 0.5 秒,或 0.99 秒,将被视为单击并弹出黄色框。如果你按住手指>=1秒,就会触发长按动作。

另一种方法是使用手势识别器...稍后我可能会为此举一个例子:)

下面是使用手势识别器的方法:

import SpriteKit
import GameplayKit

class GameScene: SKScene {

    var longPressGesture:UILongPressGestureRecognizer!
    var singleTapGesture:UITapGestureRecognizer!

    let kLongPressStartedActionKey = "longPressStarted"
     let kStoppingLongPressActionKey = "stoppingLongPressActionKey"

    let desc = SKSpriteNode(color: .white, size: CGSize(width: 150, height: 150))
    let button = SKSpriteNode(color: .purple, size: CGSize(width: 150, height: 150))
    let other = SKSpriteNode(color: .yellow, size: CGSize(width: 150, height: 150))

    override func didMove(to view: SKView) {

        longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(GameScene.longPress(_:)))
        singleTapGesture = UITapGestureRecognizer(target: self, action: #selector(GameScene.singleTap(_:)))
        self.view?.addGestureRecognizer(longPressGesture)
        self.view?.addGestureRecognizer(singleTapGesture)
        addChild(desc)
        addChild(button)
        addChild(other)

        button.position.y = -160
        button.name = "button"
        desc.alpha = 0.0
        desc.name = "description"
        other.name = "other"
        other.alpha = 0.0
        other.position.y = -320

    }

    private func stopLongPress(){



        desc.removeAction(forKey: self.kLongPressStartedActionKey)

        //Start fade out action if it isn't already started
        if desc.action(forKey: kStoppingLongPressActionKey) == nil {
            desc.run(SKAction.fadeOut(withDuration: 0.2), withKey: kStoppingLongPressActionKey)
        }

    }

    func singleTap(_ sender:UITapGestureRecognizer){


        if sender.state == .ended {

            let location = convertPoint(fromView: sender.location(in: self.view))

            if self.button.contains(location) {
                    self.other.alpha = self.other.alpha == 0.0 ? 1.0 : 0.0
            }
        }
    }

    func longPress(_ sender: UILongPressGestureRecognizer) {
        let longPressLocation = convertPoint(fromView: sender.location(in: self.view)) 

        if sender.state == .began {

            if button.contains(longPressLocation) {
                desc.run(SKAction.fadeIn(withDuration: 0.5), withKey: self.kLongPressStartedActionKey)
            }

        }else if sender.state == .ended {
            self.stopLongPress()
        }else if sender.state == .changed {


            let location = convertPoint(fromView:  sender.location(in: self.view))


            if !button.contains(location) {

                stopLongPress()

            }

        }
    }
}