JS/HTML5游戏常用算法之路径搜索算法 A*寻路算法完整实例

非常感谢你对于本站文章的关注。下面是针对文章“JS/HTML5游戏常用算法之路径搜索算法 A*寻路算法完整实例”的完整攻略解析。

1. 介绍

本文主要讲解的是一种常用于解决路径搜索问题的算法—— A*寻路算法。使用该算法可以在搜索空间(如地图、游戏场景等)中找到一条最优路径,可应用于许多领域,如自动驾驶、游戏AI等。

2. 算法流程

该算法通过在搜索空间中创建一个节点集来实现。

  • 先将起点加入节点集。
  • 从节点集中选取离起点最近的节点,计算其相邻节点的路径距离,如果路径距离加上该节点到起点的距离小于该相邻节点到起点的距离,那么更新该相邻节点到起点的距离,并将该节点加入节点集。
  • 重复步骤2,直到到达终点或搜索完所有节点。

3. 代码实现

该算法实现中,需定义地图和节点对象。

//定义地图对象
var map = {
    width: 10,
    height: 10,
    obstacles: [{x:3,y:3},{x:4,y:3},{x:5,y:3},{x:4,y:4}]
};

//定义节点对象
function node(x, y, endX, endY) {
    this.x = x; //节点横坐标
    this.y = y; //节点纵坐标
    this.g = 0; //起点到当前节点的距离
    this.h = Math.abs(endX - x) + Math.abs(endY - y); //当前节点到终点的估算距离
    this.f = this.g + this.h; //节点综合评价函数
    this.parent = null; //当前节点的父节点
}

以上实现是一个简单示例,地图的width和height分别为地图的宽度和高度,obstacles表示地图上的障碍物,使用数组形式存储,每个障碍物包含x和y属性表示该障碍物在地图上的位置信息。节点对象包括x、y、g、h、f和parent属性。其中g表示起点到当前节点的距离,h表示当前节点到终点的估算距离,f表示g和h的综合评价函数,parent表示当前节点的父节点。

在实现中需要定义开始节点和结束节点,调用寻路函数进行搜索。

//开始节点
var start = new node(0, 0, 9, 9);

//结束节点
var end = new node(9, 9, 9, 9);

//寻路函数
function findPath(start, end) {
    var openList = [start]; //节点集合(初始状态只包含起点)
    var closedList = []; //已处理节点集合

    while (openList.length > 0) {
        //找到f值最小的节点
        var node = openList[0];
        for (var i = 1; i < openList.length; i++) {
            if (openList[i].f < node.f) {
                node = openList[i];
            }
        }

        //将该节点从节点集中删除并加入已处理集合
        openList.splice(openList.indexOf(node), 1);
        closedList.push(node);

        //如果该节点为终点
        if (node.x === end.x && node.y === end.y) {
            var path = [];
            while (node.parent) {
                path.push(node);
                node = node.parent;
            }
            return path.reverse();
        }

        //找到该节点相邻的节点,并计算路径距离
        var neighbors = getNeighbors(node, end);
        for (var j = 0; j < neighbors.length; j++) {
            var neighbor = neighbors[j];

            //如果该节点已在已处理集合中则跳过
            if (closedList.indexOf(neighbor) > -1) {
                continue;
            }

            //计算路径距离
            var g = node.g + (neighbor.x === node.x || neighbor.y === node.y ? 10 : 14);

            //如果路径距离加上该节点到终点的距离小于该相邻节点到起点的距离,则更新节点并加入节点集中
            if (g + neighbor.h < neighbor.f) {
                neighbor.g = g;
                neighbor.f = neighbor.g + neighbor.h;
                neighbor.parent = node;
                if (openList.indexOf(neighbor) === -1) {
                    openList.push(neighbor);
                }
            }
        }
    }

    //如果没有找到路径
    return null;
}

//计算当前节点相邻的节点
function getNeighbors(node, end) {
    var neighbors = [];
    var x = node.x,
        y = node.y;

    //左
    if (x > 0 && !(map.obstacles.filter(function(item){return item.x===x-1 && item.y===y}).length>0)){
        neighbors.push(new node(x - 1, y, end.x, end.y));
    }

    //右
    if (x < map.width - 1 && !(map.obstacles.filter(function(item){return item.x===x+1 && item.y===y}).length>0)){
        neighbors.push(new node(x + 1, y, end.x, end.y));
    }

    //上
    if (y > 0 && !(map.obstacles.filter(function(item){return item.x===x && item.y===y-1}).length>0)){
        neighbors.push(new node(x, y - 1, end.x, end.y));
    }

    //下
    if (y < map.height - 1 && !(map.obstacles.filter(function(item){return item.x===x && item.y===y+1}).length>0)){
        neighbors.push(new node(x, y + 1, end.x, end.y));
    }

    //左上
    if (x > 0 && y > 0 && !(map.obstacles.filter(function(item){return item.x===x-1 && item.y===y-1}).length>0)){
        neighbors.push(new node(x - 1, y - 1, end.x, end.y));
    }

    //右上
    if (x < map.width - 1 && y > 0 && !(map.obstacles.filter(function(item){return item.x===x+1 && item.y===y-1}).length>0)){
        neighbors.push(new node(x + 1, y - 1, end.x, end.y));
    }

    //左下
    if (x > 0 && y < map.height - 1 && !(map.obstacles.filter(function(item){return item.x===x-1 && item.y===y+1}).length>0)){
        neighbors.push(new node(x - 1, y + 1, end.x, end.y));
    }

    //右下
    if (x < map.width - 1 && y < map.height - 1 && !(map.obstacles.filter(function(item){return item.x===x+1 && item.y===y+1}).length>0)){
        neighbors.push(new node(x + 1, y + 1, end.x, end.y));
    }

    return neighbors;
}

4. 示例说明

以下是一个示例,以10*10的地图为例,地图中有四个障碍物,起点为左上角,终点为右下角。

0   1   2   3   4   5   6   7   8   9   
1   .   .   .   .   .   .   .   .   .   |   0
2   .   .   .   #   #   #   .   .   .   |   1
3   .   .   .   .   .   .   .   .   .   |   2
4   .   .   .   .   .   .   .   .   .   |   3
5   .   .   .   .   .   .   .   .   .   |   4
6   .   .   .   .   .   .   .   .   .   |   5
7   .   .   .   .   .   .   .   .   .   |   6
8   .   .   .   .   .   .   .   .   .   |   7
9   .   .   .   .   .   .   .   .   .   |   8
                             |  9
      0 1   2   3   4   5   6   7   8   9   

假设障碍物的坐标为对应位置的左上角坐标。

根据以上示例,在调用寻路函数后,实现的输出结果为:

[
    node {x: 9, y: 9, g: 40, h: 0, f: 40, parent: node{x:8,y:8,...}},
    node {x: 8, y: 8, g: 33, h: 2, f: 35, parent: node{x:7,y:7,...}},
    node {x: 7, y: 7, g: 26, h: 4, f: 30, parent: node{x:6,y:6,...}},
    ...
    node {x: 1, y: 1, g: 10, h: 10, f: 20, parent: node{x:0,y:0,...}},
    node {x: 0, y: 0, g: 0, h: 18, f: 18, parent: null}
]

输出结果包含了所有寻找到最短路径的节点。可以从后往前找到起点和终点间所需的节点数,实现路径的绘制。

5. 总结

以上就是本文对 A*寻路算法的完整分析及实现。希望通过阅读本文,读者可以完全了解本算法的实现过程和应用场景。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JS/HTML5游戏常用算法之路径搜索算法 A*寻路算法完整实例 - Python技术站

(0)
上一篇 2023年5月19日
下一篇 2023年5月19日

相关文章

  • Go语言实现常用排序算法的示例代码

    本文将详细介绍如何使用Go语言实现常用排序算法的示例代码。主要内容包括: 排序算法介绍 排序算法示例代码 算法测试 排序算法介绍 排序算法是计算机科学基本的算法,其目的是将一组数据按照特定的规则进行排序。常用的排序算法包括冒泡排序、选择排序、插入排序、归并排序和快速排序等。以下是每种算法的简单介绍: 冒泡排序:重复比较相邻的两个元素,将较大的元素向后移动,最…

    算法与数据结构 2023年5月19日
    00
  • C#常见算法面试题小结

    C#常见算法面试题小结 常见算法 本文主要讲解C#常见算法,在面试或实际工作中应用较为广泛。以下是本文讨论的常见算法: 排序算法 查找算法 贪心算法 动态规划算法 字符串算法 排序算法 冒泡排序 冒泡排序是一种效率低下的排序,但是学习它有助于了解其他的排序算法。 冒泡排序的核心思想是重复地走访过要排序的序列,每次比较相邻的两个元素,如果他们的顺序错误就把他们…

    算法与数据结构 2023年5月19日
    00
  • asp下几种常用排序算法

    我将为您详细讲解ASP下几种常用排序算法的完整攻略。 一、排序算法简介 排序算法是计算机科学中非常基础的算法之一。它是将一组数据中的元素按照某种规则进行排序的过程。排序算法是计算机程序设计的基础,它涉及到数据结构、算法、模式识别等计算机科学领域内的基础理论。 排序算法主要分为以下几种: 冒泡排序 选择排序 插入排序 快速排序 归并排序 本文将针对ASP下几种…

    算法与数据结构 2023年5月19日
    00
  • C语言库函数qsort及bsearch快速排序算法使用解析

    这里是关于C语言库函数qsort及bsearch快速排序算法使用的详细攻略。 qsort排序函数 1. 定义 qsort是C语言标准库中快速排序算法的一个实现函数。它用于对一个数组中的元素进行排序。qsort函数的定义如下: void qsort(void* base, size_t nitems, size_t size, int (*compar)(co…

    算法与数据结构 2023年5月19日
    00
  • C语言冒泡排序法的实现(升序排序法)

    冒泡排序是一种简单的排序算法。它会依次比较相邻两个元素,如果它们的顺序错误就交换它们的位置,直到所有元素都排列成功。 以下是C语言冒泡排序的实现过程: 1.先定义数组 代码示例: int a[10] = {23, 56, 12, 45, 9, 17, 98, 67, 41, 3}; 2.开始排序 首先,我们需要使用两层循环来遍历每一个元素。 外层循环从第一个…

    算法与数据结构 2023年5月19日
    00
  • 几种经典排序算法的JS实现方法

    一、冒泡排序 原理 冒泡排序将待排序元素两两比较,根据比较结果交换位置,一遍冒泡会让至少一个元素到达最终位置。重复这个过程,直到排序完成。 JS实现 function bubbleSort(arr) { const len = arr.length; for (let i = 0; i < len; i++) { for (let j = 0; j &…

    算法与数据结构 2023年5月19日
    00
  • java如何给对象按照字符串属性进行排序

    在 Java 中,我们可以使用 Collections.sort() 方法对任意类型的对象进行排序。但是,如果我们想要按照对象的某一个字符串属性进行排序,我们可以使用 Comparator 接口来实现。 具体步骤如下: 首先,创建一个 Comparator 对象,重写 compare() 方法,按照需要的属性进行排序。例如,如果我们要按照对象的 name 属…

    算法与数据结构 2023年5月19日
    00
  • Python实现的最近最少使用算法

    Python实现最近最少使用算法 最近最少使用算法(Least Recently Used,LRU)是一种缓存淘汰策略,用于在缓存已满时选择要被淘汰的缓存块。该算法的基本思想是,当缓存已满时,淘汰最近最少使用的缓存块。 下面我们将通过python代码实现LRU算法的主要思想,并提供两个示例说明。 算法思路 LRU算法需要同时维护两个数据结构。 记录最近访问顺…

    算法与数据结构 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部