在 Sprite Kit 中检测长触摸
Detect long touch in Sprite Kit
我在 SKScene 中有一个节点,我正在根据用户的触摸移动它。基本上,这个角色也应该试图跟随用户的手指(假设手指在屏幕上)。我目前已经这样实现了,效果很好:
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()
}
但是,问题是如果用户将 his/her 手指放在 phone 上。 touchesBegan 只被调用一次,那是在点击开始的时候,而不是在它被按住的时候。我希望玩家角色不断地尝试伸手去拿手指。
我将相机放在节点的中心,所以节点应该触摸手指的唯一时间是用户将手指 on/in 放在节点上(即与节点相同的位置)。因此,在我 运行 移动节点的 SKAction 之后,触摸无效,因为它位于旧位置。
我该怎么做?
您可以像这样注册长按事件:
let longPressRecognizer = UILongPressGestureRecognizer(target: self, action: "longPressed:")
self.view.addGestureRecognizer(longPressRecognizer)
func longPressed(sender: UILongPressGestureRecognizer) {
// your code
}
向您的 SKScene 添加两个实例变量,BOOL fingerIsTouching
和 CGPoint touchLocation
。
在 -touchesBegan:
中,将 fingerIsTouching
设置为 YES 并将 touchLocation
更新到正确的位置。
在你的 SKScene 的 -update:
方法中,检查 fingerIsTouching
是否为 YES 并根据 touchLocation
移动你的角色。我推荐使用 -update:
因为它每帧调用一次,这就足够了。不过,您可能必须使用 SKAction
以外的其他方法来移动角色。
不要忘记在 -touchesMoved:
中更新 touchLocation
,并在 -touchesCancelled:
和 -touchesEnded:
中重置 fingerIsTouching
:)
对于 Obj-C 很抱歉,希望这说明了这一点。
对于Swift 4:
您首先要使 GameScene 成为 UIGestureRecognizerDelegate:
class GameScene: SKScene, UIGestureRecognizerDelegate {
因此您还需要将委托方法添加到 GameScene class:
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
然后在 GameScene 的 override func didMove(to view: SKView) {
中添加以下内容:
let pressed:UILongPressGestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(longPress(sender:)))
pressed.delegate = self
pressed.minimumPressDuration = 0.1
view.addGestureRecognizer(pressed)
最后在 GameScene 中添加你的函数来处理长按(你也可以在其中辨别长按的状态):
func longPress(sender: UILongPressGestureRecognizer) {
if sender.state == .began { print("LongPress BEGAN detected") }
if sender.state == .ended { print("LongPress ENDED detected") }
}
我在 SKScene 中有一个节点,我正在根据用户的触摸移动它。基本上,这个角色也应该试图跟随用户的手指(假设手指在屏幕上)。我目前已经这样实现了,效果很好:
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()
}
但是,问题是如果用户将 his/her 手指放在 phone 上。 touchesBegan 只被调用一次,那是在点击开始的时候,而不是在它被按住的时候。我希望玩家角色不断地尝试伸手去拿手指。
我将相机放在节点的中心,所以节点应该触摸手指的唯一时间是用户将手指 on/in 放在节点上(即与节点相同的位置)。因此,在我 运行 移动节点的 SKAction 之后,触摸无效,因为它位于旧位置。
我该怎么做?
您可以像这样注册长按事件:
let longPressRecognizer = UILongPressGestureRecognizer(target: self, action: "longPressed:")
self.view.addGestureRecognizer(longPressRecognizer)
func longPressed(sender: UILongPressGestureRecognizer) {
// your code
}
向您的 SKScene 添加两个实例变量,BOOL fingerIsTouching
和 CGPoint touchLocation
。
在 -touchesBegan:
中,将 fingerIsTouching
设置为 YES 并将 touchLocation
更新到正确的位置。
在你的 SKScene 的 -update:
方法中,检查 fingerIsTouching
是否为 YES 并根据 touchLocation
移动你的角色。我推荐使用 -update:
因为它每帧调用一次,这就足够了。不过,您可能必须使用 SKAction
以外的其他方法来移动角色。
不要忘记在 -touchesMoved:
中更新 touchLocation
,并在 -touchesCancelled:
和 -touchesEnded:
中重置 fingerIsTouching
:)
对于 Obj-C 很抱歉,希望这说明了这一点。
对于Swift 4:
您首先要使 GameScene 成为 UIGestureRecognizerDelegate:
class GameScene: SKScene, UIGestureRecognizerDelegate {
因此您还需要将委托方法添加到 GameScene class:
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
return true
}
然后在 GameScene 的 override func didMove(to view: SKView) {
中添加以下内容:
let pressed:UILongPressGestureRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(longPress(sender:)))
pressed.delegate = self
pressed.minimumPressDuration = 0.1
view.addGestureRecognizer(pressed)
最后在 GameScene 中添加你的函数来处理长按(你也可以在其中辨别长按的状态):
func longPress(sender: UILongPressGestureRecognizer) {
if sender.state == .began { print("LongPress BEGAN detected") }
if sender.state == .ended { print("LongPress ENDED detected") }
}