如何使用SpriteKit中的SKShapeNode通过触摸特定路径来绘制路径

时间:2018-11-24 04:55:20

标签: ios sprite-kit uibezierpath skshapenode

  1. 我使用UIBezierPath创建路径,然后从该路径创建SKShapeNode。
  2. 我希望用户通过触摸屏幕来绘制相同的路径以匹配我的原始路径。

这是代码:

导入SpriteKit 导入GameplayKit

GameScene类:SKScene {

var orginalPath: UIBezierPath!

var orgialShape: SKShapeNode!
var userTouchs = [CGPoint]()
var drawingLine: SKShapeNode!


override func didMove(to view: SKView) {

    orginalPath = UIBezierPath()
    orginalPath.move(to: CGPoint(x: 170, y: 230))
    orginalPath.addLine(to: CGPoint(x: 370, y: 230))
    orginalPath.addQuadCurve(to: CGPoint(x: 480, y: 55), controlPoint: CGPoint(x: 525, y: 150))


    orgialShape = SKShapeNode(path: orginalPath.cgPath)
    orgialShape.strokeColor = UIColor.white
    orgialShape.lineWidth = 30
    orgialShape.lineCap = .round
    orgialShape.lineJoin = .round
    orgialShape.zPosition = 0
    orgialShape.name = "orginal"
    addChild(orgialShape)

}

func createLine() {
    if userTouchs.count > 2 {
        let line = SKShapeNode(points: &userTouchs, count: userTouchs.count)
        line.strokeColor = UIColor.red
        line.lineWidth = 10
        line.lineCap = .round
        line.zPosition = 10
        line.isAntialiased = true
        line.name = "newLine"
        addChild(line)

    }
}


override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    if let touch = touches.first {
        let location = touch.location(in: self)
        let objects = nodes(at: location)
        for object in objects {
            if object.name == "orginal" {
                    userTouchs.append(location)
            }
        }
    }
}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    if let touch = touches.first {
        let location = touch.location(in: self)
        let objects = nodes(at: location)
        for object in objects {
            if object.name == "orginal" {
                    print(location)
                    userTouchs.append(location)
                    createLine()
            }
        }
    }
}

此代码应使用户像在图片中所示的那样在我的路径上“仅”绘制:

enter image description here

但是问题是当我编写代码时,我发现可以在路径上画一条线,实际上它看起来像正方形,而不仅仅是我在图片中显示的路径:

enter image description here enter image description here enter image description here

所以请问有人可以向我解释正确的方法,使用户仅在我的路径上绘制,如果他触摸了该路径,他将无法绘制任何东西。

1 个答案:

答案 0 :(得分:0)

您可以定义允许用户插入的路径,例如在此处查看绿色路径:

clip path

然后剪辑到该路径:

self.currentBezierPath.addClip()

在我的解答中查看有关此方法的更多详细信息:How to draw inside the black edges in iOS SDK with OpenGL ES?

确保用户在一个方向上遵循路径

您可以划分区域,例如成小矩形并按顺序存储到数组中,请参见此处的草图:

divide path into areas

然后确保用户仅以升序触摸矩形(图中红色显示)开始,并且用户没有离开外边界(图中绿色显示)。

要检查点是否在路径内,可以使用以下方法:

    let inside = bezierPath.contains(point)

能解决您的用例吗?