cocos2dx(lua)ASTAR算法
·
原理在网上已经有相关文章,就不补充了,因为一直在网上搜不到用lua实现的a星算法,故有下文(只有关键的代码)。
local openList = {}
local closeList = {}
local opcount = 0
local clcount = 0
local newx,newy --新坐标
local step = 0 --移动步数
local predir = nil --原移动方向
local prefns = nil
local idx = 1 --新节点的索引
local num = 1 --openList中表个数
local function setOpenList(direction)
local id = p.mapLayer:tileGIDAt(ccp(newx,newy))if id == 0 then
for k,v in pairs(openList) do
if newx == v.point.x and newy == v.point.y then
return
end
end
for k,v in pairs(closeList) do
if newx == v.point.x and newy == v.point.y then
return
end
end
opcount = opcount + 1
H = math.abs(desx - newx) + math.abs(desy - newy)
openList[opcount] = {}
openList[opcount].point = {x=newx,y=newy}
openList[opcount].go = step
openList[opcount].fns = step + H
openList[opcount].dir = direction
if H == 0 then
step = 0
clcount = clcount + 1
closeList[clcount] = openList[opcount]
p.spriteX,p.spriteY = p.toOpenGLXY(openList[opcount].point.x,openList[opcount].point.y)
end
end
end
--上下左右探索
local function explore()
--up
newx = srcx
newy = srcy - 1
if newy > -1 then
if predir ~= "down" then
setOpenList("up")
end
end
--right
newx = srcx + 1
newy = srcy
if newx < s.width then
if predir ~= "left" then
setOpenList("right")
end
end
--left
newx = srcx - 1
newy = srcy
if newx > -1 then
if predir ~= "right" then
setOpenList("left")
end
end
--down
newx = srcx
newy = srcy + 1
if newy < s.height then
if predir ~= "up" then
setOpenList("down")
end
end
end
local function setCloseList()
for k,v in pairs(openList) do
if k == 1 then
prefns = v.fns
end
if v.fns <= prefns then
idx = k
prefns = v.fns
end
if k == num then
srcx = openList[idx].point.x
srcy = openList[idx].point.y
predir = openList[idx].dir
clcount = clcount + 1
closeList[clcount] = openList[idx]
step = openList[idx].go
table.remove(openList,idx)
opcount = opcount - 1
end
end
end
--获取closelist
while num ~= 0 do
step = step + 1
explore()
if step == 0 then
break
end
num = table.getn(openList)
setCloseList()
end
--播放动作
local function runPlayer()
--获取最佳路径
local nNum = table.getn(closeList)
local srcx,srcy,desx,desy,go
local v = closeList[nNum]
srcx,srcy = v.point.x,v.point.y
go = v.go
for k=nNum-1,1,-1 do
local v = closeList[k]
desx,desy = v.point.x,v.point.y
local H = math.abs(desx - srcx) + math.abs(desy - srcy)
if H > 1 or v.go ~= go - 1 then
table.remove(closeList,k)
else
srcx,srcy = desx,desy
go = v.go
end
end
--播放动作
local newx,newy
local ctime = 0.3
for k,v in pairs(closeList) do
local delay = CCDelayTime:create((ctime+0.2) *(k-1))
local x,y = p.toOpenGLXY(v.point.x,v.point.y)
local moveTo = CCMoveTo:create(ctime,ccp(x,y))
local seq = CCSequence:createWithTwoActions(delay,moveTo)
p.sprite:runAction(seq)
end
end
if step == 0 then
runPlayer()
else
print("不可到达",desx,desy,id)
end
更多推荐



所有评论(0)