首先定义一个节点类
----定义节点类 
local  node= class("node") 
--创建节点,x,y是map的item 
ate(x,y,map) 
local myNode={} 
-- 节点在tmx的位置 
myNode.x = x; 
myNode.y = y; 
---A start参数 
myNode.g = 0;  --当前节点到起始点的代价 
myNode.h = 0;  --当前点的终点的估价 
myNode.f = 0;  --f=g+h 
myNode.father={} -- 记录父节点,用来回溯路径   
return myNode 
end 
return node 
有了node类,我们就可方便书写A start 算法主要逻辑
----A start寻路算法 
local  A_start= class("A_start") 
local node = require("src/model/node") 
local cost_stargiht =1 ; --直线移动花费 
local cost_diag=1.414; --对角线移动花费 
local MapY = 59 --地图y坐标最大值 
local MapX = 89 --地图x坐标最大值 
local _open = {}; --察表 
local _close = {}; --以考察表 
--计算某点的估值函数,可以多种实现 
local function  calculateH(point,endPoint) 
print(endPoint.x , point.x) 
----计算两个点的距离 
local x = math.floor(endPoint.x - point.x)  --获取该点x到终点x的距离 
local y = math.floor(endPoint.y - point.y)  --获取该点y到终点y的距离 
local dis =math.abs(x)+math.abs(y) 
--local dis = math.sqrt(math.pow(x,2)+math.pow(y,2))     
return dis 
end 
---判断某点是否在close表内 
local function isClose(point) 
for key, var in ipairs(_close) do 
if(var.x == point.x and var.y == point.y )then 
return true 
end 
lua字符串转数组
end 
return false 
end 
---判断某点是否在open表内 
local function isOpen(point) 
for key, var in ipairs(_open) do 
if(var.x == point.x and var.y == point.y )then 
return true 
end 
end 
return false 
end 
---寻路住逻辑,startPoint起始点,endPoint为终点,map为地图 
function A_start.findPath(startPoint, endPoint, map) 
_open = {}; --初始化 
_close = {}; --初始化 
--起始点 
local point = ate(startPoint.x,startPoint.y,map) 
point.g = 0   
point.h = calculateH(point,endPoint) 
point.f = point.g + point.h 
--当前节点不等于终点 
while(not(point.x == endPoint.x and point.y == endPoint.y))do   
----获取其上下左右四点 
local around={} 
if(point.y > 0)then --上 
table.insert(ate(point.x,point.y-1,map)) 
end 
if(point.y < MapY)then --下 
table.insert(ate(point.x,point.y+1,map)) 
end 
if(point.x > 0)then --左   
table.insert(ate(point.x-1,point.y,map)) 
end 
if(point.x < MapX)then --右 
table.insert(ate(point.x+1,point.y,map)) 
end 
--检查周围点 
for key, var in pairs(around) do 
--如果不可行走或已在close表,忽略此点 
if(isClose(var) or (veable))then 
--print("忽略该点" .. var.x .. "  " .. var.y)           
else 
--计算此点的代价 
local g = cost_stargiht+ point.g    -- G值等同于上一步的G值 + 从上一步到这里的成本           
local h = calculateH(var,endPoint) 
local f = g + h 
--该点不在open列表内 
if(not isOpen(var))then 
var.g = g; 
var.h = h; 
var.f = f 
var.father = point --指向父节点 
table.insert(_open,var) -- 添加到open表 
--如果在open表,进行f比较 
else 
for key1, var1 in ipairs(_open) do 
if(var1.x == var.x and var1.y == var.y)then   
--if(var1.f>f)then---两个版本,// 检查G值还是F值 
if(var1.g>g)then 
var1.f = f 
var1.g = g 
var1.h = h 
var1.parent = point   
end 
break 
end 
end 
end 
end 
end 
----当前节点完一遍添加到——close表 
table.insert(_close,point) 
--open为空,则查失败 
(_open)== 0)then 
return 0 ---查失败返回0 
end 
-
--从open表去除最小的f点,并从open表移除 
local max=99999 
local myKey 
for key2, var2 in ipairs(_open) do 
if(var2.f<max)then 
max = var2.f 
myKey = key2 
end 
end 
--从_open表移除并取出最小f的点最为起始点 
point = ve(_open,myKey)     
end 
return point.father; -- 返回路径 
end 
return A_start 
这样就完成了A start算法,下面我们来进行测试一下
--精灵移动方法,cocos2d 方法 
local function Noderun(var,node) 
veNum< (node.path))then 
node.layer:getChildByTag(100):runAction(cc.Sequence:create( 
cc.MoveTo:create(Soldier.speed,node.veNum]),cc.CallFunc:create(Noderun,node)))                                 
else     
end 
end       
local startItem = { x = 5,y = 57}     
--终点 
local endItem = { x = 20,y = 49} 
--A_start寻路,调用寻路方法 
local result = require("src/util/A_start").findPath(startItem,endItem,map) 
---路径查到 
if(result ~= 0)then 
var.path = {} --path{}先清零 
table.insert(var.path,Point(map,endItem)) -- 插入终点 
--位置数组 
--这里重要,是查到的路径,还记的在node定义的father变量吗,路径就得靠它,每一个结点的 
--father属性都指向下一个结点,所以可以回溯出路径 
while(result.x)do 
local item = {x =result.x, y=result.y}  --把所有item连起来解释路径 
--Point()是转换为cocos2d的坐标,用于精灵移动               
table.insert(var.path ,  1 , Point(map,item)) 
result=result.father 
end   
-
-节点移动,这里是cocos2d-x 的结点移动,不会的不影响 
Noderun("",var)   
--路径 没到 
else 
print("查失败") 
end 

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。