lua 寻路

  -- @file PathFindHelper.lua
  --
  -- 使用 AStart 寻路算法实现
  -- 寻路算法助手
  -------------------------------------------------------------------------------
   
  PathFindHelper = PathFindHelper or class("PathFindHelper", EventDispatcher)
   
  local MOVE_DIR = {
  LEFT = 1,
  RIGHT = 2,
  TOP = 3,
  BOTTOM = 4,
   
  LEFT_TOP = 5,
  LEFT_BOTTOM = 6,
  RIGHT_TOP = 7,
  RIGHT_BOTTOM = 8,
  }
   
  local MOVE_OFFSET = {
  [MOVE_DIR.LEFT] = {{-1, 0}, 10},
  [MOVE_DIR.RIGHT] = {{ 1, 0}, 10},
  [MOVE_DIR.TOP] = {{ 0, 1}, 10},
  [MOVE_DIR.BOTTOM] = {{ 0,-1}, 10},
  [MOVE_DIR.LEFT_TOP] = {{-1, 1}, 14},
  [MOVE_DIR.LEFT_BOTTOM] = {{-1,-1}, 14},
  [MOVE_DIR.RIGHT_TOP] = {{ 1, 1}, 14},
  [MOVE_DIR.RIGHT_BOTTOM] = {{ 1,-1}, 14},
  }
   
  function PathFindHelper:ctor(map_data, width, height, check_block_func)
  self._map_data = map_data
  self._map_width = width
  self._map_height = height
  self._check_block_func = check_block_func
   
  self:init()
  end
   
  function PathFindHelper:get_point_index( point )
  return (point.x + point.y*self._map_width + 1)
  end
   
  --检查点是否是阻塞不可走的
  function PathFindHelper:check_point_is_block( point )
  if point.x < 0 or point.x >= self._map_width or point.y < 0 or point.y >= self._map_height then
  return true
  end
   
  local index = self:get_point_index(point)
  if self._check_block_func and type(self._check_block_func) == "function" then
  return self._check_block_func(self._map_data[index])
  else
  return self._map_data[index] ~= 0
  end
  end
   
  function PathFindHelper:get_h_value(p1, p2)
  return (math.abs(p1.x - p2.x) + math.abs(p1.y - p2.y))*10
  end
   
  function PathFindHelper:find_path( start_point, end_point, only_cross)
  local only_cross = only_cross or false
  local can_move_dirs = {MOVE_DIR.TOP, MOVE_DIR.BOTTOM, MOVE_DIR.LEFT, MOVE_DIR.RIGHT}
  if not only_cross then
  table.insert(can_move_dirs, MOVE_DIR.LEFT_TOP)
  table.insert(can_move_dirs, MOVE_DIR.LEFT_BOTTOM)
  table.insert(can_move_dirs, MOVE_DIR.RIGHT_TOP)
  table.insert(can_move_dirs, MOVE_DIR.RIGHT_BOTTOM)
  end
   
  local end_index = self:get_point_index(end_point)
   
  open_list = {}
  open_check_index = {}
  local item_value = { point = start_point, g_cost = 0, h_cost = self:get_h_value(start_point, end_point), parent = nil}
  table.insert(open_list, item_value )
  local open_index = self:get_point_index(start_point)
  open_check_index[open_index] = item_value
   
  local function open_cmp(a, b)
  local f_a = a.g_cost + a.h_cost
  local f_b = b.g_cost + b.h_cost
   
  return f_a > f_b
  end
   
  local close_list = {}
  local end_point_item = nil
  while 1 do
  table.sort(open_list, open_cmp)
  local open_item = table.remove(open_list)
  if not open_item then
  break
  end
  local cur_point = open_item.point
  local cur_index = self:get_point_index( cur_point )
  local cur_g_cost = open_item.g_cost
  local cur_h_cost = open_item.h_cost
   
  close_list[cur_index] = true --标记当前点为检查过的点
   
  for _, dir in pairs(can_move_dirs) do
  local offset = MOVE_OFFSET[dir]
  local move_offset = offset[1]
  local move_g_cost = offset[2]
   
  local dest_point = cc.p(cur_point.x + move_offset[1], cur_point.y + move_offset[2])
  if dest_point.x >= 0 and dest_point.x < self._map_width and dest_point.y >= 0 and dest_point.y < self._map_height then
  --print("### x: ", dest_point.x, " ### y: ", dest_point.y)
  local dest_index = self:get_point_index( dest_point )
  local dest_h_cost = self:get_h_value(dest_point, end_point)
  local dest_g_cost = move_g_cost + cur_g_cost
   
  --如果已经在检查过的点中,或不可行走的点
  if close_list[dest_index] or self:check_point_is_block(dest_point) then
  if not close_list[dest_index] then
  --print(dest_point.x, dest_point.y, "is blocked", self._map_data[dest_index])
  end
  --直接跳过
  else
  --如果此点已经在开启列表中
  local open_record = open_check_index[dest_index]
  if open_record then
  local recore_f = open_record.g_cost + open_record.h_cost
  local dest_f = dest_g_cost + dest_h_cost
   
  if dest_f < recore_f then
  open_record.parent = open_item
  end
  else
  local item_value = { point = dest_point, g_cost = dest_g_cost, h_cost = dest_h_cost, parent = open_item}
  table.insert(open_list, item_value)
  open_check_index[dest_index] = item_value
  end
  end
  end
  end
   
  if open_check_index[end_index] then
  end_point_item = open_check_index[end_index]
  break
  end
  end
   
  if not end_point_item then return nil end
   
  local path = {}
  table.insert(path, 1, end_point_item.point)
   
  local loop = end_point_item.parent
  while loop do
  table.insert(path, 1, loop.point)
  loop = loop.parent
  end
  return path
  end
   
   
  function PathFindHelper:init()
   
  end
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值