游戏中有敌我双方,有四十个方格,当轮到我方武将行动的时候,要先显示出我方武将可以行动的方位,这个就涉及到我方武将的行动力的大小来决定,预先做出路径的预算。这里还要考虑敌方以及地标(例如:炸弹、势头)的阻挡,以及特殊方格对武将行动力的消耗以及敌方的间隔阻挡规则。
当碰到这个问题的时候,问老大选择用什么寻路算法,他推荐的是Dijstra算法,但我看了之后感觉还不是很适合我的需求,第一:我觉得Dijstra算法是有向图的最佳路径选择,节点之间路径长度必须先知晓,但我这里四十个方格如果要两两制定感觉稍微复杂,而且随着武将的移动,地图还是时时变化的,感觉更复杂。第二:Distra算法没有阻挡考虑,当然也可以记录若干路径然后考虑阻挡选择最优路径,我感觉也稍复杂。
然而我的第一反应该需求A*算法挺接近的,然后咨询老大,老大说A*方格之间距离必须要均等不然比较复杂。然后再咨询公司其他稍有经验同事,当然各有个的说法,什么深度、广度遍历,感觉没一个确定的说法。让我选择就纠结了一天,不敢轻易选择,如果稍有考虑不慎,说不定就要做几天白用工,但最后我还是坚持自己的想法用A*来实现。
5.如果某个相邻方格 D 已经在 "开启列表" 里了, 检查如果用新的路径 (就是经过C 的路径) 到达它的话, G值是否会更低一些, 如果新的G值更低, 那就把它的 "父方格" 改为目前选中的方格 C, 然后重新计算它的 F 值和 G 值 (H 值不需要重新计算, 因为对于每个方块, H 值是不变的). 如果新的 G 值比较高, 就说明经过 C 再到达 D 不是一个明智的选择, 因为它需要更远的路, 这时我们什么也不做
-
module('Maze', package.seeall)
-
require("script/battle/TabledArray")
-
require("script/battle/BattleCommon")
-
require ("script/battle/Point")
-
-
-- --获取列表中F值最小的点
-
function getMinPoint( pointsList )
-
local minPoint = pointsList.tbl[1]
-
for i = 1,pointsList:getSize() do
-
if minPoint.F > pointsList.tbl[i].F then
-
minPoint = pointsList.tbl[i]
-
end
-
end
-
return minPoint
-
end
-
-
-- --检测是否有阻挡,没有阻挡为true
-
function checkBlock( maze,x,y,roleFlag) --x范围[1,5] y范围[1,8]
-
if roleFlag == BattleCommon.BATTLE_GROUP_ALLIES then --我方阵营
-
if maze.mazeArray[x][y][1] == 0 or maze.mazeArray[x][y][1] == 1 then
-
return true --没有阻挡
-
else
-
return false
-
end
-
elseif roleFlag == BattleCommon.BATTLE_GROUP_ENEMY then
-
if maze.mazeArray[x][y][1] == 0 or maze.mazeArray[x][y][1] == 2 then
-
return true --没有阻挡
-
else
-
return false
-
end
-
end
-
end
-
-
-- --列表中是否包含x,y的点
-
function existsXY( list,x,y )
-
if list:getSize()>0 then
-
for i,point in pairs(list.tbl) do
-
if point.X == x and point.Y == y then
-
return true
-
end
-
end
-
end
-
return false
-
end
-
-
--列表中是否包含某个点
-
function existsPoint( list,point )
-
for i, p in pairs(list.tbl) do
-
if (p.X == point.X) and (p.Y == point.Y) then
-
return true
-
end
-
end
-
return false
-
end
-
-
-
-- --检测能达到的点
-
function canReach( maze,startPoint,x,y,roleFlag)
-
if (not checkBlock(maze,x,y,roleFlag)) or existsXY(maze.closeList,x,y) then --关闭列表中包含这个点或者有阻挡
-
return false
-
else
-
if (math.abs(x-startPoint.X)+math.abs(y-startPoint.Y) == 1 ) then
-
return true
-
end
-
end
-
end
-
-
-- --获取相邻的点
-
function getSurroundPoints( maze,point,roleFlag )
-
local surroundPoints = TabledArray.create()
-
for i = point.X - 1 ,point.X + 1 do
-
for j=point.Y - 1,point.Y + 1 do
-
if i>0 and i<6 and j > 0 and j < 9 then --排除超过表姐
-
if BattleCommon.distanceFromTo(point.posId,BattleCommon.convertToPositionId(j-1,i-1)) < 2 then
-
if canReach(maze,point,i,j,roleFlag) then
-
surroundPoints:append(maze.mazeArray[i][j][2])
-
end
-
end
-
end
-
end
-
end
-
return surroundPoints --返回point点的集合
-
end
-
-
-- --计算G值
-
function CalcG( point )
-
local G = point.G
-
local parentG = 0
-
if point.parentPoint then
-
parentG = point.parentPoint.G
-
end
-
return G + parentG
-
end
-
-
function foundPoint( tempStart,point )
-
local G = CalcG(point)
-
if G < point.G then
-
point.parentPoint = tempStart
-
point.G = G
-
point:CalcF()
-
end
-
end
-
-
-
function notFoundPoint( maze,tempStart,point )
-
point.parentPoint = tempStart
-
point.G = CalcG(point)
-
point:CalcF()
-
maze.openList:append(point)
-
end
-
-
function getPoint( list,data )
-
for i,point in pairs(list.tbl) do
-
if point.posId == data.posId then
-
return point
-
end
-
end
-
return nil
-
end
-
-
-- --寻找路径(起始路径)
-
local function findPath( maze,startPoint,endPoint,roleFlag)
-
maze.openList:append(startPoint)
-
while maze.openList:getSize() ~= 0 do
-
--找出F的最小值
-
local tempStart = getMinPoint(maze.openList)
-
maze.openList:removeById(1)
-
maze.closeList:append(tempStart)
-
--找出它相邻的点
-
local surroundPoints = getSurroundPoints(maze,tempStart,roleFlag)
-
for i,point in pairs(surroundPoints.tbl) do
-
if existsPoint(maze.openList,point) then
-
--计算G值,如果比原来大,就什么都不做,否则设置他的父节点为当前节点,并更新G和F
-
foundPoint(tempStart,point)
-
else
-
--如果他们不再开始列表里面,就加入,并设置父节点,并计算GHF
-
notFoundPoint(maze,tempStart,point)
-
end
-
end
-
--如果最后一个存在则返回
-
if getPoint(maze.openList,endPoint) then
-
return getPoint(maze.openList,endPoint)
-
end
-
end
-
return getPoint(maze.openList,endPoint)
-
end
-
-
-
--根据一个table创建一个地形
-
function create( tb )
-
local maze = {}
-
maze.step = 1 --格子与格子的基本距离,用于计算H值
-
maze.mazeArray = tb
-
maze.openList = TabledArray.create() --开启列表
-
maze.closeList = TabledArray.create() --关闭列表
-
maze.findPath = findPath
-
return maze
-
end
-
-
-
return Maze
请发表评论