【问题标题】:How do I drag and drop a sprite in Swift 3.0?如何在 Swift 3.0 中拖放精灵?
【发布时间】:2016-08-17 19:15:24
【问题描述】:

我想要做的就是能够在屏幕上拖放一个精灵。我试过以下代码:

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    
}
}
}

此代码确实有效,但是,当我快速拖动球时,我猜它检测到“球”不再包含点“位置”并且球停止了,这意味着我又捡起了球。我希望球能够快速响应我的触球,这样球就不会停止移动。我该怎么做?

【问题讨论】:

  • 因为你需要从逻辑上考虑,如果你快速移动,你的手指在检查时不再接触球。您需要使用 touchesBegan 使用您的 containsPoint 代码启动激活状态,然后使用 touchesMoved,如果状态已激活,您只需移动球,您不检查该点,然后在 touchesEnded 或 touchesCanceled 上,您将其停用

标签: swift sprite-kit sprite swift3


【解决方案1】:

这是在 Sprite Kit 中执行此操作的正确方法。就像我在评论中所说的那样,您需要将移动节点分配给激活状态,在这种情况下,我使用一个名为 movableNode 的变量来执行我的激活状态。当您触摸球时,它会通过将其分配给movableNode 来激活。然后当你拖动你的手指时,movableNode 会随着拖动而移动,然后一旦你松开,你通过将movableNode 设置为 nil 进入停用状态。请注意,此代码仅适用于单点触控应用程序,如果您想处理多点触控,则需要跟踪哪个触控在进行拖动。

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
    }
}

【讨论】:

  • 如果您要投反对票,请解释原因,这是正确的解决方案
【解决方案2】:

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
}

【讨论】:

  • 太棒了。谢谢。
  • 所以这基本上只会让我的节点只有在你正确拖动它的情况下才能移动?因为当我点击显示屏的某些部分时,节点会移动到那里。我不希望节点移动,除非我在屏幕上拖动它。
【解决方案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
    }

【讨论】:

  • 这怎么可能是一个答案,SKNodes 和 UIViews 是两个不同的东西,如果你移动得很快,你应该仍然会遇到这个 Draggable Image touchesMoved 没有被触发的问题,因为你超出了框架
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多