关于A星寻路的一些代码
来源:互联网 发布:零基础学算法可行 编辑:程序博客网 时间:2024/06/16 18:01
好不容易攒出了几个东西写在博客上面,看CSDN上面的大神太多,我还是吧这些博客当成笔记或日记来写吧,想来网站也不会封了我
Unity的东西我感觉到了个瓶颈,有点难提升,官方的文档全英文看不懂,自己感觉还是去做做项目会好一点,等这几天把Shader研究到放弃,笔记博客谢谢好,就要开始大量“抄”项目了,看见什么实现什么。不多说,还是实现A星吧。
A星的思想大家可以百度一下,我这里就简单提一下公式:F=G+H
F就是我们需要进行排序的值,G是已经过的路程长度(相当于),H是将要走的路程(也是相当于),具体百度,写不出来~
大体的思想就是:一个出发点A和一个终点B,从A开始向四周遍历值F,如果位置合法(不越界,未访问,非障碍)加入到list集合中,把遍历过的点加入visited集合中,在每次遍历list的时候,根据F值进行排序,取最小的F值点,向八个方向遍历,把位置合法的点存入list中,直到list为空。而路径的求法就是在一开始定义点这个类的时候加点思想就可以啦,每个点都有一个父节点,在向八个方向访问的时候赋值,最后取路劲的时候,会把点从后往前推,直到起点A,我这用了一个Stack存储,也可以用list,然后倒一下,都行。然后贴上代码:
注:看懂了地图自己生成吧我这是0是起点,9是终点,1是可行走点,2是障碍物点。大小6*8(看你喜欢)usingUnityEngine;
usingSystem.Collections.Generic;
usingSystem.IO;
publicclassAStar:MonoBehaviour
{
byte[,] mapData =newbyte[6, 8];
Vector2start;
Vector2end;
//存放未访问的节点
List<Node> list =newList<Node>();
//存放已访问的节点
List<Node> visited =newList<Node>();
//路径
Stack<Vector2> path =newStack<Vector2>();
Vector2[] dirs =newVector2[] {Vector2.left,Vector2.right,Vector2.up,Vector2.down ,
newVector2(1, 1),newVector2(-1, 1),newVector2(1, -1),newVector2(-1, -1) };
GameObjectplayer;
Vector3moveDir;
Vector3target;
publicvoidStart()
{
LoadMapData();
BuildMap();
BFS();
player =GameObject.CreatePrimitive(PrimitiveType.Sphere);
player.transform.position = GetPosition(start);
target = GetPosition(path.Peek());
}
publicvoidUpdate()
{
moveDir = (target - player.transform.position).normalized;
player.transform.Translate(moveDir *Time.deltaTime);
if(Vector3.Distance(player.transform.position, target) < 0.1f)
{
path.Pop();
if(path.Count == 0)
{
this.enabled =false;
}
else
{
target = GetPosition(path.Peek());
}
}
}
Vector3GetPosition(Vector2pos)
{
floatpos_x = -3 + pos.y;
floatpos_y = 4 + pos.x;
returnnewVector3(pos_x, 1, pos_y);
}
///<summary>
///获取起始点和终止点
///</summary>
voidGetStartEnd()
{
for(inti = 0; i < mapData.GetLength(0); i++)
{
for(intj = 0; j < mapData.GetLength(1); j++)
{
if(mapData[i, j] == 0)
{
start.x = i;
start.y = j;
}
elseif(mapData[i, j] == 9)
{
end.x = i;
end.y = j;
}
}
}
}
///<summary>
///关于Node类的排序规则
///</summary>
///<param name="x"></param>
///<param name="y"></param>
///<returns></returns>
intNodeSort(Nodex,Nodey)
{
if(x.F == y.F)
{
return0;//表示不交换位置
}
elseif(x.F > y.F)
{
return1;//表示交换位置
}
else
{
return-1;//表示不交换位置
}
}
///<summary>
///判断是否合法
///</summary>
///<param name="point"></param>
///<returns></returns>
boolisOk(Vector2point)
{
//越界
if(point.x < 0 || point.y < 0 || point.x > mapData.GetLength(0) || point.y > mapData.GetLength(1))
{
returnfalse;
}
//障碍物
if(mapData[(int)point.x, (int)point.y] == 2)
{
returnfalse;
}
//已访问
for(inti = 0; i < visited.Count; i++)
{
if(visited[i].X == point.x && visited[i].Y == point.y)
{
returnfalse;
}
}
returntrue;
}
///<summary>
///A*算法
///</summary>
voidAStar()
{
GetStartEnd();
Noderoot =newNode(start);
list.Add(root);
while(list.Count > 0)
{
list.Sort(NodeSort);
//先按F值排序,后取出F值最小的节点
Nodenode = list[0];
list.Remove(node);//移除
visited.Add(node);//添加节点到已访问集合
for(inti = 0; i < dirs.Length; i++)
{
Vector2point;
point.x = node.X + dirs[i].x;
point.y = node.Y + dirs[i].y;
//判断位置是否合法
if(isOk(point))
{
Noden =newNode(point, node);
n.G = i > 3 ? node.G + 14 : node.G + 10; G += 14 或10(基于方向是正的还是斜的)
n.CalcuteH(newNode(end)); ((end.x-n.x + end.y-n.y)*10 )
n.CalucuteF(); F=G+H
list.Add(n);
if(point == end)
{
Debug.Log("Find!!");
Nodep = n;
//逆序输出路径
while(p !=null)
{
path.Push(newVector2(p.X, p.Y));
p = p.Parent;
}
return;
}
}
}
}
}
///<summary>
///给mapData赋值
///</summary>
voidLoadMapData()
{
stringpath =Application.dataPath +"/Map/Map2.txt";
StreamReadersr =newStreamReader(path);
stringdata = sr.ReadToEnd();
string[] allData = data.Split('\n');
for(inti = 0; i < 6; i++)
{
for(intj = 0; j < 8; j++)
{
mapData[i, j] =byte.Parse(allData[i][j].ToString());
}
}
sr.Close();
sr.Dispose();
}
///<summary>
///根据mapData创建地图
///</summary>
voidBuildMap()
{
GameObjectCube =Resources.Load("Cube")asGameObject;
GameObjectBlueCube =Resources.Load("BlueCube")asGameObject;
GameObjectRedCube =Resources.Load("RedCube")asGameObject;
GameObjectGreenCube =Resources.Load("GreenCube")asGameObject;
for(inti = 0; i < mapData.GetLength(0); i++)
{
for(intj = 0; j < mapData.GetLength(1); j++)
{
GameObjectcube;
switch(mapData[i, j])
{
case0: cube = Instantiate(GreenCube);break;
case1: cube = Instantiate(Cube);break;
case2: cube = Instantiate(RedCube);break;
case9: cube = Instantiate(BlueCube);break;
default:
cube = Instantiate(Cube);
break;
}
cube.transform.position =newVector3(-3 + j, 0, 4 + i);
cube.transform.localScale =Vector3.one * 0.8f;
cube.transform.SetParent(transform);
}
}
}
}
0 0
- 关于A星寻路的一些代码
- 关于数据处理的一些代码
- 关于代码的一些思考
- 关于Portal的一些代码
- 关于pydbg的一些代码
- 关于动作的一些代码
- 关于 (int&)a 的一些讨论
- 关于标签<a>的一些用法总结
- 关于A*算法的一些研究
- 关于恢复注册表修改的一些代码
- 关于截屏的一些代码
- 关于Struts2的一些实例代码
- 关于 鱼宝宝的一些代码
- 关于qtp的又一些代码
- 一些关于Android的代码地址
- 关于 HOG 代码 的一些解释
- 一些关于C#处理进程的代码
- 一些关于C#发送邮件的代码
- Linux指令
- 总结:操作系统相关知识
- 快乐、聪明和有用,你会如何选择?
- 多边形重心问题
- Swift学习笔记 ---Properties
- 关于A星寻路的一些代码
- 《福布斯》2011 年评腾讯创新能力全球第四,超越苹果和谷歌,如何理解?
- 屏幕横竖发生变化时,当前Activity发生的生命周期变化
- 【概念笔记】JAVA基础 - part1
- 粗糙集(Rough set) 理论
- 第五周-raptor 矩形面积计算
- 软件工程导论作业
- Android Studio快捷键
- hiho1388 FFT/NTT