[Bukkit插件开发教程] [高质量插件系列] [算法] - A*寻路算法在三维MC中的实际应用

注意:本文适合 有JavaSE基础 勇于尝试 有耐性的读者食用
(正所谓算法开发 学到头了 也就到头了orz)

本文中二维A*思想部分来自于 A* Pathfinding for Beginners - Artificial Intelligence - Tutorials - GameDev.net

在开始之前:

本文不会完全将最终代码贴出,仅取部分作为参考。您的代码理应源于您自己,我们不是为了开发而开发!
撰写本文的想法起始于本人最近进行的一款寻路插件的开发,在研究现有寻路算法时发现了最具优越性的A*寻路算法,但是网络上几乎无法找到三维空间下的A*,即便有也未有详细思路或查询代价过高(此点会在下文说明),故本人特意以MC特性为基础在二维A*的基础上进行改进,经过几天的调试与分析,最终得出本文中完全具备经典二维A*思想的三维A*算法。如若对本文内容持有异议或拥有更好的观点,欢迎各位进行留言!

初始化

我们先了解几个概念:
首先我们将要搜索的地图视作二维的 区分出来两类方块 地面 和 墙面
地面可以是草方块、原石等 可供玩家正常行走的方块
墙面可以是水、岩浆等可视为 无法行走,不进行查找的方块
那么在地面上我们就可以确定搜索的 起点 和 终点


在正式搜索之前 我们先定义一个内部类Node作为节点储存寻路过程中产生的每个结点的位置信息(Location)、父节点(Node)、G值(父节点移动到当前节点的成本)、H值(从当前节点移动到终点的估算成本)以及当前节点与终点的高度差(int)

  1. public static class Node {
  2.     private final Location location;
  3.     private int height = 0;
  4.     private Node parent = null;
  5.     private int G;
  6.     private int H;
  7.     public Node(Location location) {
  8.         this.location = location;
  9.     }


要注意的是虽然我们在寻路的过程中以Node的实例进行操作,但事实上对位置进行操作时我们仍是对Location进行操作。故为了方便储存与对节点进行操作,我们再定义一个名为NodeSet的类继承HashSet来储存节点与覆写contains、get与remove方法。并实例化一个openList与closeList便于节点的回溯与处理(见下文)

  1. private final NodeSet openList = new NodeSet(initialCapacity);
  2. private final NodeSet closeList = new NodeSet(initialCapacity);
  3. private static class NodeSet extends HashSet<Node> {
  4.         public NodeSet(int initCap) {
  5.             super(initCap);
  6.         }
  7.         public Node get(Location loc) {
  8.             Iterator<Node> iterator = super.iterator();
  9.             while (iterator.hasNext()) {
  10.                 Node node = iterator.next();
  11.                 if (node.location.equals(loc)) {
  12.                     return node;
  13.                 }
  14.             }
  15.             return null;
  16.         }
  17.         public boolean contains(Node node) {
  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值