在两个点/触摸之间拉伸SKSpriteNode

时间:2019-06-27 18:36:52

标签: ios swift iphone sprite-kit

我有一个SKSpriteNode,其中设置了centerRect属性,以便可以拉伸该节点以使其看起来像样式行。我的意图是让用户触摸屏幕,并与节点绘制/拖动一条直线。该线将绕锚点旋转以保持笔直。

touchesBegan:中,添加了节点:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    guard let touch = touches.first else { return }
    let positionInScene = touch.location(in: self)
    if let _ = fgNode.childNode(withName: "laser") {
        print("already there")
    } else {
        laser.centerRect = CGRect(x: 0.42857143, y: 0.57142857, width: 0.14285714, height: 0.14285714)
        laser.anchorPoint = CGPoint(x: 0, y: 0.5)
        laser.position = positionInScene
        fgNode.addChild(laser)
    }
}

并在touchesMoved:中进行了调整:

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

使用两个功能拉伸和旋转节点:

func stretchLaserTo(_ point: CGPoint) {
    let offset = point - laser.anchorPoint
    let length = offset.length()
    let direction = offset / CGFloat(length)
    laser.xScale = length
    rotate(sprite: laser, direction: direction)
}


func rotate(sprite: SKSpriteNode, direction: CGPoint) {
    sprite.zRotation = atan2(direction.y, direction.x)
}

我认为我在正确的道路上。线条随着我的触摸旋转并扩展,但是,它非常灵敏,并且不会停留在我的触摸上。也许我要去做错了。是否有执行这种操作的标准技术?

可以在此处查看此工作的示例:https://imgur.com/A83L45i

1 个答案:

答案 0 :(得分:2)

我建议您将子画面的锚点设置为(0,0),将子画面的比例设置为子画面位置与当前触摸位置之间的距离,然后旋转子画面。

首先,创建一个精灵并设置其锚点。

let laser = SKSpriteNode(color: .white, size: CGSize(width: 1, height: 1))

override func didMove(to view: SKView) {
    laser.anchorPoint = CGPoint(x: 0, y: 0)
    addChild(laser)
}

touchesBegan中,将子画面的位置设置为触摸的位置。在这种情况下,它也是该行的开始。

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    guard let touch = touches.first else { return }
    let positionInScene = touch.location(in: self)
    laser.position = positionInScene
    laser.setScale(1)
}

更新精灵,使其形成一条从精灵的位置开始并在当前触摸位置结束的线。

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

通过将精灵xScale设置为从行首到当前触摸位置的距离来拉伸精灵,然后旋转精灵。

func stretchLaserTo(_ point: CGPoint) {
    let dx = point.x - laser.position.x
    let dy = point.y - laser.position.y
    let length = sqrt(dx*dx + dy*dy)
    let angle = atan2(dy, dx)
    laser.xScale = length
    laser.zRotation = angle
}