A星寻路 lua

[复制链接]
查看19532 | 回复56 | 2021-8-18 17:33:22 | 显示全部楼层 |阅读模式
  1. local _map_data         -- 地图数据
  2. local _open_list        -- 开放节点
  3. local _open_map         -- 开放节点,为了提高性能而加
  4. local _close_map        -- 关闭节点
  5. local _deleget          -- 代理
  6. local _dest_point       -- 目标点
  7. local _start_point      -- 起点
  8. local _path             -- 路径

  9. -- 寻找路径
  10. --[[
  11. deleget = {
  12.     g = function(point1, point2)
  13.         -- add your code
  14.         -- 返回点point1到点point2的实际代价
  15.     end
  16.     h = function(point1, point2)
  17.         -- add your code
  18.         -- 返回点point1到点point2的估算代价
  19.     end
  20.     getValue = function(j, i)
  21.         -- 返回地图中第i行,第j列的数据 1为障碍物,0为非障碍物
  22.     end
  23.     width -- 地图宽度
  24.     height -- 地图高度
  25. }
  26. --]]
  27. function findPath(deleget, start_point, dest_point)
  28.     _deleget = deleget
  29.     _dest_point = dest_point
  30.     _start_point = start_point
  31.     init()
  32.     while _open_list ~= nil do
  33.         local cur_point = _open_list[1]
  34.         table.remove(_open_list, 1)
  35.         if cur_point==nil then
  36.             return nil
  37.         end
  38.         _open_map[cur_point.key] = nil
  39.         if isEqual(cur_point, dest_point) then
  40.             return makePath(cur_point)
  41.         else
  42.             _close_map[cur_point.key] = cur_point
  43.             local next_points = getNextPoints(cur_point)
  44.             for i = 1, #next_points do
  45.                 local next_point = next_points[i]
  46.                 if _open_map[next_point.key] == nil and _close_map[next_point.key] == nil and isObstacle(next_point) == false then
  47.                     _open_map[next_point.key] = next_point
  48.                     table.insert(_open_list, next_point)
  49.                 end
  50.             end
  51.             table.sort(_open_list, compareF)
  52.         end
  53.     end
  54.     return nil
  55. end

  56. function init()
  57.     _open_list = {}
  58.     _open_map = {}
  59.     _close_map = {}
  60.     _path = {}
  61.     _map_data = {}

  62.     for i = 1, _deleget.height do
  63.         _map_data[i] = {}
  64.         for j = 1, _deleget.width do
  65.             local value = _deleget.getValue(j, i)
  66.             _map_data[i][j] = value
  67.         end
  68.     end
  69.     _open_map[getKey(_start_point)] = _start_point
  70.     table.insert(_open_list, _start_point)
  71. end

  72. function createPoint(x, y)
  73.     local point = {
  74.         ["x"] = x,
  75.         ["y"] = y,
  76.         ["last"] = nil,
  77.         ["g_value"] = 0,
  78.         ["h_value"] = 0,
  79.         ["f_value"] = 0
  80.     }
  81.     point["key"] = getKey(point)
  82.     return point
  83. end

  84. -- 得到下一个可以移动的点
  85. -- @param point 当前所在点
  86. function getNextPoints(point)
  87.     local next_points = {}
  88.     for i = 1, #_deleget.directions do
  89.         local offset = _deleget.directions[i]
  90.         local next_point = createPoint(point.x + offset[1], point.y + offset[2])
  91.         next_point["last"] = point
  92.         if next_point.x >= 1 and next_point.x <= _deleget.width and next_point.y >= 1 and next_point.y <= _deleget.height then
  93.             next_point["g_value"] = _deleget.g(point, next_point)
  94.             next_point["h_value"] = _deleget.h(point, _dest_point)--math.abs(next_points.x - _dest_point.x) + math.abs(next_points.y - _dest_point.y)
  95.             next_point["f_value"] = next_point.g_value + next_point.h_value
  96.             table.insert(next_points, next_point)
  97.         end
  98.     end
  99.     return next_points
  100. end

  101. -- 得到路径
  102. -- @param end_point 目标点
  103. function makePath(end_point)
  104.     _path = {}
  105.     local point = end_point
  106.     while point.last ~= nil do
  107.         table.insert(_path, createPoint(point.x, point.y))
  108.         point = point.last
  109.     end
  110.     local start_point = point
  111.     table.insert(_path, start_point)
  112.     return _path
  113. end

  114. -- 两个点的代价比较器
  115. function compareF(point1, point2)
  116.     return point1.f_value < point2.f_value
  117. end

  118. -- 是否是障碍物
  119. function isObstacle(point)
  120.     local value = _map_data[point.y][point.x]
  121.     if value == 1 then
  122.         return true
  123.     end
  124.     return false
  125. end

  126. -- 两个点是否是同一个点
  127. function isEqual(point1, point2)
  128.     return point1.key == point2.key
  129. end

  130. -- 根据点得到点的key
  131. function getKey(point)
  132.     local key =  strformat("%d,%d", point.x, point.y)
  133.     return key
  134. end
复制代码


回复

使用道具 举报

尘络 | 2021-8-18 18:01:57 | 显示全部楼层
顶顶顶顶顶顶顶顶
回复

使用道具 举报

youmu | 2021-8-18 19:47:19 | 显示全部楼层
好的完全不懂
回复

使用道具 举报

Aitlo | 2021-8-18 19:56:31 | 显示全部楼层
好家伙~属于那种类型有些的自动寻路?
回复

使用道具 举报

qq99989680 | 2021-8-18 21:04:05 | 显示全部楼层
可否录个视频来个游戏实测?
回复

使用道具 举报

龙睛鱼 | 2021-8-19 08:30:52 | 显示全部楼层
回复

使用道具 举报

fojiao1992 | 2021-8-19 15:37:41 | 显示全部楼层
好的完全不懂
回复

使用道具 举报

风雷 | 2021-8-19 16:27:55 | 显示全部楼层
qq99989680 发表于 2021-8-18 21:04
可否录个视频来个游戏实测?

有时间录个吧,这是我以前写寻路的源码.
回复

使用道具 举报

junling888 | 2021-8-19 22:41:01 | 显示全部楼层
大佬牛逼,学习一波,一步步拆解学习,师傅
回复

使用道具 举报

xywl | 2021-8-20 12:59:33 | 显示全部楼层
完全不懂前排支持出视频
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则