【问题标题】:How to draw a path by touches on a specific path using SKShapeNode in SpriteKit如何在 SpriteKit 中使用 SKShapeNode 通过触摸特定路径来绘制路径
【发布时间】:2018-11-24 04:55:19
【问题描述】:
  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()
            }
        }
    }
}

这段代码应该让用户“只”在我的路径上绘制,就像我在图片中显示的那样:

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

所以请任何人向我解释让用户只在我的路径上绘制的正确方法,如果他触摸了路径,他就无法绘制任何东西。

【问题讨论】:

    标签: ios sprite-kit uibezierpath skshapenode


    【解决方案1】:

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

    然后剪辑到这个路径:

    self.currentBezierPath.addClip()
    

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

    确保用户沿一个方向跟随路径

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

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

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

        let inside = bezierPath.contains(point)
    

    这会解决您的用例吗?

    【讨论】:

    • 谢谢你的回答我看到你的作品,如果你有一张图片来填充颜色,它的工作很好,但在我的情况下,我的应用程序应该学习孩子们如何写两个字母,所以我需要用户跟随字母路径和你的解决方案,一些时间字母线相交,所以用户只是用颜色填充字母,而不是遵循正确的路径来学习如何正确书写,如果你有另一个答案我会很乐意告诉我.
    • @AmmarAhmad 啊,好的,我明白了,我已经更新了答案。它现在应该确保用户沿着正确的方向跟随字母路径,并且根本不会离开整个路径。
    • 实际上它的使用方法非常有趣,我认为它会解决我的问题,但是你能告诉我如何用简单的代码将路径分成一个矩形(比如分割一条简单的线)所以我能理解你是怎么做到的,再次感谢你的帮助。
    • 这是一个聪明的解决方案:stackoverflow.com/a/26131682/2331445。它在Objective-C中。如果您向下滚动并查看 ArrowView.m 的 drawRect,您可以看到 Rob_forEachPointAtInterval 方法的运行:对于每个间隔,它返回一个点和一个向量。例如,您可以创建一个矩形路径数组,而不是绘制箭头。
    猜你喜欢
    • 1970-01-01
    • 2011-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-05
    • 2012-03-16
    • 1970-01-01
    相关资源
    最近更新 更多