SpriteKit场景中的多个平移手势

时间:2014-12-03 03:20:50

标签: ios swift sprite-kit uigesturerecognizer

我有SKScene个节点(SKSpriteNode s,SKShapeNode s等),我希望能够单独平移 同时。我需要能够:

  • 触摸一个节点并移动它。
  • 移动一个节点时,触摸多个其他节点并移动它们。

例如,如果我可以为每个节点添加UIPanGestureRecognizer,这将很容易。但是,据我所知,UIGestureRecognizer的唯一选择是将其添加到view的{​​{1}}。我用一个识别器实现了这一点,并且在我SKScene上识别器的相关操作中的所有触摸和节点的操作都有点痛苦。这是我为识别器所做的事情:

SKScene

基本上,我只是在手势识别器的class MultiplePanGestureRecognizer: UIGestureRecognizer { var currentTouches: Array<UITouch> = [] override func touchesBegan(touches: NSSet!, withEvent event: UIEvent!) { super.touchesBegan(touches, withEvent: event) for touch in touches { currentTouches.append(touch as UITouch) } state = .Began } override func touchesMoved(touches: NSSet!, withEvent event: UIEvent!) { super.touchesMoved(touches, withEvent: event) state = .Changed } override func touchesEnded(touches: NSSet!, withEvent event: UIEvent!) { super.touchesEnded(touches, withEvent: event) removeCancelledOrEndedTouches(touches) } override func touchesCancelled(touches: NSSet!, withEvent event: UIEvent!) { super.touchesCancelled(touches, withEvent: event) removeCancelledOrEndedTouches(touches) } // Add new touches to currentTouches func addUntrackedTouchesFromSet(touches: NSSet!) { for touch in touches { let index = find(currentTouches, touch as UITouch) if index == nil { currentTouches.append(touch as UITouch) } } } // Remove received touches from currentTouches array func removeCancelledOrEndedTouches(touches: NSSet!) { for touch in touches { if let index = find(currentTouches, touch as UITouch) { currentTouches.removeAtIndex(index) } } // End the gesture if there are no touches remaining in currentTouches if currentTouches.count == 0 { state = .Ended } } override func reset() { super.reset() currentTouches = [] } } 属性上保留所有触摸功能,以便我可以在附加的操作中访问所有它们。这意味着我必须在currentTouches中兼顾触及命中节点等的内容。最初,我尝试通过在手势识别器SKScene中将其状态设置为.Began来重新启动手势。但是,手动将识别器的状态重置为touchesBegan:withEvent:并未触发操作,因此我不得不让新触摸在我的识别器中触发.Began状态,然后处理所有事情回到行动中。

作为参考,我的.Changed中的方法是作为识别器操作添加的:

SKScene

func handleMultiplePan(recognizer: MultiplePanGestureRecognizer) { switch recognizer.state { case .Began, .Changed: // Remove those touches from tracking that are no longer being // recognized touchNodeMap.prune(recognizer.currentTouches) // Iterate over the recognizer's currentTouches for touch in recognizer.currentTouches { // Is it over a child node of the scene? if let node = getChildNodeForTouch(touch) { // If so, add it to the touchNodeMap touchNodeMap.add(touch, withNode: node) } } // Iterate over currentlyPanningTouches and move nodes accordingly for (touch, node) in touchNodeMap { let location = touch.locationInNode(self) let previousLocation = touch.previousLocationInNode(self) let deltaX = location.x - previousLocation.x let deltaY = location.y - previousLocation.y node.position = CGPointMake(node.position.x + deltaX, node.position.y + deltaY) } // Get node for most recent touch let (_, mostRecentNode) = touchNodeMap.mostRecentTouchAndNode() // Remove and re-add it to the scene if mostRecentNode != nil { mostRecentNode!.removeFromParent() addChild(mostRecentNode!) } default: break } } 只是将touchNodeMap es映射到Dictionary的{​​{1}}。)

我的问题是,我在这里遗失了什么吗?有没有办法在每个节点上使用UITouch?或者,有没有更好的方法来做我想做的事情?

1 个答案:

答案 0 :(得分:0)

我遇到了同样的挑战,得到了@vacawama的非常好的帮助。请参阅此链接:How to implement multiple PanGestures (Draggable views)?

我这是你在寻找什么?