Не так давно Apple представила элементы GameplayKit в редакторе сцен Xcode, и это здорово. Однако у меня возникли проблемы с элементом Navigation Graph:
Чего я пытаюсь добиться, так это нарисовать GKGraph из редактора сцен, получить его в коде и использовать в качестве основы для поиска пути.
Итак, сначала я рисую GKGraph:
Затем я получаю его в GameScene.swift следующим образом:
graph = self.graphs.values.first
где graphs — это предопределенный Apple массив для хранения GKGraphs из редактора сцен. Все идет нормально.
Затем я хочу, чтобы игрок нашел путь к месту касания на экране. Для этого я использую UITapGestureRecognizer со следующим методом обратного вызова:
var moving = false
func moveToLocation(recognizer: UITapGestureRecognizer) {
var tapLocation = recognizer.location(in: recognizer.view!)
tapLocation = self.convertPoint(fromView: tapLocation)
guard (!moving) else { return }
moving = true
let startNode = GKGraphNode2D(point: vector_float2(Float(player.visualComponent.node.position.x), Float(player.visualComponent.node.position.y)))
let endNode = GKGraphNode2D(point: vector_float2(Float(tapLocation.x), Float(tapLocation.y)))
NSLog(graph.nodes.debugDescription)
graph.connectToLowestCostNode(node: startNode, bidirectional: true)
graph.connectToLowestCostNode(node: endNode, bidirectional: true)
NSLog(graph.nodes.debugDescription)
let path: [GKGraphNode] = graph.findPath(from: startNode, to: endNode)
guard path.count > 0 else { moving = false; return }
var actions = [SKAction]()
for node: GKGraphNode in path {
if let point2d = node as? GKGraphNode2D {
let point = CGPoint(x: CGFloat(point2d.position.x), y: CGFloat(point2d.position.y))
let action = SKAction.move(to: point, duration: 1.0)
actions.append(action)
}
}
graph.remove([startNode, endNode])
// Convert those actions into a sequence action, then run it on the player node.
let sequence = SKAction.sequence(actions)
player.visualComponent.node.run(sequence, completion: { () -> Void in
// When the action completes, allow the player to move again.
self.moving = false
})
}
Используя этот метод, я заставляю игрока перейти к месту касания. Проблема в том, что путь, возвращаемый GameplayKit, включает только startNode и endNode, а это означает, что игрок вообще не идет по предварительно нарисованному GKGraph, а идет прямо. в endNode.
Примечание. При первом запуске NSLog(graph.nodes.debugDescription) отображаются все 10 предварительно нарисованных узлов. Когда я снова запускаю его после graph.connectToLowestCostNode, я получаю все 12 узлов. Так что мой график, кажется, содержит все необходимое для поиска пути.
Как вы думаете, в чем проблема? Почему graph.findPath не использует предварительно нарисованные 10 узлов для определения пути? Ваши ответы будут высоко оценены.