2016-08-17 20 views
7

我想要做的就是能够在屏幕上拖放一个精灵。我试过下面的代码:如何在Swift 3.0中拖放一个精灵?

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

override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) { 
    for touch in (touches) { 
     let location = touch.locationInNode(self) 
     if ball.containsPoint(location) { 
      ball.position = location  
} 
} 
} 

此代码工作,但是,当我拖动球非常快,我想它检测到“球”不再包含点“位置”和球这意味着我再次拿起球。我希望球能够快速响应我的接触,以便球不会停止移动。我将如何做到这一点?

+1

因为你需要从逻辑上思考它,如果你快速移动,当它执行检查时你的手指不再接触球。你需要使用touchesBegan使用你的包含点代码来启动一个激活状态,然后你使用touchesMoved,如果状态被激活,你只是移动球,你不检查点,然后在touchesEnded或touchesCanceled,你停用它 – Knight0fDragon

回答

-3

我在那里我已经子类一个UIImageView,并把它称为一个“DraggableImage”

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 
     originalPosition = self.center 
    } 

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { 
     if let touch = touches.first { 
      let position = touch.location(in: self.superview) 
      self.center = CGPoint(x: position.x, y: position.y) 
     } 
    } 

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

     self.center = originalPosition 
    } 
+0

这甚至是一个答案,SKNodes和UIViews是两个不同的东西,如果你快速移动,你应该仍然有这个Draggable图像touchesMoved不会被解雇的问题,因为你超出了框架 – Knight0fDragon

10

这是做雪碧套件正确的方式实现。就像我在我的评论中所说的,您需要将移动节点分配到激活状态,在这种情况下,我使用一个名为movableNode的变量来执行我的激活状态。当你触球时,通过将其分配给movableNode而激活。然后,当您拖动手指时,movableNode将随着拖动一起移动,然后一旦释放,您就通过将movableNode设置为零来进入停用状态。请注意,此代码仅适用于单点触控应用程序,如果您想要处理多点触控,则需要跟踪哪个触控正在进行拖动。

var movableNode : SKNode? 

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 
    if let touch = touches.first { 
     let location = touch.locationInNode(self) 
     if ball.containsPoint(location) { 
      movableNode = ball 
      movableNode!.position = location  
     } 
    } 
} 

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { 
    if let touch = touches.first where movableNode != nil { 
     movableNode!.position = touch.locationInNode(self) 
    } 
} 

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { 
    if let touch = touches.first where movableNode != nil { 
     movableNode!.position = touch.locationInNode(self) 
     movableNode = nil 
    } 
} 
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) { 
    if let touch = touches.first { 
     movableNode = nil 
    } 
} 
+0

如果你打算投票,解释为什么,这是正确的解决方案 – Knight0fDragon

6

KnightOFDragon解决方案工作得很好。如果您不想将精灵中心位置移动到您的手指触摸屏幕的位置,并且您想将精灵从其中心原始位置移动,我只需添加几行。

var movableNode : SKNode? 
var ballStartX: CGFloat = 0.0 
var ballStartY: CGFloat = 0.0 

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { 
    if let touch = touches.first { 
     let location = touch.location(in: self) 
     if (map?.contains(location))! { 
      movableNode = ball 
      ballStartX = (movableNode?.position.x)! - location.x // Location X of your sprite when touch started 
      ballStartY = (movableNode?.position.y)! - location.y // Location Y of your sprite when touch started 
     } 
    } 
} 

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { 
    if let touch = touches.first, movableNode != nil { 
     let location = touch.location(in: self) 
     movableNode!.position = CGPoint(x: location.x+ballStartX, y: location.y+ballStartY) // Move node around with distance to your finger 
    } 
} 

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { 
    if let _ = touches.first, movableNode != nil { 
     movableNode = nil 
    } 
} 
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) { 
if let touch = touches.first { 
    movableNode = nil 
} 
+0

辉煌。谢谢。 – Steve

+0

所以这基本上只会让我的节点只有在你拖动它的时候才能移动?因为当我点击显示器的某些部分时,节点在那里移动。除非我在屏幕上的某处拖动,否则我不希望节点移动。 – Dewan