【问题标题】:Create a line with two CGPoints SpriteKit Swift用两个 CGPoints SpriteKit Swift 创建一条线
【发布时间】:2015-09-15 13:07:45
【问题描述】:

我正在尝试制作一个简单的应用程序,您可以在其中触摸一个点,无论您触摸哪里,精灵都会沿着一条线穿过该点到达屏幕边缘。我想画线段连接精灵的原点(它开始的点)和你触摸的点,以及精灵的原点和屏幕边缘的终点之间,所以我可以可视化路径sprite 以及原点、触摸点和结束点的 x 和 y 偏移量之间的关系。

希望这不会太混乱。

TL;DR:我需要在两点之间画一条线,但我不知道如何使用 SpriteKit Swift 来做到这一点。

提前致谢。

【问题讨论】:

  • [使用 touchesMoved 画线][1] [1]: stackoverflow.com/a/26045711/2775981
  • @Vicky,从表面上看,该教程是用 Objective-C 编写的。我不知道如何用 Objective-C 编写代码,也无法仅仅通过阅读来理解它。

标签: ios swift sprite-kit


【解决方案1】:

这可以使用 CGPath 和 SKShapeNode 来完成。

让我们从 CGPath 开始。当我们需要使用一系列形状或线条构造路径时,使用 CGPath。路径是连接两点的线。所以画一条线:

  1. moveToPoint:将路径的当前点设置为指定点。
  2. addLineToPoint:从当前点到指定点画一条直线。 要么 addCurveToPoint:根据一定的切线和控制点,从当前点到指定点绘制一条曲线。

您可以在此处查看文档: http://developer.apple.com/library/mac/#documentation/graphicsimaging/Reference/CGPath/Reference/reference.html

你需要做的是:

    var path = CGPathCreateMutable()
    CGPathMoveToPoint(path, nil, 100, 100)
    CGPathAddLineToPoint(path, nil, 500, 500)

现在要使路径可见,并为其赋予笔触颜色、线宽等属性。您在 SpriteKit 中创建一个 SKShapeNode 并向其添加路径。

    let shape = SKShapeNode()
    shape.path = path
    shape.strokeColor = UIColor.whiteColor()
    shape.lineWidth = 2
    addChild(shape)

希望这会有所帮助:)。

【讨论】:

  • 我刚刚升级到 Swift 3,这个解决方案对我来说就坏了。请参阅下面的答案以进行迁移。
【解决方案2】:

按照THIS的教程一步一步来,你就可以做到。

考虑下面的代码:

override func touchesMoved(touches: NSSet, withEvent event: UIEvent) {
    let location = touches.anyObject()!.locationInNode(scene)
    if let pig = movingPig {
        pig.addMovingPoint(location)
    }
}

这是一个简单的方法。您将获得用户手指的下一个位置,如果您在touchesBegan(_:,withEvent:) 中找到一头猪,如非零的movingPig 值所示,则将该位置添加到该猪作为下一个航路点。

到目前为止,您可以为猪存储一条路径——现在让猪遵循这条路径。将以下代码添加到update() 内的GameScene.swift

dt = currentTime - lastUpdateTime
lastUpdateTime = currentTime

enumerateChildNodesWithName("pig", usingBlock: {node, stop in
    let pig = node as Pig
    pig.move(self.dt)
})

你可以看到结果:

画线:

目前只有猪知道它要走的路,但场景也需要知道这条路才能画出来。这个问题的解决方案是为您的Pig 类提供一种新方法。

func createPathToMove() -> CGPathRef? {
    //1
    if wayPoints.count <= 1 {
        return nil
    }
    //2
    var ref = CGPathCreateMutable()

    //3
    for var i = 0; i < wayPoints.count; ++i {
         let p = wayPoints[i]

    //4
    if i == 0 {
        CGPathMoveToPoint(ref, nil, p.x, p.y)
    } else {
        CGPathAddLineToPoint(ref, nil, p.x, p.y)
     }
 }

 return ref
 }

此方法绘制猪的路径:

func drawLines() {


//1
  enumerateChildNodesWithName("line", usingBlock: {node, stop in
    node.removeFromParent()
  })

  //2
  enumerateChildNodesWithName("pig", usingBlock: {node, stop in
    //3
    let pig = node as Pig
    if let path = pig.createPathToMove() {          
      let shapeNode = SKShapeNode()
      shapeNode.path = path
      shapeNode.name = "line"
      shapeNode.strokeColor = UIColor.grayColor()
      shapeNode.lineWidth = 2
      shapeNode.zPosition = 1

      self.addChild(shapeNode)
    }
  })
}

这是你的结果:

你可以为猪设置这条路径。

您可以根据需要进行修改。

希望它会有所帮助。

【讨论】:

  • 我只想在两个(也只有两个)点之间画一条线。直线。没有什么花哨。不过谢谢
【解决方案3】:

对于 Swift 3,CGPathMoveToPoint 方法不再喜欢 nil 作为第二个参数,所以我需要一个新的解决方案。这是我想出的:

let line_path:CGMutablePath = CGMutablePath()
line_path.move(to: CGPoint(x:x1, y:y1))
line_path.addLine(to: CGPoint(x:x2, y:y2))

【讨论】:

    【解决方案4】:

    为了简单起见,我将绘制一条线所需的所有内容都提取到了SKShapeNode 的扩展中,这样您就可以使用startend 点以及strokeColorstrokeWidth(您可以随时预设这些或设置默认值)

    extension SKShapeNode {
        convenience init(start: CGPoint,
                         end: CGPoint,
                         strokeColor: UIColor,
                         lineWidth: CGFloat) {
            self.init()
    
            let path = CGMutablePath()
            path.move(to: start)
            path.addLine(to: end)
    
            self.path = path
            self.strokeColor = strokeColor
            self.lineWidth = lineWidth
        }
    }
    

    基本思想是,它将使用提供的点创建一个 CGMutablePath,并将其分配给形状节点以绘制一条线。

    叫它:

    let horizontalLine = SKShapeNode(start: CGPoint(x: 0, y: 50),
                                     end: CGPoint(x: size.width, y: 50),
                                     strokeColor: .orange,
                                     lineWidth: 2.0)
    addChild(horizontalLine)
    

    还有输出:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-08
      • 2016-11-06
      相关资源
      最近更新 更多