在多个网格A*寻路
来源:互联网 发布:app下不了软件 编辑:程序博客网 时间:2024/05/11 04:12
本文选自StackOverflow(简称:SOF)精选问答汇总系列文章之一,本系列文章将为读者分享国外最优质的精彩问与答,供读者学习和了解国外最新技术。本文将为读者讲解Unity中在多个网格A*寻路。
问题:
Caius Eugene
我正尝试着在一个cube周围执行A*寻路,这个cube是由6个网格组成的,为了保持简单,我用了四个函数:GetXPlus, GetXMinus, GetYPlus, GetYMinus。每个函数检查下一个砖块是否在最近的网格空间之内,如果不是就切换到相应的网格。
我遇到的问题是:当试图从当前网格翻转到其他方式的网格获得砖块时,返回的砖块是在相对的一侧。是否有方法让我避免为每个单个原有网格和方向写特定逻辑?
为了阐明我的问题,下图源自网格(紫色),使用GetXPlus函数:
目前执行的snippit (每格64*64):
public Tile GetXPlus( int currentX, int currentY )
{
var
newX = currentX + 1;
var
tile = GetTile( newX , currentY );
if
( newX > 64 )
//Get adjacent XPlus Grid
{
currentGrid = SetCurrentGrid( XPlusGridIndex );
tile = GetTile( newX - 64, currentY );
}
return
tile;
}
背景
这个实现源自于另一个问题的回答:
http://gamedev.stackexchange.com/questions/53866/pathfinding-on-a-uneven-planetary-surface
答案:
Corniel Nobel
我建议你可以比先前的答案走的更远。创建一个cube代表所有的砖块,你要缓存每个砖块周围的东西。砖块之间的关系是固定的,这能给你节省不少时间。
之后亦可以用double[,,] 或者int[,,,] 跟踪你处理的砖块,并在此基础上添加邻近物到Queue<Tile>.
如果需要你也可以执行GetDirection(Tile tile)。那个函数只需要在方向dictionary上搜寻。
public class Cube { private Tile[,,] tiles;
public Cube(int size)
{
tiles =
new
Tile[size, size, 6];
// initialize.
for
(
var
side = 0; side < 6; side++)
{
for
(
var
x = 0; x < size; x++)
{
for
(
var
y = 0; y < size; y++)
{
tiles[x, y, side] =
new
Tile(x, y, side);
}
}
}
// set directions & neighbors
for
(
var
side = 0; side < 6; side++)
{
for
(
var
x = 0; x < size; x++)
{
for
(
var
y = 0; y < size; y++)
{
// todo: implement.
}
}
}
}
public Tile
this
[int x, int y, int side]
{
get
{
return
tiles[x, y, side];
}
}
}
public class Tile
{
private Dictionary<DirectionType, Tile> directions =
new
Dictionary<DirectionType, Tile>();
private Tile[] neighbors =
new
Tile[4];
public Tile(int x, int y, int side)
{
this
.X = x;
this
.Y = y;
this
.Side = side;
}
public int X { get; private set; }
public int Y { get; private set; }
public int Side { get; private set; }
public Tile
this
[DirectionType dir]
{
get
{
return
directions[dir];
}
}
public Tile[] Neighbors { get {
return
neighbors; } }
}
public enum DirectionType
{
// delta: +1, 0
e,
// delta: 0, +1
n,
// delta: -1, 0
w,
// delta: 0, -1
s,
// delta: 0, 0
X
}
Tilo
你可以使用函数映射,从X Y Z坐标以及砖块组成的3D空间到另一个。
执行个命令:
enum TileBorder
{
Left = 0,
Top = 1,
Right = 2,
Bottom = 3
}
你可以在Tile class数组里存储这些改变:
class Tile
{
public Tile[] Neighbors { get; set; }
public Func<int, int, int>[] XTransitions { get; set; }
public Func<int, int, int>[] YTransitions { get; set; }
public void GetXPlus(int x, int y, out int newX, out int newY, out Tile newTile)
{
x++;
if
(x <= 64)
{
newX = x;
newY = y;
newTile =
this
;
}
else
{
newX = XTransitions[(int)TileBorder.Right](x, y);
newY = YTransitions[(int)TileBorder.Right](x, y);
newTile = Neighbors[(int)TileBorder.Right];
}
}
// ...
}
接下来你只需要在建立结构的时候注意一下就可以了。例如:这是你设置绿色砖块的方法,假设坐标包含1到64.
Tile pink =
new
Tile();
Tile green =
new
Tile();
Tile orange =
new
Tile();
Tile purple =
new
Tile();
Tile blue =
new
Tile();
green.Neighbors =
new
Tile[]
{
/* left */
orange,
/* top */
pink,
/* right */
blue,
/* bottom */
purple
};
green.XTransitions =
new
Func<int, int, int>[]
{
/* left */
(x, y) => 1,
/* top */
(x, y) => x,
/* right */
(x, y) => 64,
/* bottom */
(x, y) => x
};
green.YTransitions =
new
Func<int, int, int>[]
{
/* left */
(x, y) => 65 - y,
/* top */
(x, y) => 64,
/* right */
(x, y) => 65 - y,
/* bottom */
(x, y) => 1
};
注意砖块转变函数只是一个查找,为了充分灵活你也可以使用下面这些类型的函数:
X轴:Func<int, int, Tile, int>
Y轴:Func<int, int, Tile, int>
Z轴:Func<int, int, Tile, Tile>
- 在多个网格A*寻路
- Unity3D 多个网格模型合并 插件
- 怎么在ZBrush中插入多网格
- 在Android中的网格间距
- 13 个最佳 JavaScript 数据网格库
- ar 多个.a 到一个.a
- 网格
- 网格
- 网格
- 网格
- Eclipse:如何把多个项目放在一个文件夹下 <create a working set>
- IBM在网格方面的最新进展
- 网格控件GridView在Android中的使用
- 20.机器人逃犯:在网格中射击
- 网格控件GridView在Android中的使用
- 网格视图在Android应用程序中的使用
- 用matlab在图片上画出网格
- 在图像上添加网格【matlab】
- 算法之道(一)(未完,待续)
- 浏览器崩溃原因大集合
- 建立XML来发送到服务器。
- Apache Hadoop YARN – Concepts & Applications
- 译_jBPM4用户指南:第二章_安装
- 在多个网格A*寻路
- Apache Hadoop YARN – ResourceManager
- sql
- Apache Hadoop YARN – NodeManager
- C#异步调用的好处和方法分享
- 制作下雨的雨滴
- sql
- wireshark install/build on Ubuntu 12.04
- C# 异步回调