菜鸟教程小白 发表于 2022-12-12 18:19:30

ios - 引入障碍物时 GKObstacleGraph 找不到路径


                                            <p><p>我正在研究 Gameplaykit 寻路概念验证,但我无法让 GKObstacleGraph 正确找到路径。</p>

<p>在以下代码片段中(它应该在 Xcode 7.2Playground 上工作),如果在创建图形时提供了障碍物,则 path2 始终是一个空数组。如果我使用空的障碍物数组创建 obGraph 对象,则 findPathFromNode 返回正确的路径。 </p>

<p>创建的障碍物应该是一个简单的 U 形多边形,端点在 U 内。</p>

<pre><code>import UIKit

import GameplayKit

let pts = [vector_float2(2,2),
    vector_float2(3,2),
    vector_float2(3,6),
    vector_float2(7,6),
    vector_float2(7,2),
    vector_float2(8,3),
    vector_float2(8,7),
    vector_float2(2,7),
    vector_float2(2,2)]
let obstacle1 = GKPolygonObstacle(points: UnsafeMutablePointer(pts) ,
    count: pts.count)

let obGraph = GKObstacleGraph(obstacles: , bufferRadius: 0)

let startPt = GKGraphNode2D(point: vector_float2(5,9))
let endPt = GKGraphNode2D(point: vector_float2(5,5))
let pt3 = GKGraphNode2D(point: vector_float2(0,0))
let pt4 = GKGraphNode2D(point: vector_float2(0,9))
let pt5 = GKGraphNode2D(point: vector_float2(5,0))
let pt6 = GKGraphNode2D(point: vector_float2(10,0))

obGraph.connectNodeUsingObstacles(startPt)
obGraph.connectNodeUsingObstacles(endPt)
obGraph.connectNodeUsingObstacles(pt3)
obGraph.connectNodeUsingObstacles(pt4)
obGraph.connectNodeUsingObstacles(pt5)
obGraph.connectNodeUsingObstacles(pt6)
startPt.connectedNodes
endPt.connectedNodes
pt3.connectedNodes

let path2 = obGraph.findPathFromNode(startPt, toNode: endPt)
print(path2)
</code></pre></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>我和 jack 有同样的问题。我从 Will 的代码示例开始,并在 Xcode 10.3 中将其翻译为 Swift 5.0。我将它添加到 Xcode 的 <em>Game</em> 项目模板中。我<strong>仍然</strong>得到了相同的结果:来自 <code>findPath(from:to:)</code> 的空数组。</p>

<p>在玩弄了代码之后,我意识到任何与物理相关的东西都会影响路径。显示适用于所有人的代码的唯一方法是包括创建 <code>SKScene</code> 和所有 <code>SKNode</code> 实例。请注意,我在 <code>SKPhysicsWorld</code> 中将 <code>gravity</code> 设置为 0,并且没有向任何内容添加 <code>SKPhysicsBody</code>。</p>

<p>在 Playground 上运行它。您可以通过点击场景中的任意位置来激事件画。</p>

<pre><code>import PlaygroundSupport
import SpriteKit
import GameKit

class GameScene: SKScene {

    let nodeToMove:SKShapeNode = {
      let n = SKShapeNode(circleOfRadius: 10)
      n.lineWidth = 2
      n.strokeColor = UIColor.orange
      n.position = CGPoint(x: -200, y: 150)
      return n
    }()

    override func sceneDidLoad() {
      addChild(nodeToMove)

      let nodeToFind = SKShapeNode(circleOfRadius: 5)
      nodeToFind.lineWidth = 2
      nodeToFind.strokeColor = UIColor.red
      addChild(nodeToFind)
      nodeToFind.position = CGPoint(x: 200, y: -150)

      let nodeToAvoid = SKShapeNode(rectOf: CGSize(width: 100, height: 100))
      nodeToAvoid.lineWidth = 4
      nodeToAvoid.strokeColor = UIColor.blue
      addChild(nodeToAvoid)
      nodeToAvoid.position = CGPoint.zero

      let polygonObstacles = SKNode.obstacles(fromNodeBounds: )
      let graph = GKObstacleGraph(obstacles: polygonObstacles, bufferRadius: 10.0)
      let end = GKGraphNode2D(point: vector2(Float(nodeToMove.position.x), Float(nodeToMove.position.y)))
      let start = GKGraphNode2D(point: vector2(Float(nodeToFind.position.x), Float(nodeToFind.position.y)))
      graph.connectUsingObstacles(node: end)
      graph.connectUsingObstacles(node: start)

      graphNodes = graph.findPath(from: end, to: start) as!
      print(&#34;graphNodes = \(graphNodes)&#34;)
    }

    var graphNodes = ()

    override func touchesEnded(_ touches: Set&lt;UITouch&gt;, with event: UIEvent?) {
      touches.first.flatMap {_ in
            let newActions: = graphNodes.map { n in
                return SKAction.move(to: CGPoint(x: CGFloat(n.position.x), y: CGFloat(n.position.y)), duration: 2)
            }
            nodeToMove.run(SKAction.sequence(newActions))
      }
    }
}

let sceneView = SKView(frame: CGRect(x:0 , y:0, width: 640, height: 480))
let scene = GameScene(size: CGSize(width: 640, height: 480))
scene.scaleMode = .aspectFill
scene.anchorPoint = CGPoint(x: 0.5, y: 0.5)
scene.backgroundColor = UIColor.purple
scene.physicsWorld.gravity = CGVector(dx: 0.0, dy: 0.0)
sceneView.presentScene(scene)

PlaygroundSupport.PlaygroundPage.current.liveView = sceneView
</code></pre>

<p>控制台的输出是:</p>

<pre><code>graphNodes =
</code></pre>

<p>开始状态:</p>

<p> <a href="/image/CxSly.png" rel="noreferrer noopener nofollow"><img src="/image/CxSly.png" alt="Scene before animation starts"/></a> </p>

<p>结束状态:</p>

<p> <a href="/image/1fOFi.png" rel="noreferrer noopener nofollow"><img src="/image/1fOFi.png" alt="Scene after animation completes"/></a> </p>

<p><strong>警告:</strong>我不知道为什么用户点击和动画开始之间需要一整秒。性能调优是一个单独的主题。</p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 引入障碍物时 GKObstacleGraph 找不到路径,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/34901988/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/34901988/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 引入障碍物时 GKObstacleGraph 找不到路径