Создайте линию с двумя CGPoints SpriteKit Swift

Я пытаюсь сделать простое приложение, в котором вы касаетесь точки, и спрайт следует по линии до этой точки до края экрана, независимо от того, где вы касаетесь. Я хочу нарисовать сегменты линии, соединяющие начало спрайта (точка начала) и точку, в которую вы касались, и между началом спрайта и конечной точкой на краю экрана, чтобы я мог визуализировать путь спрайт и связь между смещениями x и y начала координат, точки касания и конечной точки.

Надеюсь, это было не слишком странно.

TL; DR: Мне нужно нарисовать линию между двумя точками, и я не знаю, как это сделать, используя SpriteKit Swift.

Спасибо заранее.

Ответ 1

Это можно сделать с помощью CGPath и SKShapeNode.

Давайте начнем с CGPath. CGPath используется, когда нам нужно построить путь, используя ряд фигур или линий. Пути - это линия, соединяющая две точки. Итак, чтобы сделать строку:

  • moveToPoint: устанавливает текущую точку пути в указанную точку.
  • 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)

Теперь, чтобы сделать видимый путь и присвоить ему атрибуты, такие как цвет штриха, ширина строки и т.д., вы создаете SKShapeNode в SpriteKit и добавляете к нему путь.

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

Надеюсь, это поможет:).

Ответ 2

Следуйте ЭТО, шаг за шагом, и вы можете это достичь.

Рассмотрим приведенный ниже код:

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

Это простой метод. Вы получаете следующую позицию пальца пользователя, и если вы нашли свиньи в touchesBegan(_:,withEvent:), как указано значением non-nil movingPig, вы добавляете положение этой свиньи в качестве следующей путевой точки.

До сих пор вы можете сохранить путь для свиньи - теперь пусть свинья будет следовать этому пути. Добавьте следующий код в update() внутри GameScene.swift:

dt = currentTime - lastUpdateTime
lastUpdateTime = currentTime

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

И вы можете увидеть результат:

enter image description here

Линии рисования:

В настоящий момент только свиньи знает путь, по которому он хочет путешествовать, но сцена также должна знать этот путь, чтобы нарисовать его. Решение этой проблемы - новый метод для вашего класса 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)
    }
  })
}

И вот ваш результат:

enter image description here

И вы можете установить этот путь для свиньи.

Вы можете изменить это в соответствии с вашими потребностями.

Надеюсь, это поможет.

Ответ 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, которое позволяет вам создать линию с start & Точка end, а также strokeColor и strokeWidth (вы всегда можете предварительно установить их или установить значения по умолчанию, если захотите)

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)

И вывод:

enter image description here