Detect long touch in Sprite Kit

|▌冷眼眸甩不掉的悲伤 提交于 2021-01-28 21:03:20

问题


I have a node in a SKScene that I am moving as per the users touch. Basically, this character should also be trying to follow the users finger (Assuming the finger is on the screen). I currently have it implemented as so, which works fine:

    override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
    let touch = touches.first as! UITouch
    player.runAction(SKAction.moveTo(touch.locationInNode(self), duration: 1))
}

override func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) {
    let touch = touches.first as! UITouch
    player.runAction(SKAction.moveTo(touch.locationInNode(self), duration: 1))
}

override func touchesCancelled(touches: Set<NSObject>!, withEvent event: UIEvent!) {
    player.removeAllActions()
}

override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
    player.removeAllActions()
}

However, the problem is that if a user holds his/her finger on the phone. The touchesBegan is only called once, and that's when the tap starts, not when it is held. I want the player character to constantly be trying to reach the finger.

I am centering the camera on the node, so the only time the node should be touching the finger is if the user puts his finger on/in the node (I.e the same position as the node). Because of this, after I run the SKAction to move the node the touch is invalid since it is at the old position.

How would I do this?


回答1:


Add two instance variables to your SKScene, BOOL fingerIsTouching and CGPoint touchLocation.

Inside -touchesBegan:, set fingerIsTouching to YES and update touchLocation to the correct location. In your SKScene's -update: method, check if fingerIsTouching is YES and move your character according to touchLocation. I recommend using -update: because it is called once per frame, which is exactly enough. You might have to use some other method for moving the character than SKAction though.

Don't forget to update touchLocation in -touchesMoved:, and reset fingerIsTouching inside -touchesCancelled: and -touchesEnded: :)

Sorry for the Obj-C, hope this illustrates the point.




回答2:


You can register a long touch event like this:

let longPressRecognizer = UILongPressGestureRecognizer(target: self, action: "longPressed:")
self.view.addGestureRecognizer(longPressRecognizer)

func longPressed(sender: UILongPressGestureRecognizer) {
    // your code
}



回答3:


For Swift 4:

You'll first want to make GameScene a UIGestureRecognizerDelegate:

class GameScene: SKScene, UIGestureRecognizerDelegate {

And so you'll also need to add the delegate method to the GameScene class:

func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {        
        return true
}

Then inside GameScene's override func didMove(to view: SKView) { add the following:

let pressed:UILongPressGestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(longPress(sender:)))
pressed.delegate = self
pressed.minimumPressDuration = 0.1
view.addGestureRecognizer(pressed)

Finally inside GameScene add your function to handle the long press (within which you can also discern the long press's state too):

func longPress(sender: UILongPressGestureRecognizer) {

     if sender.state == .began { print("LongPress BEGAN detected") }            
     if sender.state == .ended { print("LongPress ENDED detected") }

}


来源:https://stackoverflow.com/questions/30337608/detect-long-touch-in-sprite-kit

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!