GameplayKit>场景编辑器导航图>如何使用它进行寻路?

时间:2016-12-18 10:45:41

标签: ios swift sprite-kit path-finding gameplay-kit

不久前,Apple向Xcode的场景编辑器介绍了GameplayKit元素,这很棒。但是,我似乎遇到导航图元素的问题: Scene Editor Navigation Graph

我尝试实现的是从场景编辑器中绘制GKGraph,在代码中检索它,并将其用作寻路的基础。

所以我先画一个GKGraph:

Scene Editor drawn GKGraph

然后我在GameScene.swift中检索它:

graph = self.graphs.values.first

其中图形是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个节点来定义路径?非常感谢您的回答。

1 个答案:

答案 0 :(得分:3)

在从Scene Editor创建的GKGraph上调用时,似乎GameplayKit的 .findPath 方法无法正常工作。我所做的是,我将节点从预先绘制的GKGraph克隆到以编程方式创建的GKGraph:

let newGraph = GKGraph()
for drawnNode in graph.nodes! {
    newGraph.add([drawnNode])
}

然后, .findPath 就可以了。

newGraph.connectToLowestCostNode(node: startNode, bidirectional: true)
newGraph.connectToLowestCostNode(node: endNode, bidirectional: true)
let path: [GKGraphNode] = newGraph.findPath(from: startNode, to: endNode)

变量path现在包含考虑所有10 + 2个节点生成的路径。

总结:您无法直接使用在场景编辑器中创建的导航图进行路径查找。我的解决方案是首先将其节点克隆到以编程方式创建的GKGraph,然后使用最新的节点来完成剩下的工作。