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