A*自动寻路算法—java版(八方向版)

2023-11-16

上一篇博客分享了Java版的自动寻路,但是只是上下左右四个方向的,今天把八方向的也分享出来。


既然四方向的已经成功了,那么改进成八方向的,只要注意两个地方就可以了,一个是获取四周方块的时候,一个是移动的时候。


一、获取四周方块

在autofindway.java中添加静态变量,用来标识上下左右四个方向是否可通过。

//在获取上下左右四个方块的时候,判断各个方块是否满足条件(比如:只有右边和下边的方块都可通过的时候,才能去判断右下方的方块是否满足条件,否则就是穿墙了)
	private static boolean top = false;
	private static boolean down = false;
	private static boolean left = false;
	private static boolean right = false;

在获取四周方块的方法aroundFk中,考虑左上、右上、右下、左下四个方块的判断。

其中,上下左右四个方块的判断中,如果可以通过,则将对应的方向(top/down/left/right)标识为true。只有在左边和上边方块都是true的时候,才能去判断左上方方块是否满足条件,否则就存在穿墙现象。


比如下图的四种情况,红点想要移动到左上方的绿点,只有左边和上边(①)都可穿过的时候才能正常移动过去。像图②③④这三种情况如果直接移动,都存在穿墙的现象。



代码如下:只要替换掉四方向版本中的aroundFk就可以了。

/**
	 * 获取周围方块
	 * ①判断是否超越边界
	 * ②判断是否是障碍物/已计算过的方块
	 * @param fk	中心方块 
	 * @return	周围方块结集合
	 */
	public List<FangKuaiPosition> aroundFk(FangKuaiPosition fk){
		//重置
		top = false;
		down = false;
		left = false;
		right = false;
		List<FangKuaiPosition> list = new ArrayList<FangKuaiPosition>();
		//判断上面的方块是否符合条件
		//判断是否超过越边界
		if(fk.getY() - 1 >= 0){
			FangKuaiPosition tmpFk = new FangKuaiPosition(fk.getX(), fk.getY() - 1, fk);
			//判断是否是障碍物/已计算过的方块
			if(!BasePanel.zhangaiList.contains(tmpFk) 
					&& !BasePanel.closedList.contains(tmpFk)){
				list.add(tmpFk);
				top = true;//上方方块符合条件
			}
		}
		
		//判断下面的方块是否符合条件
		if(fk.getY() + 1 < BasePanel.heightLength){
			FangKuaiPosition tmpFk = new FangKuaiPosition(fk.getX(), fk.getY() + 1, fk);
			if(!BasePanel.zhangaiList.contains(tmpFk) 
					&& !BasePanel.closedList.contains(tmpFk)){
				list.add(tmpFk);
				down = true;//下方方块符合条件
			}
		}
		
		//判断左面的方块是否符合条件
		if(fk.getX() - 1 >= 0){
			FangKuaiPosition tmpFk = new FangKuaiPosition(fk.getX() - 1, fk.getY(), fk);
			if(!BasePanel.zhangaiList.contains(tmpFk) 
					&& !BasePanel.closedList.contains(tmpFk)){
				list.add(tmpFk);
				left = true;//左方方块符合条件
			}
		}
		//判断右面的方块是否符合条件
		if(fk.getX() + 1 < BasePanel.widthLength){
			FangKuaiPosition tmpFk = new FangKuaiPosition(fk.getX() + 1, fk.getY(), fk);
			if(!BasePanel.zhangaiList.contains(tmpFk) 
					&& !BasePanel.closedList.contains(tmpFk)){
				list.add(tmpFk);
				right = true;//右方方块符合条件
			}
		}
		
		//左上方方块校验(左移一格不超过边界&&上移一格不超过边界&&左边方块符合条件&&上边方块符合条件,下面的类似原理)
		if(fk.getX() - 1 >= 0 && fk.getY() - 1 >= 0 && left && top){
			FangKuaiPosition tmpFk = new FangKuaiPosition(fk.getX() - 1, fk.getY() - 1, fk);
			//判断是否是障碍物/已计算过的方块
			if(!BasePanel.zhangaiList.contains(tmpFk) 
					&& !BasePanel.closedList.contains(tmpFk)){
				list.add(tmpFk);
			}
		}
		
		//右上方方块校验
		if(fk.getX() + 1 < BasePanel.widthLength && fk.getY() - 1 >= 0 && right && top){
			FangKuaiPosition tmpFk = new FangKuaiPosition(fk.getX() + 1, fk.getY() - 1, fk);
			//判断是否是障碍物/已计算过的方块
			if(!BasePanel.zhangaiList.contains(tmpFk) 
					&& !BasePanel.closedList.contains(tmpFk)){
				list.add(tmpFk);
			}
		}
		
		//右下方方块校验
		if(fk.getX() + 1 < BasePanel.widthLength && fk.getY() + 1 < BasePanel.heightLength && right && down){
			FangKuaiPosition tmpFk = new FangKuaiPosition(fk.getX() + 1, fk.getY() + 1, fk);
			//判断是否是障碍物/已计算过的方块
			if(!BasePanel.zhangaiList.contains(tmpFk) 
					&& !BasePanel.closedList.contains(tmpFk)){
				list.add(tmpFk);
			}
		}
		
		//左下方方块校验
		if(fk.getX() - 1 >= 0 && fk.getY() + 1 < BasePanel.heightLength && left && down){
			FangKuaiPosition tmpFk = new FangKuaiPosition(fk.getX() + 1, fk.getY() + 1, fk);
			//判断是否是障碍物/已计算过的方块
			if(!BasePanel.zhangaiList.contains(tmpFk) 
					&& !BasePanel.closedList.contains(tmpFk)){
				list.add(tmpFk);
			}
		}
		//将中心方块添加到已处理过的集合中
		BasePanel.closedList.add(fk);
		getFGH(list,fk);
		return list;
	}

二、移动

在basepanel.java中的movePanel方法里面,四方向的版本只做了上下左右四个方向的移动判断,所以这里需要将左上、右上、右下、左下的移动判断添加进来。同样,也是替换掉四方向版本中的这个movePanel方法就可以了。


/**
	 * 方块移动
	 * @param wayList	移动路线
	 * @throws InterruptedException
	 */
	public void movePanel(List<FangKuaiPosition> wayList) throws InterruptedException{
		
		if(wayList == null || wayList.size() == 0){
			System.out.println("无法 到达终点 !");
			return;
		}
		
		for(int i = wayList.size() - 2; i >= 0; i--){
			FangKuaiPosition fk = wayList.get(i);
			
			//向左上移动
			while(cat.getY() > fk.getY() * MyPanel.size && cat.getX() > fk.getX() * MyPanel.size){
				cat.setBounds(cat.getX() - 2, cat.getY() - 2, MyPanel.size, MyPanel.size);
				Thread.sleep(sleepTime);
			}
			
			//向右上移动
			while(cat.getY() > fk.getY() * MyPanel.size && cat.getX() < fk.getX() * MyPanel.size){
				cat.setBounds(cat.getX() + 2, cat.getY() - 2, MyPanel.size, MyPanel.size);
				Thread.sleep(sleepTime);
			}
			
			//向右下移动
			while(cat.getY() < fk.getY() * MyPanel.size && cat.getX() < fk.getX() * MyPanel.size){
				cat.setBounds(cat.getX() + 2, cat.getY() + 2, MyPanel.size, MyPanel.size);
				Thread.sleep(sleepTime);
			}
			
			//向左下移动
			while(cat.getY() < fk.getY() * MyPanel.size && cat.getX() > fk.getX() * MyPanel.size){
				cat.setBounds(cat.getX() - 2, cat.getY() + 2, MyPanel.size, MyPanel.size);
				Thread.sleep(sleepTime);
			}
			
			//向上
			while(cat.getY() > fk.getY() * MyPanel.size && cat.getX() == fk.getX() * MyPanel.size){
				cat.setBounds(cat.getX(), cat.getY() - 2, MyPanel.size, MyPanel.size);
				Thread.sleep(sleepTime);
			}
			
			//向下
			while(cat.getY() < fk.getY() * MyPanel.size && cat.getX() == fk.getX() * MyPanel.size){
				cat.setBounds(cat.getX(), cat.getY() + 2, MyPanel.size, MyPanel.size);
				Thread.sleep(sleepTime);
			}
			
			//向左
			while(cat.getX() > fk.getX() * MyPanel.size && cat.getY() == fk.getY() * MyPanel.size){
				cat.setBounds(cat.getX() - 2, cat.getY(), MyPanel.size, MyPanel.size);
				Thread.sleep(sleepTime);
			}
			
			//向右
			while(cat.getX() < fk.getX() * MyPanel.size && cat.getY() == fk.getY() * MyPanel.size){
				cat.setBounds(cat.getX() + 2, cat.getY(), MyPanel.size, MyPanel.size);
				Thread.sleep(sleepTime);
			}
			
		}
		System.out.println("寻路结束!");
	}


好了,给大家展示一下结果:


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

A*自动寻路算法—java版(八方向版) 的相关文章

随机推荐

  • ue中的经纬高转xyz的问题

    在ue中 做了个地球仪 发现经纬度转地心坐标系老是出问题 后来发现 是转ue时 x y坐标要互换 也对 因为在cesium for unreal中还有一系列ecef转ue的相关函数 即下面的代码中 xy需要互换 在ue中才能正常使用 偏心率
  • 【图解网络协议】面试官:三次握手都不会,回去等通知吧

    文章目录 一 网络基础知识准备 1 OSI七层网络模型总结 2 TCP IP协议总结 3 TCP协议流程 4 UDP协议 5 什么是socket 二 http协议 1 什么是http协议 2 http 1 0 与 http 1 1的区别 3
  • 香农公式简介

    信道容量 指信道中信息无差错传输的最大速率 信道模型中定义了两种广义信道 调制信道和编码信道 调制信道是一种连续信道 可以用连续信道的信道容量来表征 编码信道是一种离散信道 可以用离散信道的信道容量来表征 香农公式 设信道带宽为B 单位为H
  • 五种IO模型(详解+形象例子说明)

    在网络环境下 通俗的讲 将IO分为两步 1 等 2 数据搬迁 如果要想提高IO效率 需要将等的时间降低 五种IO模型包括 阻塞IO 非阻塞IO 信号驱动IO IO多路转接 异步IO 其中 前四个被称为同步IO 在介绍五种IO模型时 我会举生
  • 给一个正整数n,求出位数。并按正序输出,逆序输出

    求出位数 思路 通过让给定的正整数n整除10 且每整除一次让统计位数的变量count自增一 返回count得到位数 include
  • 华硕主板固态硬盘不识别_[主板] 开机后无法识别硬盘或SSD的故障排除方式

    1 尝试更新官网最新的BIOS版本 可参考FAQ 华硕EZ Flash 3 介绍 2 在计算机开机后 立刻按压键盘上的 delete 键 在BIOS EZ Mode 页面的 Storage Information 字段 确认是否可以显示所接
  • 使用EasyExcel生成表格并且返回File对象

    通过此方法 可以导出表格并且存入File对象中进行其他的操作 这里通过File来进行异步存储到文件服务器 用于下载中心 public static
  • myeclipse10配置tomcat详细过程

    首先确保你已经成功的安装 了myeclipse10和tomcat 我用的是tomcat6 1 在myeclipse10中添加tomcat 选择属性preferences之后进入配置框 选择servers下的tomcat6 视你自己的版本而定
  • 【翻译】软件表现不佳,未来取决于这种情况的改变

    如果一件事不能永远进行下去 它就不会 赫伯 斯坦法则 科技行业的未来会是什么样子 从现在到2030年 我们所有人面临的挑战不再是我们将如何说服世界 或更直接地说 我们的老板或客户 成为碳零 无论我们是否愿意 这都会到来 我们的新问题是 作为
  • 如何阅读他人的项目源代码程序

    阅读他人的项目源代码步骤 备份并编译运行代码 熟悉项目编程语言的语法和惯例用语 看项目文档 有机会可向项目开发人员请教 自上而下构建项目程序的系统架构 建立系统架构和功能逻辑之间的关联 核心代码重点剖析与注释 调整心态 反复阅读 工欲善其事
  • Vue3只读代理---readonly、isReadonly、shallowReadonly

    readonly 获取一个对象 响应式或纯对象 或 ref 并返回原始代理的只读代理 不能给属性重新赋值 只读代理是递归的 访问的任何嵌套 property 也是只读的
  • springmvc源码学习(二十四)异步请求管理器WebAsyncManager初始化

    目录 前言 一 WebAsyncManager初始化 二 参数的初始化 三 自定义参数 总结 前言 Springmvc的异步执行请求是有异步管理器WebAsyncManager来控制的 一 WebAsyncManager初始化 1 在请求到
  • 大数据--Hadoop环境部署(4)Hadoop集群部署

    Hadoop集群的部署方式分为三种 分别是独立模式 Standalone mode 伪分布式模式 Pseudo Distributed mode 和完全分布式模式 Cluster mode 独立模式和伪分布式模式主要用于学习和调试 完全分布
  • 数据圈最全的数据分析&产品文章合集

    关注公众号 回复 进群 与3万 数据人交流 公众号介绍 一个数据人的自留地 成立于2020年2月25日 目前发表原创300 篇 拥有3万 粉丝 交流群10 个 连载数据产品 数据分析 画像标签 策略算法 运营增长 求职面试等20多个方向的文
  • Spring Boot Kafka - 序列化和反序列化JSON

    文章目录 Spring Boot Kafka 序列化和反序列化JSON 前言 配置JsonSerializer和JsonDeserializer 定义一个Model类 Producer类 Consumer类 Controller类 测试 小
  • EMNLP 2020 Beyond Instructional Videos: Probing for More Diverse Visual-Textual Grounding on YouTube

    动机 从无标签的网络视频中进行预训练已经迅速成为在许多视频待处理任务中实际获得高性能的的手段 通过预测语音内容和自动语音识别 ASR token之间的grounded关系来学习特征 然而 先前的训练前工作仅限于教学录像 作者希望这个领域是相
  • 1.uniapp全局状态管理

    概念 把多个组件之间共享数据抽离出来 通过一个 单例模式 进行管理 工具 具备全局状态管理的库 Vuex 全局状态管理中的库 步骤 1 建立Store文件夹 2 建立index js文件 3 在main js中注册Vue插件 4 测试Vue
  • POI实现word转HTML!呵呵!!!

    那些说POI把word转HTML如何如何完美的人们 copy东copy西 有想过转出来的格式与word不一致么 唉
  • 动态规划法--求数组中最大子集合的和

    例题 给定一个数组int a 9 1 3 5 1 7 5 3 1 计算数组中连续的最大和以及出现的位置 输出 下标1到5位连续的最大和为15 首先看到这种题目 我的第一反应 就是用冒泡排序的思想去做 public class zuoye p
  • A*自动寻路算法—java版(八方向版)

    上一篇博客分享了Java版的自动寻路 但是只是上下左右四个方向的 今天把八方向的也分享出来 既然四方向的已经成功了 那么改进成八方向的 只要注意两个地方就可以了 一个是获取四周方块的时候 一个是移动的时候 一 获取四周方块 在autofin