cocos2dx for lua A*寻路算法实现2

关于A*算法的实现过程,简单来说就是一个计算权限的过程。

首先,创建一个地图节点类,"MapNode.lua"

local MapNode = class("MapNode")

function MapNode:ctor()

self._row = 0--行

self._col = 0--列

self._parent = nil--父节点

self._f = 0--当前节点的总开销

self._g = 0--当前节点的累计开销

self._h = 0--启发因子

end

return MapNode

"TestScene.lua"

local MapNode = require "app.views.MapNode"

local TestScene = class("TestScene",cc.load("mvc").ViewBase)

local mapCol = 9

local mapRow = 9

local tileWidth = 50

local tileHeight = 50

local Direction = {}--方向

Direction.Right = 0

Direction.Right_Down = 1

Direction.Down = 2

Direction.Left_Down = 3

Direction.Left = 4

Direction.Left_Up = 5

Direction.Up = 6

Direction.Right_Up = 7

function TestScene:ctor()

self._mapData = {}--地图数据

for i = 0,mapRow -1 do

self._mapData[i] = {}

for j = 0,mapCol -1 do

self._mapData[i][j] = 0

end

end

self._map = {}

self._lPath = {}--收集的路径

self._bFind = false

for i = 0,mapRow -1 do

self._map[i] = {}

for j = 0,mapCol -1 do

local mapNode = MapNode.new()

mapNode._row = i

mapNode._col = j

self._map[i][j] = mapNode

end

end

for i = 1,mapCol do--创建地图快图片

for j = 1,mapRow do

local tileSp = cc.Sprite:create("tilemap.png")

self:addChild(tileSp)

tileSp:setPosition(i*tileWidth-(tileWidth*0.5),j*tileHeight-(tileWidth*0.5))

end

end

local from = cc.p(0,0)--起点

local to = cc.p(7,8)--目标点

local sp1 = display.newSprite("qizi.png",to.x *tileWidth+(tileWidth*0.5),to.y *tileHeight+(tileWidth*0.5))--目标点图片

self:addChild(sp1)

local sp2 = display.newSprite("qizi.png",from.x *tileWidth+(tileWidth*0.5),from.y *tileHeight+(tileWidth*0.5))--起点图片

self:addChild(sp2)

self:setCollisionSp()

self._sprite = sp.SkeletonAnimation:create("spine/116_m_fks/116_m_fks.json","spine/116_m_fks/116_m_fks.atlas",0.08)

self._sprite:setAnimation(0,"stanby_1",true)--创建角色

self._sprite:setScale(-1,1)

self._sprite:setPosition(from.x *tileWidth+(tileWidth*0.5),from.y *tileHeight)

self:addChild(self._sprite)

self:processAStar(from,to)--收集路径到_lPath

self:drawPathNode()

self._posIndex = #self._lPath

self:moveSprite()

end

function TestScene:drawPathNode()--画路径图片

for k,v in pairs(self._lPath) do

local sp3 = display.newSprite("redPoint.png",v._col *tileWidth+(tileWidth*0.5),v._row  *tileWidth+(tileWidth*0.5))

self:addChild(sp3)

end

end

function TestScene:moveSprite()--移动精灵

local x = self._lPath[self._posIndex]._col *tileWidth+(tileWidth*0.5)

local y = self._lPath[self._posIndex]._row *tileWidth+(tileWidth*0.5)

transition.moveTo(self._sprite,{x = x,y = y,time = 1,onComplete = function()

self._posIndex = self._posIndex - 1

if self._posIndex == 0 then

return

end

self:moveSprite()

end})

end

function TestScene:setCollisionSp()--设置障碍物

for i = 3,6 do

for j = 3,6 do

self._mapData[i][j] = 1

local sp = display.newSprite("collision.png",i*tileWidth+(tileWidth*0.5),j*tileHeight+(tileWidth*0.5))

self:addChild(sp)

end

end

end

function TestScene:canPass(row,col)--判断是否能够通过

if self._mapData[col][row] == 0 then

return true

end

return false

end

function TestScene:getAdjacent(currentPos,dir)--根据方向获取相邻格子的位置

if dir == Direction.Right then

return cc.p(currentPos.x + 1,currentPos.y)

elseif dir == Direction.Right_Down then

return cc.p(currentPos.x + 1,currentPos.y - 1)

elseif dir == Direction.Down then

return cc.p(currentPos.x,currentPos.y - 1)

elseif dir == Direction.Left_Down then

return cc.p(currentPos.x - 1,currentPos.y - 1)

elseif dir == Direction.Left then

return cc.p(currentPos.x - 1,currentPos.y)

elseif dir == Direction.Left_Up then

return cc.p(currentPos.x - 1,currentPos.y + 1)

elseif dir == Direction.Up then

return cc.p(currentPos.x,currentPos.y + 1)

elseif dir == Direction.Right_Up then

return cc.p(currentPos.x + 1,currentPos.y + 1)

end

end

function TestScene:AStarCore(fromPos,toPos)--算法核心代码

local open = {}

local close = {}

local targetNode = self._map[toPos.y][toPos.x]

local fromNode = self._map[fromPos.y][fromPos.x]

local f,g,h;

fromNode._g = 0

fromNode._h = math.abs(fromPos.x - toPos.x) +  math.abs(fromPos.y - toPos.y)

fromNode._f = fromNode._h

open[#open + 1] = fromNode

while #open > 0 do

local mapNode = open[1]

table.remove(open,1)

if mapNode._row == toPos.x and mapNode._col == toPos.y then

return true

end

close[#close + 1]  = mapNode

local parentPos = cc.p(mapNode._col,mapNode._row)

local adjacentPos = nil

local adjacentNode = nil

for i = 0,7 do

adjacentPos = self:getAdjacent(parentPos,i)

if adjacentPos.x >= 0 and adjacentPos.x < mapCol and adjacentPos.y >= 0 and adjacentPos.y < mapRow then

adjacentNode = self._map[adjacentPos.y][adjacentPos.x]

if self:canPass(adjacentPos.y,adjacentPos.x) == true and self:isContain(close,adjacentNode) == false and

self:isContain(open,adjacentNode) == false then

if i % 2 == 0 then

g = adjacentNode._g + 1

else

g = adjacentNode._g + 1.4

end

h = math.abs(adjacentPos.x -toPos.x) + math.abs(adjacentPos.y - toPos.y)

f = g + h

adjacentNode._parent = mapNode

adjacentNode._f = f

adjacentNode._g = g

adjacentNode._h = h

open[#open + 1] = adjacentNode

end

end

end

table.sort(open,function(a,b)

return a._f < b._f

end)

end

return false

end

function TestScene:processAStar(from,to)--执行A*算法

local f = self:AStarCore(from,to)

if f ==  true then

self:collectRoute(from,to)

release_print(true)

return true

end

return false

end

function TestScene:collectRoute(from,to)--收集路线

self._lPath = {}

local mapNode = self._map[to.y][to.x]

self._lPath[#self._lPath + 1] = mapNode

while mapNode._col ~= from.x or mapNode._row ~= from.y do

mapNode = mapNode._parent

self._lPath[#self._lPath + 1] = mapNode

end

end

function TestScene:isContain(tbl,cell) --在table中是否包含某个单元

for k,v in pairs(tbl) do

if tbl[k] == cell then

return true

end

end

return false

end

return TestScene

执行效果如下:

转载请注明出处,from 博客园HemJohn

时间: 2024-12-28 15:20:40

cocos2dx for lua A*寻路算法实现2的相关文章

A*寻路算法的lua实现

一.问题概述 游戏中有敌我双方,有四十个方格,当轮到我方武将行动的时候,要先显示出我方武将可以行动的方位,这个就涉及到我方武将的行动力的大小来决定,预先做出路径的预算.这里还要考虑敌方以及地标(例如:炸弹.势头)的阻挡,以及特殊方格对武将行动力的消耗以及敌方的间隔阻挡规则. 当碰到这个问题的时候,问老大选择用什么寻路算法,他推荐的是Dijstra算法,但我看了之后感觉还不是很适合我的需求,第一:我觉得Dijstra算法是有向图的最佳路径选择,节点之间路径长度必须先知晓,但我这里四十个方格如果要两

菜鸟福利 A星寻路算法 cocos2d-x实现

这篇blog是翻译自iOS Tutorial Team的成员 Johann Fradj,他目前是一位全职的资深iOS开发工程师.他是HotApps Factory的创始人,该公司开发了AppCooker 你是否在做一款游戏的时候想实现一种寻路算法,让一些怪兽或者游戏主角,让它们移动到特定的位置,避开墙壁和障碍物呢? 如果是的话,请看这篇教程,我们会展示如何使用著名的A星寻路算法来实现它! 公式表示为: f(n)=g(n)+h(n), 其中 f(n)是从初始点经由节点n到目标点的估价函数, g(n

这是一个真正靠谱的寻路算法

绝对没有其他看起来高大上 给别人讲都将不明白的理论.管你 人工智能 啥的 ,还有一百度一大篇的a*算法 ,其实大部分文章的理论都是讲不通的 或者没有讲清楚 更别说代码.做事刨根问底的牛脾气又上来了. 两周前 偶然原因接触到了寻路算法 于是百度 找到了a* .讲来将去大概意思就是持续性的找离目标近的节点 并且走过的节点不能重复走.反正百度搜a*算法 一搜一大片.在很简单的障碍的情况下是没问题 : 但是拐个弯就不行了,不是找最近的么,我让你一直找最近的. 直接迂在里面出不来了: 期间我曾经想过为什么

A*寻路算法入门(一)

大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请告诉我,如果觉得不错请多多支持点赞.谢谢! hopy ;) 免责申明:本博客提供的所有翻译文章原稿均来自互联网,仅供学习交流之用,请勿进行商业用途.同时,转载时不要移除本申明.如产生任何纠纷,均与本博客所有人.发表该翻译稿之人无任何关系.谢谢合作! 该篇博客由iOS课程团队的Johann Fradj发布,他现在是一个全职开发iOS的开发者.他是Hot Apps Factory(其是App Cooker的创造者)的共同创建

A*寻路算法的优化与改进

提要 通过对上一篇A*寻路算法的学习,我们对A*寻路应该有一定的了解了,但实际应用中,需要对算法进行一些改进和优化. Iterative Deepening Depth-first search- 迭代深化深度优先搜索 在深度优先搜索中一个比较坑爹情形就是在搜索树的一枝上没有要搜的结果,但是却非常深,甚至深不见底,这样就根本搜索不到结果.为了防止这种情况出现,就出现了Iterative Deepening的思想. 迭代深化搜索(Iterative deepening search, IDS)或者

[转] A*寻路算法C++简单实现

参考文章: http://www.policyalmanac.org/games/aStarTutorial.htm   这是英文原文<A*入门>,最经典的讲解,有demo演示 http://www.cnblogs.com/technology/archive/2011/05/26/2058842.html  这是国人翻译后整理的简版,有简单代码demo,不过有些错误,讲得很清晰,本文图片来自这篇 http://blog.csdn.net/b2b160/article/details/4057

cocos2d-x 中LUA和平台之间的函数调用理解

先看一张流程图如下: 第一步: 先把NDKHelper中的方法转成LUA中可以调用的,转得方法可参考quick中LUA的用法.这个类主要是中间桥梁的作用,它可以根据是什么平台调用IOSNDKHelper或者AndroidSNDKHelper,这些判断都是用C语言来写的.还有就是对一些回调函数的保存机制和平台要用LUA中一些方法的保存. 第二步: IOS平台需要处理的就是IOSNDKHelper,这个类主要就是接收和发送给NDKHelper数据的方法,还有一个就是加载IOS平台的BasePlatf

HTML5-A*寻路算法

设置起点 设置终点 设置障碍 清除障碍 允许斜向跨越 HTML5-A*寻路算法,布布扣,bubuko.com

RCP:gef智能寻路算法(A star)

本路由继承自AbstactRouter,参数只有EditPart(编辑器内容控制器),gridLength(寻路用单元格大小),style(FLOYD,FLOYD_FLAT,FOUR_DIR). 字符集编码为GBK,本文只做简单的代码解析,源码戳我 如果源码不全,可以联系本人. 算法实现主要有三: 1.Astar单向寻路 2.地图预读 3.弗洛伊德平滑算法 Astar寻路的实现: ANode minFNode = null; while (true) { minFNode = findMinNo