在用户想要通过鼠标导航或触摸某些无法通过的地图的场景中。将点发送到GKObstacleGRpah
FindPath 时,它只返回一个空数组。
我希望该单元能够到达最近(或足够近)的可通过点。
什么是在GKObstacleGraph
.
我知道我可以得到,GKObstacle
所以我可以枚举它的顶点,我知道我的单位的位置......
但是好吧......下一步是什么?
注意:我没有使用GKAgengts
.
在用户想要通过鼠标导航或触摸某些无法通过的地图的场景中。将点发送到GKObstacleGRpah
FindPath 时,它只返回一个空数组。
我希望该单元能够到达最近(或足够近)的可通过点。
什么是在GKObstacleGraph
.
我知道我可以得到,GKObstacle
所以我可以枚举它的顶点,我知道我的单位的位置......
但是好吧......下一步是什么?
注意:我没有使用GKAgengts
.
这是我在解决这个问题时的想法。可能有一个更简单的答案,但我还没有找到。
1. 判断一个点是否有效。
为此,我实际上有每个障碍物的 CGPath 表示。我从PhysicsEditor导出路径,然后通过将它们转换为 CGPath 的自定义脚本加载它们。我总是将该 CGPath 与我从路径创建的 GKObstacle 一起存储。最后,我可以调用CGPathContainsPoint
来确定障碍物包含的点。如果属实,我知道这一点是无效的。
2.一旦点无效,找出点击了哪个障碍物。
通过我在 #1 中的方法,我已经掌握了 CGPath 和它所属的障碍。
3.找到最近的顶点
现在我知道了障碍物,找到离正在移动的单元最近的顶点。我找不到点击点的壁橱顶点,因为那可能在拐角处。相反,找出所需位置和单位之间的向量。然后,从所需位置通过顶点绘制一条不可见的线。我用这个方程来找出线会交叉的地方。
// http://stackoverflow.com/questions/1811549/perpendicular-on-a-line-from-a-given-point
let k = ((end.y - start.y) * (hitPoint.x - start.x) - (end.x - start.x) * (hitPoint.y - start.y)) / ((end.y - start.y) * (end.y - start.y) + (end.x - start.x) * (end.x - start.x))
let x4 = hitPoint.x - k * (end.y - start.y)
let y4 = hitPoint.y + k * (end.x - start.x)
let ret = float2(x: x4, y: y4)
4. 按单元大小向移动单元偏移交点
知道路径与朝向单元的向量相交的位置,我们可以移动到交叉点 +(向量 * 单元大小)。
5. 边缘案例
当您有两个相互接触的障碍物或者如果您有非常大的障碍物时,这会变得很棘手。用户可能认为他们正在移动到地图的远端,但此脚本将返回到可能在附近的壁橱有效点。正因为如此,我废弃了所有的代码,我只是不允许你移动到无效的位置。出现红色 X 和蜂鸣声,提示用户在地图上选择一个新的有效位置。
6. 演示机器人
我可能是错的,但我隐约记得 Apple 的 DemoBots 有类似的逻辑——它们也可能是一个很好的参考。
7.调试层
我花了很长时间才得到一个概念证明。我强烈建议在调试层上画线以验证您的逻辑。