我怎样才能在不跳到锚点的情况下拖放一个非常高的精灵?

How can I drag and drop a very tall sprite without it jumping to its anchor point?

提问人:Dominick 提问时间:10/25/2023 更新时间:10/27/2023 访问量:28

问:

我使用以下代码使用 Swift 在我的 SpriteKit 场景中移动一个非常高、很薄的精灵。

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    super.touchesMoved(touches, with: event)
    let touch = touches.first!
    let moveableNodeTouchLocation = touch.location(in: moveableNode)
    monkeySprite.position = moveableNodeTouchLocation

当我创建 monkeySprite 时,我可以将锚点更改为 CGPoint(x: 1.0, y: 1.0) 或 0.5 或 0,锚点在哪里,这就是 sprite 在拖动触摸移动事件时“跳转到”的位置。

有没有办法将精灵从它被触摸的位置移动?我尝试将锚点更改为触摸的位置,如下所示:

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    super.touchesMoved(touches, with: event)
    guard let touch = touches.first, let touchedSprite = touchedSprite else { return }
    let location = touch.location(in: self)

    // Calculate the new anchor point based on the touch location and offset
    let newAnchorX = (location.x - touchOffset.x) / touchedSprite.size.width
    let newAnchorY = (location.y - touchOffset.y) / touchedSprite.size.height

    // Set the new anchor point
    touchedSprite.anchorPoint = CGPoint(x: newAnchorX, y: newAnchorY)

    // Adjust the sprite's position to keep it in the same visual location
    touchedSprite.position = location
}

但它并没有改变精灵最初跳跃的方式,将之前的锚点移动到触摸事件的位置,然后平滑地拖动屏幕以跟随之后移动的触摸。在初次接触期间,是否有不同的方法可以建立新的锚点,或者我应该尝试不同的方法?

Swift Sprite-Kit 精灵 可拖拽

评论

2赞 bg2b 10/26/2023
更改锚点可能不是您想要执行的操作。相反,记录开始触摸相对于精灵位置的偏移量。当触摸移动时,将 Sprite 移动到触摸的位置加上相同的偏移量。
0赞 Dominick 10/27/2023
谢谢你,我做错了

答:

0赞 Dominick 10/27/2023 #1

感谢bg2b为我指明了正确的方向!以下作品:

private var sprite: SKSpriteNode!
private var initialTouchOffset: CGPoint = .zero
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
initialTouchOffset = CGPoint(x: location.x - sprite.position.x, y: location.y - sprite.position.y)
 }

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    guard let touch = touches.first, isDragging else { return }
    let location = touch.location(in: self)
    
    sprite.position = CGPoint(x: location.x - initialTouchOffset.x, y: location.y - initialTouchOffset.y)
}