【问题标题】:How to build an Apple GameplayKit GKGridGraph如何构建 Apple GameplayKit GKGridGraph
【发布时间】:2022-11-20 02:24:38
【问题描述】:

我正在使用 Swift 和 Apple 的 SpriteKit 和 GameplayKit 框架构建一个回合制策略游戏。我正在尝试使用 GameplayKit 提供的 GKGridGraph 数据结构来表示地图网格,但在弄清楚如何构建 GKGridGraph 时遇到了问题。如果你构建一个 GKGridGraphNodes 数组,然后使用 add() 方法将它们添加到一个空的 GKGridGraph 中,网格图不知道网格,即使节点在图中“中”。请参阅下面的沙箱代码:

override func sceneDidLoad() {
    // Dimensions of our grid
    let width: Int32 = 4
    let height: Int32 = 4

    // Create an empty graph
    let graph = GKGridGraph()

    // Create a mutable array to hold the nodes
    var nodes: [GKGridGraphNode] = []

    // Build up the array of empty graph nodes
    for row in 0..<height {
        for col in 0..<width {
            let position = SIMD2<Int32>(Int32(col), Int32(row))
            nodes.append(GKGridGraphNode(gridPosition: position))
        }
    }

    // Add all the nodes
    graph.add(nodes)

    // Try to find each node in the grid.
    // No nodes are found using node() method.
    for row in 0..<height {
        for col in 0..<width {
            let pos = SIMD2<Int32>(Int32(col), Int32(row))

            if let _ = graph.node(atGridPosition: pos) {
                print("Found node at [\(row),\(col)]")
            }
        }
    }
}

GKGridGraph 方法 node(atGridPosition) 不会在网格中找到任何节点。我发现以这种方式构造 GKGridGraph 使其意识到自己的网格的唯一方法是使用构造函数:

init(fromGridStartingAt: vector_int2, 
     width: Int32, 
     height: Int32, 
     diagonalsAllowed: Bool, 
     nodeClass: AnyClass)

它确实构建了一个网格感知图。但是,我想出的唯一方法(基于阅读书籍、网站和 API 文档)如何删除我不想遍历的节点是使用 GKGraph remove() 方法。但是,我发现 remove 方法的性能非常糟糕,因此构建“完整”网格图然后返回并删除我不想出现在图中的节点对我来说是行不通的。我不知道为什么 remove() 的性能如此糟糕(可能不得不切断所有相邻的连接),但对于大网格来说它似乎几乎无法使用。

我还尝试在添加节点数组后手动添加所有节点到节点的连接,但这对使用 node() 方法在特定网格位置检索节点没有影响。

有谁知道如何做我想完成的事情:仅使用我最初想要在图中的节点完全构建 GKGridGraph?

【问题讨论】:

    标签: ios swift sprite-kit gameplay-kit


    【解决方案1】:

    正如你所说,GKGridGraph 的 remove 方法性能很差,几个小时后我找到了一个有效的修复方法

    主要思想是永远不要使用 remove 方法,而只是手动断开和重新连接节点。

    这是您要从 gridGraph 中删除的 wallNode 的示例

    let wallNode = gridGraph.node(gridPosition: vector(Int32(column), Int32(row))
    wallNode.removeConnections(to: wallNode.connectedNodes, bidirectionnal: true)
    

    对于您的特定问题,您应该只对图中的所有节点执行此操作,然后重新连接您想要的节点

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-15
      相关资源
      最近更新 更多