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

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

 local MapNode = class("MapNode")

function MapNode:ctor()
self._row = --行
self._col = --列
self._parent = nil--父节点
self._f = --当前节点的总开销
self._g = --当前节点的累计开销
self._h = --启发因子
end return MapNode

"AStar.lua"逻辑实现

local Direction = {}--方向
Direction.Right =
Direction.Right_Down =
Direction.Down =
Direction.Left_Down =
Direction.Left =
Direction.Left_Up =
Direction.Up =
Direction.Right_Up = local MapNode = require "app.views.MapNode" AStar = {}
AStar.__index = AStar function AStar.create()
local temp = {}
setmetatable(temp, AStar)
return temp
end --mapData:二维数组,存放底图数据,0是可行走格子,1是有障碍格子
function AStar:init(mapData)
self._mapData = mapData--地图数据
    
    self._map = {}
    self._lPath = {}--收集的路径
    self._bFind = false local mapRow = #mapData
local mapCol = #mapData[]     for i = , mapRow - do
        self._map[i] = {}
        for j = , mapCol - do
            local mapNode = MapNode.new()
            mapNode._row = i
            mapNode._col = j
            self._map[i][j] = mapNode
        end
    end
end --开始寻路
--from:开始格子位置(非坐标)
--to:目标格子位置
function AStar:getSearchPath(from, to)
self:processAStar(from, to)--收集路径到_lPath
    return self._lPath
end function AStar:canPass(row,col)--判断是否能够通过
    if self._mapData[col][row] == then
        return true
    end
    return false
end
 
function AStar:getAdjacent(currentPos,dir)--根据方向获取相邻格子的位置
if dir == Direction.Right then
        return cc.p(currentPos.x + ,currentPos.y)
    elseif dir == Direction.Right_Down then
        return cc.p(currentPos.x + ,currentPos.y - )
    elseif dir == Direction.Down then
        return cc.p(currentPos.x,currentPos.y - )
    elseif dir == Direction.Left_Down then
        return cc.p(currentPos.x - ,currentPos.y - )
    elseif dir == Direction.Left then
        return cc.p(currentPos.x - ,currentPos.y)
    elseif dir == Direction.Left_Up then
        return cc.p(currentPos.x - ,currentPos.y + )
    elseif dir == Direction.Up then
        return cc.p(currentPos.x,currentPos.y + )
    elseif dir == Direction.Right_Up then
        return cc.p(currentPos.x + ,currentPos.y + )
end
end
 
function AStar: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 =
    fromNode._h = math.abs(fromPos.x - toPos.x) +  math.abs(fromPos.y - toPos.y)
    fromNode._f = fromNode._h
    
    open[#open + ] = fromNode
    while #open > do
    local mapNode = open[]
        table.remove(open,)
    
    if mapNode._row == toPos.x and mapNode._col == toPos.y then
       return true
    end
    
    close[#close + ]  = mapNode
    local parentPos = cc.p(mapNode._col,mapNode._row)
    local adjacentPos = nil
    local adjacentNode = nil
    
    for i = , do
            adjacentPos = self:getAdjacent(parentPos,i)
            if adjacentPos.x >= and adjacentPos.x < mapCol and adjacentPos.y >= 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 % == then
                        g = adjacentNode._g +
                    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 + ] = adjacentNode
                end
            end
    end
    table.sort(open,function(a,b)
       return a._f < b._f
    end)
    end
    return false
end
 
function AStar:processAStar(from,to)--执行A*算法
    local f = self:AStarCore(from,to)
    if f ==  true then
        self:collectRoute(from,to)
        return true
    end
    return false
end
 
function AStar:collectRoute(from, to)--收集路线
    self._lPath = {}
    local mapNode = self._map[to.y][to.x]
    self._lPath[#self._lPath + ] = mapNode
    while mapNode._col ~= from.x or mapNode._row ~= from.y do
        mapNode = mapNode._parent
        self._lPath[#self._lPath + ] = mapNode
    end
end
 
function AStar:isContain(tbl,cell) --在table中是否包含某个单元
    for k,v in pairs(tbl) do
        if tbl[k] == cell then
            return true
        end
    end
    return false
end

测试一下:

TestScene.lua

require "AStar.lua"
local TestScene = class("TestScene",cc.load("mvc").ViewBase) function TestScene:ctor()
    local mapData = {
{, , , , , , , }
{, , , , , , , }
{, , , , , , , }
{, , , , , , , }
{, , , , , , , }
{, , , , , , , }
{, , , , , , , }
{, , , , , , , }
}--地图数据
 
    self.mapData = mapData
    for i = , #mapData do--创建地图快图片
        for j = , #mapData[] 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(,)--起点
    local to = cc.p(,)--目标点
    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(,"stanby_1",true)--创建角色
    self._sprite:setScale(-,)
    self._sprite:setPosition(from.x *tileWidth+(tileWidth*0.5),from.y *tileHeight)
    self:addChild(self._sprite)
    
    local astar_logic = AStar.create()
astar_logic:init(mapData)
self._lPath = astar_logic:getSearchPath(from, to)
    self:drawPathNode()
    self._posIndex = #self._lPath
    self:moveSprite()
end function TestScene:setCollisionSp()--设置障碍物
for k, v in pairs(self.mapData) do
for m, n in pairs(v) do
if n == then--障碍物
local sp = display.newSprite("collision.png",i*tileWidth+(tileWidth*0.5),j*tileHeight+(tileWidth*0.5))
            self:addChild(sp)
end
end
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 = ,onComplete = function() 
        self._posIndex = self._posIndex -
        if self._posIndex == then
            return
        end
        self:moveSprite()
    end})
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

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

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

  1. cocos2d-x学习日志(13) --A星寻路算法demo

    你是否在做一款游戏的时候想创造一些怪兽或者游戏主角,让它们移动到特定的位置,避开墙壁和障碍物呢?如果是的话,请看这篇教程,我们会展示如何使用A星寻路算法来实现它! A星算法简介: A*搜寻算法俗称A星 ...

  2. A*寻路算法lua实现

    前言:并在相当长的时间没有写blog该,我觉得有点"颓废"该,最近认识到各种同行,也刚刚大学毕业,我认为他们是优秀的.认识到与自己的间隙,有点自愧不如.我没有写blog当然,部分原 ...

  3. 《C++游戏开发》十六 游戏中的寻路算法(二):迷宫&A*算法基础

    本系列文章由七十一雾央编写,转载请注明出处.  http://blog.csdn.net/u011371356/article/details/10289253 作者:七十一雾央 新浪微博:http: ...

  4. A*寻路算法详细解读

    文章目录 A*算法描述 简化搜索区域 概述算法步骤 进一步解释 具体寻路过程 模拟需要更新F值的情况 Lua代码实现 在学习A*算法之前,很好奇的是A*为什么叫做A*.在知乎上找到一个回答,大致意思是 ...

  5. A*寻路算法的个人理解

    A*寻路算法是一个求两点之间的最短路径的方法 算法详情如下: 准备工作: 两个容器:   open容器和close容器 价值估算公式:    F = G + H G:从起点移动到指定方格的移动代价: ...

  6. A星寻路算法介绍

    你是否在做一款游戏的时候想创造一些怪兽或者游戏主角,让它们移动到特定的位置,避开墙壁和障碍物呢? 如果是的话,请看这篇教程,我们会展示如何使用A星寻路算法来实现它! 在网上已经有很多篇关于A星寻路算法 ...

  7. A*寻路算法探究

    A*寻路算法探究 A*算法常用在游戏的寻路,是一种静态网路中求解最短路径的搜索方法,也是解决很多搜索问题的算法.相对于Dijkstra,BFS这些算法在复杂的搜索更有效率.本文在U3D中进行代码的测试 ...

  8. A*寻路算法

    对于初学者而言,A*寻路已经是个比较复杂的算法了,为了便于理解,本文降低了A*算法的难度,规定只能横竖(四方向)寻路,而无法直接走对角线,使得整个算法更好理解. 简而言之,A*寻路就是计算从起点经过该 ...

  9. 算法:Astar寻路算法改进,双向A*寻路算法

    早前写了一篇关于A*算法的文章:<算法:Astar寻路算法改进> 最近在写个js的UI框架,顺便实现了一个js版本的A*算法,与之前不同的是,该A*算法是个双向A*. 双向A*有什么好处呢 ...

随机推荐

  1. Spring Cloud Hystrix理解与实践(一):搭建简单监控集群

    前言 在分布式架构中,所谓的断路器模式是指当某个服务发生故障之后,通过断路器的故障监控,向调用方返回一个错误响应,这样就不会使得线程因调用故障服务被长时间占用不释放,避免故障的继续蔓延.Spring ...

  2. CC17:猫狗收容所

    题目 有家动物收容所只收留猫和狗,但有特殊的收养规则,收养人有两种收养方式,第一种为直接收养所有动物中最早进入收容所的,第二种为选择收养的动物类型(猫或狗),并收养该种动物中最早进入收容所的. 给定一 ...

  3. k8s的nfs存储外挂设置过程

    需求: 在k8s集群里的某个模块生成的目录文件或者更新的目录文件,存储到外面某台服务器上 1.安装nfs服务(192.168.1.2  Ubuntu 16.04) apt-get install nf ...

  4. Canada Cup 2016 C. Hidden Word 构造模拟题

    http://codeforces.com/contest/725/problem/C Each English letter occurs at least once in s. 注意到题目有这样一 ...

  5. (转)nginx应用总结(2)--突破高并发的性能优化

    原文:http://www.cnblogs.com/kevingrace/p/6094007.html 在日常的运维工作中,经常会用到nginx服务,也时常会碰到nginx因高并发导致的性能瓶颈问题. ...

  6. 百度地图API的基本用法

    首先 ,如果想调用百度地图api,你需要获取一个百度地图api的密钥. 申请秘钥的步骤: 1.搜索百度地图: 2.进入后,先登录然后点击申请密钥: 3. 4.申请成功,拥有密钥 有了密钥之后,引入百度 ...

  7. RxJava四个基础接口

    Publisher Subscriber Subscription Processor ----------------------------------- public interface Pub ...

  8. 最具士兵突击实战类型的JavaScript

    JavaScript实战一书的基础知识部分帮助读者快速踏入JavaScript领域之门,jQuery部分帮助读者随心所欲地去工作,HTML5部分帮读者搭上时代的班车,Node.JS则可以让读者屹立在技 ...

  9. 链接服务器"(null)"的 OLE DB 访问接口 "SQLNCLI10" 返回了消息 "Cannot start more transactions on this session."

    开发同事反馈一个SQL Server存储过程执行的时候,报"链接服务器"(null)"的 OLE DB 访问接口 "SQLNCLI10" 返回了消息 ...

  10. [nmon]使用nmon工具监控系统资源

    1.下载nmon 下载正确的nmon版本, 查看linux服务器版本,命令:lsb_release -a,查看到当前系统为RedHat 6.4 然后我们根据我们的linux版本,下载相应nmon版本, ...