A*寻路 -- 更加真实 的路径(二)

本文介绍了A*寻路算法在处理路径不平滑及遇到不可移动点时的问题,提出了弗洛伊德路径平滑算法和寻找替代点法。弗洛伊德算法用于合并共线节点和去除多余拐点,而寻找替代点法解决了不可移动点导致的寻路问题。同时,文章探讨了这两种方法的实现思路和代码实现。
摘要由CSDN通过智能技术生成

转:http://bbs.9ria.com/thread-95620-1-1.html

 

对于A*传统寻路的结果不平滑的问题,我们讨论了一种判断两点间是否存在障碍物的算法,并在用户点击鼠标选择了目的地后先判断起终点间是否存在障碍物,若不存在,则路径数组中将只具有一个终点节点;否则进行A*寻路运算。大致过程可用下面代码表示:

 

//判断起终点间是否存在障碍物,若存在则调用A*算法进行寻路,通过A*寻路得到的路径是一个个所要经过的节点数组;否不存在障碍则直接把路径设置为只含有一个终点元素的数组

var hasBarrier:Boolean = _grid.hasBarrier(startPosX, startPosY, endPosX, endPosY);

if( hasBarrier )
{
      _grid.setStartNode(startPosX, startPosY);
      _grid.setEndNode(endPosX, endPosY);
      findPath();
}

else
{
        _path = [_grid.getNode(endPosX, endPosY)];
       _index = 0;
       addEventListener(Event.ENTER_FRAME, onEnterFrame);//开始行走
}

 

如果你听从了我的建议这么做了,我只能说声抱歉,因为在实际应用中发现了一些问题,什么问题呢?就是当起终点间不存在障碍物时,主角行走的目的地将跳过 A*寻路算法的“考验”,直接设置为我点击的位置(endPosX, endPosY),因此,此位置若有时候会是路径网格外的某一点,主角也以此为目的地进行移动,这样导致的结果就是主角“飞”起来了,或是主角“穿越” 了……为了避免这个问题的发生,我们就必须时时刻刻地使用A*算法去计算路径,即使起终点间没有障碍物也必须调用寻路方法进行寻路。但是如果用A*寻路算 法计算出来的路径不平滑怎么办呢?别急,下面我们来讨论A*寻路算法的路径平滑处理办法:弗洛伊德路径平滑算法。这个算法出之lizhi写的文章:http://wonderfl.net/c/aWCe ,并已被很多人采纳~我们先看一下结果演示:MyPathFinding2

弗洛伊德路径平滑算法应在通过A*寻路算法得出路径后进行,它的步骤分为两步:一、合并路径数组中共线的节点;二、尽可能地去掉多余拐点。这个过程如下图所示:

原始A*寻路路径



 去掉共线点



 去掉多余拐点


可以看到,使用弗洛伊德路径平滑处理 后的路径正如我们期望的那样,而且大大削减了路径数组中的节点数目。

那么接下来来讲讲实现思路吧。首先,不难发现,若存在三点A(1,1), B(2,2), C(3,3),若B与A的横、纵坐标差值分别等于C与B的横、纵坐标差值,则A,B,C三点共线,使用代码来表示就是:

 

 

if( (bx -ax == cx - bx) && (by-ay == cy - by) )
{

//三点共线

}
 

由上式可知去掉路径中共线节点的方法。接下来讨论如何去掉多余的拐点。
仔细观察第三幅图你会发现,若路径中存在节点A,B,C,D,E,F,G,如果A与G之间的连线所经过的节点中没有一个节点是不可移动节点,则我们称A与 G之间是不存在障碍物的。如两节点间不存在障碍物,则可以去掉此两点间其他所有节点。如上例中A-G这些节点,若A与G之间不存在障碍物,则我们可以去掉 A与G之间的B,C,D,E,

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值