我正在尝试开发一个简单的2D游戏,其中一些“僵尸”将追逐我。
我计算路径的想法如下(X =路径不可用):
[4] [4] [X] [1] [1] [2] [3] [4] [5]
[3] [X] [X] [0] [1] [X] [X] [X] [5]
[3] [2] [1] [1] [1] [X] [3] [4] [5]
[3] [2] [2] [2] [2] [2] [3] [4] [5]
从0开始,给它周围的位置1值,接近1,给2值等。这样我只需要搜索较低的索引,知道最快达到0的方法。
(1)我不知道这个算法是否有名称,所以我无法真正找到有关它的信息。
(2)计算此
的最佳解决方案/算法/流程(3)在我的手机中,游戏画面的分辨率为1700 x 1440,所以我的代码需要15秒。我创建了一个最终值,以缩小所有内容并降低矩阵大小,但是,stil需要很多,实际上无法播放。
(4)还有其他需求吗?也许添加线程?我不知道是否会起作用......
private void expandAllFrom(int x, int y){ // x and y already scalled down
nodes = new ArrayList<Point>(); // "nodes" is a global variable //
nodes.add(new Point(x, y));
while ( nodes.size() > 0 ){
Point p = nodes.remove(0);
expand(p.x, p.y);
}
}
private void expand(int x, int y){
int limXMin = x - 1, limXMax = x + 1, limYMin = y - 1, limYMax = y + 1;
int value = map[x][y];
// Check limits of screen
if ( limXMin < 0 ) limXMin = 0;
if ( limXMax > SCREEN_X_DIV - 1) limXMax = SCREEN_X_DIV - 1;
if ( limYMin < 0 ) limYMin = 0;
if ( limYMax > SCREEN_Y_DIV - 1) limYMax = SCREEN_Y_DIV - 1;
for (int i = limXMin; i <= limXMax; i++){
for (int j = limYMin; j <= limYMax; j++){
if ( map[i][j] == 0 ) {
if ( i != x || j != y ){
nodes.add(new Point(i, j));
map[i][j] = value + 1;
}
}
}
}
}
我使用FIFO列表。我在那里添加节点,例如,流程将类似于:
(1) Add 0 position to expand node list.
(2) Expand 0 by setting 1 values arround it. Then add them to expand node list.
(2) Expand 1 by setting 2 values arround it. Then add them to expand node list.
(...)
(X) Expand 2 by setting 3 values arround it. Then add them to expand node list.
(Y) Expand 3 by setting 4 values arround it. Then add them to expand node list.
(...)
答案 0 :(得分:2)
这只是 breadth-first search (BFS) ,用于查找单源最短路径。您要计算的数字与每个网格单元所在的级别完全对应。好的是,通过正确实施BFS,您不需要数字。只需在玩家所在位置启动BFS程序,然后让每个僵尸走向他们当前所在单元格的父指针。
答案 1 :(得分:1)
如上所述,你所做的是breadth first search,这是Dijkstra's algorithm的一个特例。为自己找到它做得好!
问题是,BFS的时间复杂度为O(V+E)
,其中V
是节点数,E
是边数。在您的情况下,它将按照地图大小的顺序排列,具体取决于地图的稀疏程度(即,有多少X-es)。对于大小为1700x1440的地图,无论如何都是数百万。
如果僵尸的数量不是太大,那么逐个计算每个僵尸的最短路径会更快(你仍然可以在僵尸之间共享和重新使用扩展的节点),使用BFS的变体用启发式方法。例如,jump point search针对统一成本迷宫进行了优化(跳转点搜索是A-star algorithm的特例)。
这个想法是采取一个起点(一个僵尸的位置)和一个终点(玩家的位置),并计算它们之间的最短路径,扩展更接近的节点首先到达目的地。这里更接近意味着到端点的近似距离更小。到达节点的距离是已知的,并且A星将选择从起点到节点的距离之和加上从节点到末端的近似距离最小的节点。由于您允许对角移动,距离近似不能是Manhattan distance,也不能是Eucledian距离,因为近似值必须是实际距离的下限。你可以采取例如。 max(│x-x&#39;│,│y-y&#39;│)。跳跃点搜索通过利用地图的迷宫结构进一步改善了这一点,以排除更多节点。
This site动画了几个这样的算法,这样你就可以了解它们是如何工作的。
这种方法的好处在于你不会搜索整个地图,只有它的一小部分位于僵尸和玩家之间。这可能已经比任何全尺寸BFS算法快几个数量级。要显示加速速度有多大,请查看以下图像。搜索只搜索标记的节点:
另一个优点是,您可以在运行时间和“聪明”之间做出妥协。的僵尸。您所要做的就是不要将这样的算法一直运行到终点。您可以在预定义的步数之后停止,并获得路径开头的近似值(通过查看起点和最有希望的节点之间的最短路径,然后展开)。因此,根据您计算的时间长短,您可能拥有最佳或不太理想的僵尸。