问题
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