博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
02.A*
阅读量:6680 次
发布时间:2019-06-25

本文共 7688 字,大约阅读时间需要 25 分钟。

链接:https://pan.baidu.com/s/15j770Uf5IVp3lDskSI-0TA 密码:xq10

在这里插入图片描述
在这里插入图片描述

using System.Collections;using System.Collections.Generic;using UnityEngine;/// /// 格子的类型/// public enum NodeType{
Walk, Stop,}/// /// 格子类/// public class AStarNode{
//格子的坐标 public int x; public int y; //寻路消耗 public float f; //距离起点的距离 public float g; //距离终点的距离(曼哈顿距离) public float h; //格子的父物体 public AStarNode Father; //格子的类型 public NodeType Type; public AStarNode(int x,int y,NodeType nodeType) {
this.x = x; this.y = y; this.Type = nodeType; } }

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

using System.Collections;using System.Collections.Generic;using UnityEngine;/// /// 格子管理器/// public class AStarMgr {
private AStarMgr() {
} private static AStarMgr _instance; public static AStarMgr Instance {
get {
if (_instance==null) {
_instance=new AStarMgr(); } return _instance; } } //地图的宽高 private int mapW; private int mapH; //地图相关所有的格子对象容器 public AStarNode[,] nodes; //开启列表 private List
openList=new List
(); //关闭列表 private List
closeList=new List
(); public void InitMapInfo(int w,int h) {
this.mapW = w; this.mapH = h; nodes=new AStarNode[w,h]; for (int i = 0; i < w; i++) {
for (int j = 0; j < h; j++) {
AStarNode node=new AStarNode(i,j,UnityEngine.Random.Range(0,100)<20?NodeType.Stop:NodeType.Walk); nodes[i, j] = node; } } } //寻路方法 public List
FindPath(Vector2 startPos, Vector2 endPos) {
//首先判断传入的点上方合法 //01. 在地图的范围内 if (startPos.x < 0 || startPos.x >= mapW || startPos.y < 0 || startPos.y >= mapH) {
return null; } if (endPos.x<0||endPos.x>=mapW||endPos.y<0||endPos.y>=mapH) {
return null; } //02.不是阻挡 //得到起点和终点对应的格子 AStarNode start = nodes[(int)startPos.x, (int)startPos.y]; AStarNode end = nodes[(int)endPos.x, (int)endPos.y]; //如果不合法,自己返回为空不能寻路 if (start.Type==NodeType.Stop||end.Type== NodeType.Stop) {
return null; } //清空开启和关闭列表 上一次寻路的数据给清除掉 openList.Clear(); closeList.Clear(); //将开始点放入关闭列表 start.Father = null; start.f = 0; start.g = 0; start.h = 0; closeList.Add(start); while (true) {
//从起点开始 找周围的点 并放入开启列表中 //左上 x-1 y-1 FinNearlyNodeToOpenList(start.x - 1, start.y - 1, 1.4f, start, end); //上 x y-1 FinNearlyNodeToOpenList(start.x, start.y - 1, 1f, start, end); //右上 x+1 y-1 FinNearlyNodeToOpenList(start.x + 1, start.y - 1, 1.4f, start, end); //左 x-1 y FinNearlyNodeToOpenList(start.x - 1, start.y, 1f, start, end); //右 x+1 y FinNearlyNodeToOpenList(start.x + 1, start.y, 1f, start, end); //左下 x-1 y+1 FinNearlyNodeToOpenList(start.x - 1, start.y + 1, 1.4f, start, end); //下 x y+1 FinNearlyNodeToOpenList(start.x, start.y + 1, 1f, start, end); //右下 x+1 y+1 FinNearlyNodeToOpenList(start.x + 1, start.y + 1, 1.4f, start, end); //死路判断 开启列表为空 if (openList.Count==0) {
return null; } //选出开启列表中寻路消耗最小的点 openList.Sort(SortOpenList); //放入关闭列表中 然后再从开启列表中移除 closeList.Add(openList[0]); //找到这个最近的点openList[0],进行下一次的寻路计算 start = openList[0]; openList.RemoveAt(0); //如果这个点已经是终点了 那么得到最终结果返回出去 if (start == end) {
//找到了 List
path=new List
(); path.Add(end); while (end.Father!=null) { path.Add(end.Father); end = end.Father; } path.Reverse(); return path; } //如果这个点 不是终点 那么继续寻路 } } //找到一个相邻的点放入OpenList中 //判断这些点 是否是边界 是否是阻挡 是否在开启和关闭列表中如果不是 才计算 private void FinNearlyNodeToOpenList(int x,int y,float g,AStarNode father, AStarNode end) { if (x<0||x>=mapW||y<0||y>=mapH) { return; } AStarNode node = nodes[x, y]; //OpenList和CloseList中是否包含这个点 if (node==null||node.Type==NodeType.Stop||openList.Contains(node)||closeList.Contains(node)) { return; } node.Father = father; //计算f值 node.g = father.g + g; node.h = Mathf.Abs(end.x - node.x) + Mathf.Abs(end.y - node.y); node.f = node.g + node.f; openList.Add(node); } private int SortOpenList(AStarNode a,AStarNode b) { if (a.f>b.f) { return 1; } else if (a.f==b.f) { return 1; } else { return -1; } }}
using System.Collections;using System.Collections.Generic;using System.Runtime.CompilerServices;using UnityEngine;public enum ColorType{
Normal, Yellow, Red, Green,}public class GameManager : MonoBehaviour{
private GameManager(){
} private static GameManager _instance; public static GameManager Instance {
get {
if (_instance==null) {
_instance = GameObject.FindObjectOfType
(); } return _instance; } } public int beginX=3; public int beginY=5; public int offsetX=2; public int offsetY=-2; public int mapW=5; public int mapH=8; public Dictionary
materialDic; private Dictionary
starNodeDic; List
nodes=new List
(); void Awake() {
materialDic =new Dictionary
(); starNodeDic=new Dictionary
(); materialDic.Add(ColorType.Normal, Resources.Load
("Normal")); materialDic.Add(ColorType.Red,Resources.Load
("Red")); materialDic.Add(ColorType.Yellow, Resources.Load
("Yellow")); materialDic.Add(ColorType.Green, Resources.Load
("Green")); AStarMgr.Instance.InitMapInfo(mapW,mapH); for (int i = 0; i < mapW; i++) { for (int j = 0; j < mapH; j++) { GameObject item = GameObject.CreatePrimitive(PrimitiveType.Cube); item.transform.SetParent(this.transform); item.transform.position=new Vector3(beginX+i*offsetX,beginY+j* offsetY); item.name = i + "_" + j; AStarNode node = AStarMgr.Instance.nodes[i, j]; switch (node.Type) { case NodeType.Stop: item.transform.GetComponent
().material = materialDic[ColorType.Red]; break; } starNodeDic.Add(item,node); } } } private int pos = 1; private Vector2 begin; private GameObject beginObj; private List
list; void Update() { if (Input.GetMouseButtonDown(0)) { RaycastHit info; Ray ray=Camera.main.ScreenPointToRay(Input.mousePosition); if (Physics.Raycast(ray,out info,1000)) { pos += 1; if (pos%2==0) { //清空之前的颜色 if (list!=null) { for (int i = 0; i < list.Count; i++) { foreach (var nodes in starNodeDic) { if (nodes.Value == list[i]) { nodes.Key.gameObject.transform.GetComponent
().material = materialDic[ColorType.Normal]; } } } } beginObj = info.collider.gameObject; begin = new Vector2(starNodeDic[info.collider.gameObject].x, starNodeDic[info.collider.gameObject].y); info.collider.gameObject.transform.GetComponent
().material = materialDic[ColorType.Yellow]; } else { Vector2 end = new Vector2(starNodeDic[info.collider.gameObject].x, starNodeDic[info.collider.gameObject].y); list =AStarMgr.Instance.FindPath(begin, end); if (list!=null) { for (int i = 0; i < list.Count; i++) { foreach (var nodes in starNodeDic) { if (nodes.Value==list[i]) { nodes.Key.gameObject.transform.GetComponent
().material = materialDic[ColorType.Green]; } } } } else { //是死路的时候 清空开始点的颜色 beginObj.gameObject.transform.GetComponent
().material = materialDic[ColorType.Normal]; } } } } }}

转载地址:http://ayrxo.baihongyu.com/

你可能感兴趣的文章
基于LVS的NAT模式实现PHP应用
查看>>
在物质与精神之间实现平衡
查看>>
vim 文本编辑器
查看>>
使用angular做微信内html5开发时碰到的两个坑
查看>>
pvst+
查看>>
博为峰Java技术题 ——JavaEE Servlet 国际化Ⅰ
查看>>
layabox基础:hello world
查看>>
ClassUtil
查看>>
Elastic-Job定时任务
查看>>
真实分享记录我学习Linux系统遇到的问题
查看>>
Linux下查找占用内存最多的进程
查看>>
mongodb 配置文件
查看>>
查看 docker 容器使用的资源
查看>>
Jedis的配置和优化
查看>>
layui + 阿里巴巴iconfont图标库导入
查看>>
2017总结一
查看>>
MySQL中TIMESTAMPDIFF和TIMESTAMPADD函数的用法
查看>>
Power Designer数据库建模工具,正向、逆向工程
查看>>
Libevent学习-02:搭建CentOS下的开发环境
查看>>
yum install 与 yum groupinstall 的区别
查看>>