【问题标题】:Stretch SKSpriteNode between two points/touches在两点/触摸之间拉伸 SKSpriteNode
【发布时间】:2019-06-27 18:36:52
【问题描述】:

我有一个 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

【问题讨论】:

    标签: ios swift iphone sprite-kit


    【解决方案1】:

    我建议你将精灵的锚点设置为(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
    }
    

    【讨论】:

    • 谢谢。这是一个改进。这条线更可控,但与用户移动相比仍呈指数级增长 - imgur.com/gTTzBDT
    • 您需要将精灵的宽高设置为1。尝试将我的代码复制到一个新项目中。
    • 啊。我懂了。它确实是这样工作的,但是将大小设置为 1x1 会使精灵几乎不可见。图像为 21x21。我想这可以通过将xScale 与图像大小成比例地设置来解决。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多