首页 > 解决方案 > 如何移动 SKNode?

问题描述

我正在使用 SpriteKit 和 Swift 5 编写类似 Pong 的游戏以用于学习目的。而且我试图让玩家的桨(一个 SKNode 矩形)在 x 坐标上在屏幕上移动,但不能。

我试过这个简单的解决方案:

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    for t in touches {
        let location = t.location(in: self)

        playerPaddle.position.x = location.x
    }

它有效,但似乎桨只在点击(触摸)时移动,而不是拖动。

我也尝试过使用 UIPanGestureRecognizer,但我不太明白如何调用它,这是我从 Apple Developer's 官方文档中复制的代码,并根据我的情况进行了一些更改:

@IBAction func panPiece(_ gestureRecognizer : UIPanGestureRecognizer) {

    guard gestureRecognizer.view != nil else {return}
    let piece = gestureRecognizer.view!
    let translation = gestureRecognizer.translation(in: piece.superview)
    if gestureRecognizer.state == .began {
        self.initialPos = piece.center
    }
    else if gestureRecognizer.state != .changed {
        let newPos = CGPoint(x: initialPos.x + translation.x, y: initialPos.y)
        piece.center = newPos
    }
}

标签: swiftuser-interfacesprite-kitpan

解决方案


您的touchesMoved解决方案对我有用,所以我认为还有其他问题。无论如何,我可以提供一个替代方案:

我还构建了 Pong 来学习 Swift 和 SpriteKit,并使用 SKActions 实现了划桨运动。每次触摸开始时,取消拨片的当前动作并开始移动到新的 x 位置。

如果你想保持简单的开始,那么你可以有一个恒定的移动时间,比如 0.5 秒。否则,您可以通过获取拨片和触摸位置之间的绝对距离并除以某个常数来计算移动时间。改变常数将改变桨移动的速度。

这是一个恒定移动时间的示例:

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

    if playerPaddle.hasActions() { playerPaddle.removeAllActions() }

    for touch in touches {
        let newX = touch.location(in: self).x
        let oldX = playerPaddle.position.x
        playerPaddle.run(.moveBy(x: newX - oldX, y: 0, duration: 0.5))
    }
}

推荐阅读