天天看点

开发ing经验关于游戏中寻路

任何的游戏几乎都需要寻路吸,最常用的则是A星寻路,这个算法在网络上可以找到很多的版本,然而,今天则是一起探讨寻路算法的问题。

在我们当前的正在开发的项目中,使用的就是A*算法,在正常的寻路中表现非常好,速度很快,但是实际过程中,用户则有可能点击一个不可能到达的点,那么这个时候有趣的问题就发生了,整个逻辑则会“顿”一下,当然了,这取决于运算方法和主要逻辑是不是在一起,这得另说。只说“顿”的情况,它的发生是因为这个点不可能到达,则我们强大的A*寻路把所有的点全部找个遍,实际情况则是这样的:在4000x3000的地图上,寻路循环进行了30万次,才只是找到一个近似路径而已,我们将这个部分做了修改,将寻路缩小到指定范围,如果超过这个范围则不在进行寻路,图例表示如下:

<a target="_blank" href="http://blog.51cto.com/attachment/201111/162118718.jpg"></a>

只对设定的范围内进行搜索,这也是比限定搜索长度要容易的方式,我尝试使用限定搜索的总长度,但是不怎么好,对于A*的算法代码改动太大,而使用设定范围,只需要在超出范围时候控制好即可。

关于直接寻路,我们会得到一个很不自然的路径,那么为什么不先进行直线行走,走到特定位置然后再按按照寻路点走呢,我们的项目中是这样的解决的,先使用向量计算,然后判定按照步长上的每个点是否在不可达点上,当出现这种情况,则调用寻路,虽然不能达到100%的平滑寻路,但是对于普通的行走已经足够应付,会走一个相对很爽的路径。

可能上述写的很杂乱,表述的问题其实很简单,有的时候我们研究和优化很多的代码,都是存在于实验室——一个完美的环境,而在真实环境将面临着用户乱点一通,或者提出为什么不是很平滑的移动的问题,这些问题有可能让我们需要将路重走一遍,而本篇则是我们项目当中的一篇更新邮件子内容。

//在限定范围内进行处理,所以我们在处理之前就看是否是超出了范围。

off_x += father.x;

off_y += father.y;

if ((off_x &lt; 0) || (off_x &gt;= this.mapW) || (off_x &lt; _rangeMinX) || (off_x &gt;= _rangeMaxX))

{

return false;

}

if ((off_y &lt; 0) || (off_y &gt;= this.mapH) || (off_y &lt; _rangeMinY) || (off_y &gt;= _rangeMaxY))

if (this.map[off_x, off_y].block)

//下面的代码属于另外一个部分,类的成员,作为判定的限定参数

private static int maxFinderW = 50;

private static int maxFinderH = 40;

private int _rangeMinX = 0;

private int _rangeMinY = 0;

private int _rangeMaxX = 1;

private int _rangeMaxY = 1;

private int _sx

set { _rangeMinX = value - maxFinderW; _rangeMaxX = value + maxFinderW; }

private int _sy

set { _rangeMinY = value - maxFinderH; _rangeMaxY = value + maxFinderH; }

本文转自nowpaper 51CTO博客,原文链接:http://blog.51cto.com/nowpaper/712586

继续阅读