Arrays 平面地图上最快的路径
我正试着让部队种植木材,然后把它带回营地。我使用的是包含在二维数组中的随机生成的贴图。请看这里: 我做了一些我写的BFS,我保留了一个前辈的二维数组,我还使用一个二维数组来标记我已经检查过的位置。当我找到要搜索的块(木头)时,我使用前置数组创建最快的路径 在单位数量达到100个之前,这个代码工作得很好(当木头远离时,它也会变慢) 有50个单元: 有了100台,我就有了小冰箱: 以下是“BFS”:Arrays 平面地图上最快的路径,arrays,unity3d,path,shortest-path,a-star,Arrays,Unity3d,Path,Shortest Path,A Star,我正试着让部队种植木材,然后把它带回营地。我使用的是包含在二维数组中的随机生成的贴图。请看这里: 我做了一些我写的BFS,我保留了一个前辈的二维数组,我还使用一个二维数组来标记我已经检查过的位置。当我找到要搜索的块(木头)时,我使用前置数组创建最快的路径 在单位数量达到100个之前,这个代码工作得很好(当木头远离时,它也会变慢) 有50个单元: 有了100台,我就有了小冰箱: 以下是“BFS”: void findPathTo(){ 队列q=新队列(); //设定位置 intx=(int)t
void findPathTo(){
队列q=新队列();
//设定位置
intx=(int)transform.position.x;
int y=(int)transform.position.z;
//将标记数组设置为false
对于(int i=0;i=0&&l1[1]>=0&&!标记为[l1[0]][l1[1]]){
q、 排队(l1);
前置[l1[0]][l1[1]][0]=x;
前置[l1[0]][l1[1]][1]=y;
}
}
//对于每个添加的元素
while(q.ToArray().Length!=0){
int[]l=(int[])q.Dequeue();
如果(!标记为[l[0]][l[1]]){
标记为[l[0]][l[1]]=true;
//如果找到要搜索的块,请创建路径并退出
如果(gm.map[l[0]][l[1]!=null&&gm.map[l[0]][l[1]]].GetType()==typeof(T)){
dest=(ObjectInterface)gm.map[l[0]][l[1]];
如果(gm.map[l[0]][l[1]].isFarmable())
gm.map[l[0]][l[1]]=null;
int i=l[0];
int j=l[1];
//设定路径
而(i>=0&&j>=0&&preference[i][j][0]!=-1&&preference[i][j][1]!=-1){
推送路径(前置[i][j]);
i=前身[i][j][0];
j=前任[i][j][1];
}
int[]next=(int[])path.Pop();
destX=next[0];
destY=next[1];
打破
}
//如果我们可以在此曲面上移动,则添加未标记的相邻块
如果(gm.map[l[0]][l[1]]==null){
对于(int i=0;i<4;i++){
int[]l1={l[0]-pos[i,0],l[1]-pos[i,1]};
如果(l1[0]=0&&l1[1]>=0&&!标记为[l1[0]][l1[1]]){
q、 排队(l1);
前置[l1[0]][l1[1]][0]=l[0];
前置[l1[0]][l1[1]][1]=l[1];
}
}
}
}
}
}
BFS的想法不能支持大量的单位,所以我可能应该使用*(我还没有读到太多关于它的内容)。但我也考虑过制作一个二维数组(对于木材,我必须为黄金添加一个数组…),其中包含到最近的木块的后续数组,但它必须经常更新,所以这可能不是一个好主意
你觉得怎么样?虽然这是一个有趣的讨论点,但它确实不适合这样做。也许试试gamedev forumPS,你知道unity完全内置了寻路功能吗?首先值得一试。另外,看看蚂蚁系统,它们在游戏相关的应用程序中使用非常有趣,比如这一个(动态信息素水平创建单位可能遵循的信息素轨迹)。
void findPathTo<T>() {
Queue q = new Queue();
// Set position
int x = (int)transform.position.x;
int y = (int)transform.position.z;
// Set marked array to false
for (int i = 0; i < gm.mapSizex; i++) {
for (int j = 0; j < gm.mapSizey; j++)
marked[i][j] = false;
}
// Set predecessor array to -1
for (int i = 0; i < gm.mapSizex; i++) {
for (int j = 0; j < gm.mapSizey; j++) {
for (int k = 0; k < 2; k++)
predecessor[i][j][k] = -1;
}
}
// Add element adjacent to current pos
marked[x][y] = true;
int[,] pos = new int[4,2] { { 0, 1 }, { 0, -1 }, { -1, 0 }, { 1, 0 } };
for (int i = 0; i < 4; i++) {
int[] l1 = { x - pos[i,0], y - pos[i,1] };
if (l1[0] < gm.mapSizex && l1[1] < gm.mapSizey && l1[0] >= 0 && l1[1] >= 0 && !marked[l1[0]][l1[1]]) {
q.Enqueue(l1);
predecessor[l1[0]][l1[1]][0] = x;
predecessor[l1[0]][l1[1]][1] = y;
}
}
// For each added element
while (q.ToArray().Length != 0) {
int[] l = (int[])q.Dequeue();
if (!marked[l[0]][l[1]]) {
marked[l[0]][l[1]] = true;
// If the block we're searching is found create the path and exit
if (gm.map[l[0]][l[1]] != null && gm.map[l[0]][l[1]].GetType() == typeof(T)) {
dest = (ObjectInterface)gm.map[l[0]][l[1]];
if(gm.map[l[0]][l[1]].isFarmable())
gm.map[l[0]][l[1]] = null;
int i = l[0];
int j = l[1];
// Set the path
while (i >= 0 && j >= 0 && predecessor[i][j][0] != -1 && predecessor[i][j][1] != -1) {
path.Push(predecessor[i][j]);
i = predecessor[i][j][0];
j = predecessor[i][j][1];
}
int[] next = (int[])path.Pop();
destX = next[0];
destY = next[1];
break;
}
// If we can move on this surface add unmarked adjacent blocks
if (gm.map[l[0]][l[1]] == null) {
for (int i = 0; i < 4; i++) {
int[] l1 = { l[0] - pos[i, 0], l[1] - pos[i, 1] };
if (l1[0] < gm.mapSizex && l1[1] < gm.mapSizey && l1[0] >= 0 && l1[1] >= 0 && !marked[l1[0]][l1[1]]) {
q.Enqueue(l1);
predecessor[l1[0]][l1[1]][0] = l[0];
predecessor[l1[0]][l1[1]][1] = l[1];
}
}
}
}
}
}