当前位置:首页 » 操作系统 » a寻路算法

a寻路算法

发布时间: 2022-11-01 05:55:55

‘壹’ 如何基于cocos2dx3.x实现A星寻路算法

在学习本篇教程之前,如果你有cocos2d-x的开发经验,将会有所帮助。如果没有也没关系,因为你可以将这里讲解的例子迁移到其他的语言或者框架中。找到到达你键盘的最短路径,开始吧!Maze猫首先介绍下我们将要在本篇教程中开发的简单游戏。前往下载本篇教程的工程代码。编译运行工程,你将看到以下画面。在这款游戏中,你扮演着一只小偷猫,在一个由危险的狗守护着的地牢里小心穿行。如果你试图穿过一只狗,他会把你吃掉–除非你可以用骨头去贿赂它!所以在这款游戏中,你的任务是尝试以正确的顺序捡起骨头,然后寻找路线穿过狗逃离。注意到猫只能水平或者垂直的移动(例如不能斜线移动),并且会从一个方块的中心点移动到另一个中心点。每个方块既可以是可通行的也可以是不可通行的。尝试下这款游戏,看看你能否找到出路!建议你阅读代码以熟悉它的原理。这是一款相当普通的方块-地图式游戏,我们会在接下来的教程中修改它并使用上A星寻路算法。Maze猫和A星概览正如你所看到的,当你点击地图某处时,猫会沿着你点击的方向跳到相邻的方块上。我们想对程序做修改,让猫持续的往你点击的方块方向前进,就像许多RPGs或者point-and-click冒险类游戏。让我们看下控制触摸事件代码的工作原理。如果你打开HelloWorldScene.cpp文件,你将看到像下面这样去实现触摸操作:autolistener=EventListenerTouchOneByOne::create();listener->setSwallowTouches(true);listener->onTouchBegan=[this](Touch*touch,Event*event){if(_gameOver){returnfalse;}PointtouchLocation=_tileMap->convertTouchToNodeSpace(touch);_cat->moveToward(touchLocation);returntrue;};_eventDispatcher->(listener,this);你可以看到这里只是对猫精灵调用了一个方法,让猫在方块地图上往你点击的地方移动。我们现在要做的是修改在CatSprite.m文件中的以下方法,寻找到达该点的最短路径,并且开始前进:voidCatSprite::moveToward(constPoint&target){}创建ShortestPathStep类我们开始创建一个内部类,代表路径上的一步操作。在这种情况下,它是一个方块和由A星算法计算出来的的F,G和Hscores。classShortestPathStep:publiccocos2d::Object{public:ShortestPathStep();~ShortestPathStep();staticShortestPathStep*createWithPosition(constcocos2d::Point&pos);boolinitWithPosition(constcocos2d::Point&pos);intgetFScore()const;boolisEqual(constShortestPathStep*other)const;std::stringgetDescription()const;CC_SYNTHESIZE(cocos2d::Point,_position,Position);CC_SYNTHESIZE(int,_gScore,GScore);CC_SYNTHESIZE(int,_hScore,HScore);CC_SYNTHESIZE(ShortestPathStep*,_parent,Parent);};现在添加以下代码到CatSprite.cpp文件的顶部。CatSprite::ShortestPathStep::ShortestPathStep():_position(Point::ZERO),_gScore(0),_hScore(0),_parent(nullptr){}CatSprite::ShortestPathStep::~ShortestPathStep(){}CatSprite::ShortestPathStep*CatSprite::ShortestPathStep::createWithPosition(constPoint&pos){ShortestPathStep*pRet=newShortestPathStep();if(pRet&&pRet->initWithPosition(pos)){pRet->autorelease();returnpRet;}else{CC_SAFE_DELETE(pRet);returnnullptr;}}boolCatSprite::ShortestPathStep::initWithPosition(constPoint&pos){boolbRet=false;do{this->setPosition(pos);bRet=true;}while(0);returnbRet;}intCatSprite::ShortestPathStep::getFScore()const{returnthis->getGScore()+this->getHScore();}boolCatSprite::ShortestPathStep::isEqual(constCatSprite::ShortestPathStep*other)const{returnthis->getPosition()==other->getPosition();}std::stringCatSprite::ShortestPathStep::getDescription()const{returnStringUtils::format("pos=[%.0f;%.0f]g=%dh=%df=%d",this->getPosition().x,this->getPosition().y,this->getGScore(),this->getHScore(),this->getFScore());}正如所见,这是一个很简单的类,记录了以下内容:-方块的坐标-G值(记住,这是开始点到当前点的方块数量)-H值(记住,这是当前点到目标点的方块估算数量)-Parent是它的上一步操作-F值,这是方块的和值(它是G+H的值)这里定义了getDescription方法,以方便调试。创建了isEquals方法,当且仅当两个ShortestPathSteps的方块坐标相同时,它们相等(例如它们代表着相同的方块)。创建Open和Closed列表打开CatSprite.h文件,添加如下代码:cocos2d::Vector_spOpenSteps;cocos2d::Vector_spClosedSteps;检查开始和结束点重新实现moveToward方法,获取当前方块坐标和目标方块坐标,然后检查是否需要计算一条路径,最后测试目标方块坐标是否可行走的(在这里只有墙壁是不可行走的)。打开CatSprite.cpp文件,修改moveToward方法,为如下:voidCatSprite::moveToward(constPoint&target){PointfromTileCoord=_layer->tileCoordForPosition(this->getPosition());PointtoTileCoord=_layer->tileCoordForPosition(target);if(fromTileCoord==toTileCoord){CCLOG("You'realreadythere!:P");return;}if(!_layer->isValidTileCoord(toTileCoord)||_layer->isWallAtTileCoord(toTileCoord)){SimpleAudioEngine::getInstance()->playEffect("hitWall.wav");return;}CCLOG("From:%f,%f",fromTileCoord.x,fromTileCoord.y);CCLOG("To:%f,%f",toTileCoord.x,toTileCoord.y);}编译运行,在地图上进行点击,如果不是点击到墙壁的话,可以在控制台看到如下信息:From:24.000000,0.000000To:20.000000,0.000000其中**From**就是猫的方块坐标,**To**就是所点击的方块坐标。实现A星算法根据算法,第一步是添加当前坐标到open列表。还需要三个辅助方法:-一个方法用来插入一个ShortestPathStep对象到适当的位置(有序的F值)-一个方法用来计算从一个方块到相邻方块的移动数值-一个方法是根据"曼哈顿距离"算法,计算方块的H值打开CatSprite.cpp文件,添加如下方法:voidCatSprite::insertInOpenSteps(CatSprite::ShortestPathStep*step){intstepFScore=step->getFScore();ssize_tcount=_spOpenSteps.size();ssize_ti=0;for(;igetFScore()){break;}}_spOpenSteps.insert(i,step);}intCatSprite::computeHScoreFromCoordToCoord(constPoint&fromCoord,constPoint&toCoord){//忽略了可能在路上的各种障碍returnabs(toCoord.x-fromCoord.x)+abs(toCoord.y-fromCoord.y);}intCatSprite::(constShortestPathStep*fromStep,constShortestPathStep*toStep){//因为不能斜着走,而且由于地形就是可行走和不可行走的成本都是一样的//如果能够对角移动,或者有沼泽、山丘等等,那么它必须是不同的return1;}接下来,需要一个方法去获取给定方块的所有相邻可行走方块。因为在这个游戏中,HelloWorld管理着地图,所以在那里添加方法。打开HelloWorldScene.cpp文件,添加如下方法:PointArray*HelloWorld::(constPoint&tileCoord)const{PointArray*tmp=PointArray::create(4);//上Pointp(tileCoord.x,tileCoord.y-1);if(this->isValidTileCoord(p)&&!this->isWallAtTileCoord(p)){tmp->addControlPoint(p);}//左p.setPoint(tileCoord.x-1,tileCoord.y);if(this->isValidTileCoord(p)&&!this->isWallAtTileCoord(p)){tmp->addControlPoint(p);}//下p.setPoint(tileCoord.x,tileCoord.y+1);if(this->isValidTileCoord(p)&&!this->isWallAtTileCoord(p)){tmp->addControlPoint(p);}//右p.setPoint(tileCoord.x+1,tileCoord.y);if(this->isValidTileCoord(p)&&!this->isWallAtTileCoord(p)){tmp->addControlPoint(p);}returntmp;}可以继续CatSprite.cpp中的moveToward方法了,在moveToward方法的后面,添加如下代码:boolpathFound=false;_spOpenSteps.clear();_spClosedSteps.clear();//首先,添加猫的方块坐标到open列表this->insertInOpenSteps(ShortestPathStep::createWithPosition(fromTileCoord));do{//得到最小的F值步骤//因为是有序列表,第一个步骤总是最小的F值ShortestPathStep*currentStep=_spOpenSteps.at(0);//添加当前步骤到closed列表_spClosedSteps.pushBack(currentStep);//将它从open列表里面移除//需要注意的是,如果想要先从open列表里面移除,应小心对象的内存_spOpenSteps.erase(0);//如果当前步骤是目标方块坐标,那么就完成了if(currentStep->getPosition()==toTileCoord){pathFound=true;ShortestPathStep*tmpStep=currentStep;CCLOG("PATHFOUND:");do{CCLOG("%s",tmpStep->getDescription().c_str());tmpStep=tmpStep->getParent();//倒退}while(tmpStep);//直到没有上一步_spOpenSteps.clear();_spClosedSteps.clear();break;}//得到当前步骤的相邻方块坐标PointArray*adjSteps=_layer->(currentStep->getPosition());for(ssize_ti=0;icount();++i){ShortestPathStep*step=ShortestPathStep::createWithPosition(adjSteps->getControlPointAtIndex(i));//检查步骤是不是已经在closed列表if(this->getStepIndex(_spClosedSteps,step)!=-1){continue;}//计算从当前步骤到此步骤的成本intmoveCost=this->(currentStep,step);//检查此步骤是否已经在open列表ssize_tindex=this->getStepIndex(_spOpenSteps,step);//不在open列表,添加它if(index==-1){//设置当前步骤作为上一步操作step->setParent(currentStep);//G值等同于上一步的G值+从上一步到这里的成本step->setGScore(currentStep->getGScore()+moveCost);//H值即是从此步骤到目标方块坐标的移动量估算值step->setHScore(this->computeHScoreFromCoordToCoord(step->getPosition(),toTileCoord));//按序添加到open列表this->insertInOpenSteps(step);}else{//获取旧的步骤,其值已经计算过step=_spOpenSteps.at(index);//检查G值是否低于当前步骤到此步骤的值if((currentStep->getGScore()+moveCost)getGScore()){//G值等同于上一步的G值+从上一步到这里的成本step->setGScore(currentStep->getGScore()+moveCost);//因为G值改变了,F值也会跟着改变//所以为了保持open列表有序,需要将此步骤移除,再重新按序插入//在移除之前,需要先保持引用step->retain();//现在可以放心移除,不用担心被释放_spOpenSteps.erase(index);//重新按序插入this->insertInOpenSteps(step);//现在可以释放它了,因为open列表应该持有它step->release();}}}}while(_spOpenSteps.size()>0);if(!pathFound){SimpleAudioEngine::getInstance()->playEffect("hitWall.wav");}添加以下方法:ssize_tCatSprite::getStepIndex(constcocos2d::Vector&steps,constCatSprite::ShortestPathStep*step){for(ssize_ti=0;iisEqual(step)){returni;}}return-1;}编译运行,在地图上进行点击,如下图所示:From:24.000000,0.000000To:23.000000,3.000000PATHFOUND:pos=[23;3]g=10h=0f=10pos=[22;3]g=9h=1f=10pos=[21;3]g=8h=2f=10pos=[20;3]g=7h=3f=10pos=[20;2]g=6h=4f=10pos=[20;1]g=5h=5f=10pos=[21;1]g=4h=4f=8pos=[22;1]g=3h=3f=6pos=[23;1]g=2h=2f=4pos=[24;1]g=1h=3f=4pos=[24;0]g=0h=0f=0注意该路径是从后面建立的,所以必须从下往上看猫选择了哪条路径。跟随路径前进现在已经找到了路径,只需让猫跟随前进即可。需要创建一个数组去存储路径,打开CatSprite.h文件,添加如下代码:cocos2d::Vector_shortestPath;打开CatSprite.cpp文件,更改moveToward方法,注释掉语句**boolpathFound=false**;,如下://boolpathFound=false;替换语句**pathFound=true;**为如下://pathFound=true;this->(currentStep);并且注释掉下方的调试语句://ShortestPathStep*tmpStep=currentStep;//CCLOG("PATHFOUND:");//do//{//CCLOG("%s",tmpStep->getDescription().c_str());//tmpStep=tmpStep->getParent();//倒退/

‘贰’ A* 寻路算法

A*算法
�6�1 启发式搜索
– 在搜索中涉及到三个函数
�6�1 g(n) = 从初始结点到结点n的耗费
�6�1 h(n) = 从结点n到目的结点的耗费评估值,启发函数
�6�1 f(n)=g(n)+h(n) 从起始点到目的点的最佳评估值
– 每次都选择f(n)值最小的结点作为下一个结点,
直到最终达到目的结点
– A*算法的成功很大程度依赖于h(n)函数的构建
�6�1 在各种游戏中广泛应用 Open列表和Closed列表
– Open列表
�6�1 包含我们还没有处理到的结点
�6�1 我们最开始将起始结点放入到Open列表中
– Closed列表
�6�1 包含我们已经处理过的结点
�6�1 在算法启动时,Closed列表为空 A* 算法伪代码初始化OPEN列表
初始化CLOSED列表
创建目的结点;称为node_goal
创建起始结点;称为node_start
将node_start添加到OPEN列表
while OPEN列表非空{
从OPEN列表中取出f(n)值最低的结点n
将结点n添加到CLOSED列表中
if 结点n与node_goal相等then 我们找到了路径,程序返回n
else 生成结点n的每一个后继结点n'
foreach 结点n的后继结点n'{
将n’的父结点设置为n
计算启发式评估函数h(n‘)值,评估从n‘到node_goal的费用
计算g(n‘) = g(n) + 从n’到n的开销
计算f(n') = g(n') + h(n')
if n‘位于OPEN或者CLOSED列表and 现有f(n)较优then丢弃n’ ,处理后继n’
将结点n‘从OPEN和CLOSED中删除
添加结点n‘到OPEN列表
}
}
return failure (我们已经搜索了所有的结点,但是仍然没有找到一条路径)

‘叁’ A星寻路算法和Unity自带的寻路相比有什么优势

在理解Navigation的时候,首先要明确两个知识点:

AStar:AStar是路点寻路算法中的一种,同时AStar不属于贪婪算法,贪婪算法适合动态规划,寻找局部最优解,不保证最优解。AStar是静态网格中求解最短路最有效的方法。也是耗时的算法,不宜寻路频繁的场合。一般来说适合需求精确的场合。

性能和内存占用率都还行,和启发式的搜索一样,能够根据改变网格密度、网格耗散来进行调整精确度。

A Star一般使用场景:

  • 策略游戏的策略搜索

  • 方块格子游戏中的格子寻路

Navigation:网格寻路算法,严格意义上它属于”拐角点算法”,效率是比较高的,但是不保证最优解算法。Navigation相对来说消耗内存更大,性能的话还不错。

Navigation一般使用场景:

  • 游戏场景的怪物寻路

  • 动态规避障碍

它们二者事件的实现方式和原理都不同。


AStar的话,

‘肆’ 如何在Cocos2D游戏中实现A*寻路算法

操作步骤如下:一win764位系统搭建Android开发环境需要的软件1.cocos2d-x3.3beta02.VisualStudio2012/2013安装完占硬盘空间近10G,VisualStudio2012/2013是需要注册码。4.AndroidSDK(其中包括Eclipse)5.AndroidNDK6.Ant7.Python2.7.8不要下载3.x以上版本二软件安装安装软件时不要安装在C盘。1.VisualStudio2012/2013VisualStudio2012/2013安装方法像安装其他软件一样,一路下一步就可以,但是注意安装前IE浏览器版本必须是IE10以上版本。2.Python2.7.8安装方法同上,但是不要安装在C盘。3.JAVAJDKJAVAJDK默认安装,这个可以安装在C盘。4.cocos2d-x3.3beta0 AndroidSDK AndroidNDK Ant这些软件都是解压包,不需要安装,解压就可以。三cocos2d-x3.3beta0环境调试1.打开cocos2d-x3.3beta0所在的文件[attachment=78978]按Shift+鼠标右键,点在此次打开命令窗口。现在可以看见画黄线的是软件变量名称,红线是变量路径。正常的是4个变量名称4条变量路径,如果不是就需要手动添加,方法如下:1.右键计算机(XP叫我的电脑,win7叫计算机)------2.属性------3.高级系统设置------4.环境变量------5.新建6.在变量名中添加缺少的变量名,在变量值中添加路径。如:变量名NDK_ROOT 变量值D:\android-ndk-r10b软件名称 变量名cocos2d-x3.3beta0 COCOS_CONSOLE_ROOTAndroidSDK ANDROID_SDK_ROOTAndroidNDK NDK_ROOTAnt ANT_ROOT再次.打开cocos2d-x3.3beta0所在的文件,按Shift+鼠标右键,点在此次打开命令窗口。如果看到4个变量名称4条变量路径就说明变量调试正确。四创建项目1.打开cocos2d-x3.3beta0所在的文件,按Shift+鼠标右键,点在此次打开命令窗口。2.键入setup.py回车3.键入cocosnew项目名称-p包名-l语言cpp-d项目路径如:cocosnewtest-ptiaoshi-lcpp-d/test/android/cheshi会在存放cocos2d-x3.3beta0的盘符里出现一个名称为tset的文件,打开文件-----proj.win32-----TSET.sin在VisualStudio2013中点 调试------开始执行不调试

‘伍’ 梦幻西游 寻路算法

[HOTKEY]A [NAME]压镖大大王 [CONTENT] [SCRIPT]BEGINMOVE FAST [SCRIPT]MOVETO 23 14 [SCRIPT]REM 出镖局 [SCRIPT]MOVEOUT 2 12 5 [SCRIPT]REM 长安至大唐国境线路 [SCRIPT]MOVETO 500 135 [SCRIPT]MOVETO 505 190 [SCRIPT]MOVETO 390 195 [SCRIPT]MOVETO 282 138 [SCRIPT]MOVETO 125 60 [SCRIPT]MOVETO 30 20 [SCRIPT]REM 出长安 [SCRIPT]MOVEOUT 4 3 4 [SCRIPT]REM 大唐国境至大唐境外线路 [SCRIPT]MOVETO 300 88 [SCRIPT]MOVETO 255 30 [SCRIPT]MOVETO 120 43 [SCRIPT]MOVETO 23 72 [SCRIPT]REM 出大唐国境 [SCRIPT]MOVEOUT 8 86 44 [SCRIPT]REM 大唐国境至狮陀岭线路 [SCRIPT]MOVETO 622 83 [SCRIPT]MOVETO 600 65 [SCRIPT]MOVETO 575 78 [SCRIPT]MOVETO 539 102 [SCRIPT]MOVETO 525 66 [SCRIPT]MOVETO 578 28 [SCRIPT]MOVETO 560 3 [SCRIPT]MOVETO 405 10 [SCRIPT]MOVETO 330 48 [SCRIPT]MOVETO 338 82 [SCRIPT]MOVETO 318 86 [SCRIPT]MOVETO 285 83 [SCRIPT]MOVETO 282 45 [SCRIPT]MOVETO 264 20 [SCRIPT]MOVETO 200 20 [SCRIPT]MOVETO 82 48 [SCRIPT]MOVETO 55 15 [SCRIPT]MOVETO 20 55 [SCRIPT]REM 进狮陀岭 [SCRIPT]MOVEOUT 6 49 34 [SCRIPT]REM 狮陀岭至狮王洞线路 [SCRIPT]MOVETO 108 58 [SCRIPT]MOVETO 65 35 [SCRIPT]MOVETO 65 6 [SCRIPT]MOVETO 112 20 [SCRIPT]REM 进狮王洞 [SCRIPT]MOVEOUT 118 25 35 [SCRIPT]REM 到达大大王跟前 [SCRIPT]MOVETO 22 12

------------------

[HOTKEY]B [NAME]压镖二大王 [CONTENT] [SCRIPT]BEGINMOVE FAST [SCRIPT]MOVETO 23 14 [SCRIPT]REM 出镖局 [SCRIPT]MOVEOUT 2 12 5 [SCRIPT]REM 长安至大唐国境线路 [SCRIPT]MOVETO 500 135 [SCRIPT]MOVETO 505 190 [SCRIPT]MOVETO 395 195 [SCRIPT]MOVETO 282 138 [SCRIPT]MOVETO 125 60 [SCRIPT]MOVETO 30 20 [SCRIPT]REM 出长安 [SCRIPT]MOVEOUT 4 3 4 [SCRIPT]REM 大唐国境至大唐境外线路 [SCRIPT]MOVETO 300 88 [SCRIPT]MOVETO 255 30 [SCRIPT]MOVETO 120 43 [SCRIPT]MOVETO 23 72 [SCRIPT]REM 出大唐国境 [SCRIPT]MOVEOUT 8 86 44 [SCRIPT]REM 大唐国境至狮陀岭线路 [SCRIPT]MOVETO 622 83 [SCRIPT]MOVETO 600 65 [SCRIPT]MOVETO 575 78 [SCRIPT]MOVETO 539 102 [SCRIPT]MOVETO 525 66 [SCRIPT]MOVETO 578 28 [SCRIPT]MOVETO 560 3 [SCRIPT]MOVETO 405 10 [SCRIPT]MOVETO 330 48 [SCRIPT]MOVETO 338 82 [SCRIPT]MOVETO 318 86 [SCRIPT]MOVETO 285 83 [SCRIPT]MOVETO 282 45 [SCRIPT]MOVETO 264 20 [SCRIPT]MOVETO 200 20 [SCRIPT]MOVETO 82 48 [SCRIPT]MOVETO 55 15 [SCRIPT]MOVETO 20 55 [SCRIPT]REM 进狮陀岭 [SCRIPT]MOVEOUT 6 49 34 [SCRIPT]REM 狮陀岭至大象洞线路 [SCRIPT]MOVETO 108 58 [SCRIPT]MOVETO 52 78 [SCRIPT]MOVETO 20 82 [SCRIPT]REM 进大象洞 [SCRIPT]MOVEOUT 28 84 37 [SCRIPT]REM 到达二大王跟前 [SCRIPT]MOVETO 20 10

----------------

[HOTKEY]C [NAME]压镖三大王 [CONTENT] [SCRIPT]BEGINMOVE FAST [SCRIPT]MOVETO 23 14 [SCRIPT]REM 出镖局 [SCRIPT]MOVEOUT 3 12 5 [SCRIPT]REM 长安至大唐国境线路 [SCRIPT]MOVETO 500 135 [SCRIPT]MOVETO 505 190 [SCRIPT]MOVETO 390 195 [SCRIPT]MOVETO 282 138 [SCRIPT]MOVETO 125 60 [SCRIPT]MOVETO 30 20 [SCRIPT]REM 出长安 [SCRIPT]MOVEOUT 4 3 4 [SCRIPT]REM 大唐国境至大唐境外线路 [SCRIPT]MOVETO 300 88 [SCRIPT]MOVETO 255 30 [SCRIPT]MOVETO 120 43 [SCRIPT]MOVETO 23 72 [SCRIPT]REM 出大唐国境 [SCRIPT]MOVEOUT 8 86 44 [SCRIPT]REM 大唐国境至狮陀岭线路 [SCRIPT]MOVETO 622 83 [SCRIPT]MOVETO 600 65 [SCRIPT]MOVETO 575 78 [SCRIPT]MOVETO 539 102 [SCRIPT]MOVETO 525 66 [SCRIPT]MOVETO 578 28 [SCRIPT]MOVETO 560 3 [SCRIPT]MOVETO 405 10 [SCRIPT]MOVETO 330 48 [SCRIPT]MOVETO 338 82 [SCRIPT]MOVETO 318 86 [SCRIPT]MOVETO 285 83 [SCRIPT]MOVETO 282 45 [SCRIPT]MOVETO 264 20 [SCRIPT]MOVETO 200 20 [SCRIPT]MOVETO 82 48 [SCRIPT]MOVETO 55 15 [SCRIPT]MOVETO 20 55 [SCRIPT]REM 进狮陀岭 [SCRIPT]MOVEOUT 6 49 34 [SCRIPT]REM 狮陀岭至老雕洞线路 [SCRIPT]MOVETO 108 58 [SCRIPT]MOVETO 55 60 [SCRIPT]MOVETO 30 48 [SCRIPT]REM 进老雕洞 [SCRIPT]MOVEOUT 13 43 36 [SCRIPT]REM 到达三大王跟前 [SCRIPT]MOVETO 15 12

----------------

[HOTKEY]D [NAME]压镖牛魔王 [CONTENT] [SCRIPT]BEGINMOVE FAST [SCRIPT]MOVETO 23 14 [SCRIPT]REM 出镖局 [SCRIPT]MOVEOUT 2 12 5 [SCRIPT]REM 长安至大唐国境线路 [SCRIPT]MOVETO 500 135 [SCRIPT]MOVETO 505 190 [SCRIPT]MOVETO 395 195 [SCRIPT]MOVETO 282 138 [SCRIPT]MOVETO 125 60 [SCRIPT]MOVETO 30 20 [SCRIPT]REM 出长安 [SCRIPT]MOVEOUT 4 3 4 [SCRIPT]REM 大唐国境至大唐境外线路 [SCRIPT]MOVETO 300 88 [SCRIPT]MOVETO 255 30 [SCRIPT]MOVETO 120 43 [SCRIPT]MOVETO 23 72 [SCRIPT]REM 出大唐国境 [SCRIPT]MOVEOUT 8 86 44 [SCRIPT]REM 大唐国境至牛魔寨线路 [SCRIPT]MOVETO 622 83 [SCRIPT]MOVETO 600 65 [SCRIPT]MOVETO 575 78 [SCRIPT]MOVETO 539 102 [SCRIPT]MOVETO 525 66 [SCRIPT]MOVETO 578 28 [SCRIPT]MOVETO 560 3 [SCRIPT]MOVETO 405 10 [SCRIPT]MOVETO 330 48 [SCRIPT]MOVETO 338 82 [SCRIPT]MOVETO 318 86 [SCRIPT]MOVETO 285 83 [SCRIPT]MOVETO 282 45 [SCRIPT]MOVETO 264 20 [SCRIPT]MOVETO 200 20 [SCRIPT]MOVETO 82 48 [SCRIPT]MOVETO 55 15 [SCRIPT]MOVETO 35 42 [SCRIPT]MOVETO 72 105 [SCRIPT]REM 进牛魔寨 [SCRIPT]MOVEOUT 54 116 38 [SCRIPT]REM 狮陀岭至魔王居线路 [SCRIPT]MOVETO 35 65 [SCRIPT]MOVETO 78 65 [SCRIPT]MOVETO 88 70 [SCRIPT]REM 进魔王居 [SCRIPT]MOVEOUT 93 73 39 [SCRIPT]REM 到达牛魔王跟前 [SCRIPT]MOVETO 20 12

----------------

[HOTKEY]E [NAME]压镖杨戬 [CONTENT] [SCRIPT]BEGINMOVE FAST [SCRIPT]MOVETO 23 14 [SCRIPT]REM 出镖局 [SCRIPT]MOVEOUT 3 13 5 [SCRIPT]REM 长安至大唐国境线路 [SCRIPT]MOVETO 500 135 [SCRIPT]MOVETO 505 190 [SCRIPT]MOVETO 395 190 [SCRIPT]MOVETO 282 138 [SCRIPT]MOVETO 125 60 [SCRIPT]MOVETO 30 20 [SCRIPT]REM 出长安 [SCRIPT]MOVEOUT 4 3 4 [SCRIPT]REM 大唐国境至大唐境外线路 [SCRIPT]MOVETO 300 88 [SCRIPT]MOVETO 255 30 [SCRIPT]MOVETO 120 43 [SCRIPT]MOVETO 23 72 [SCRIPT]REM 出大唐国境 [SCRIPT]MOVEOUT 8 86 44 [SCRIPT]REM 大唐国境至长寿郊外线路 [SCRIPT]MOVETO 622 83 [SCRIPT]MOVETO 600 65 [SCRIPT]MOVETO 575 78 [SCRIPT]MOVETO 539 102 [SCRIPT]MOVETO 525 66 [SCRIPT]MOVETO 578 28 [SCRIPT]MOVETO 560 3 [SCRIPT]MOVETO 405 10 [SCRIPT]MOVETO 330 48 [SCRIPT]MOVETO 338 82 [SCRIPT]MOVETO 318 86 [SCRIPT]MOVETO 285 83 [SCRIPT]MOVETO 282 45 [SCRIPT]MOVETO 264 20 [SCRIPT]MOVETO 200 20 [SCRIPT]MOVETO 82 48 [SCRIPT]MOVETO 55 15 [SCRIPT]REM 对话南瞻部洲土地 [SCRIPT]CLEAR TALKNPC [SCRIPT]TALKNPC 52 15 [SCRIPT]REM 长寿郊外至天宫线路 [SCRIPT]MOVETO 21 58 [SCRIPT]REM 对话天将 [SCRIPT]CLEAR TALKNPC [SCRIPT]TALKNPC 23 55 [SCRIPT]REM 天宫至灵宵宝殿线路 [SCRIPT]MOVETO 150 60 3 3 31 [SCRIPT]REM 进灵宵宝殿 [SCRIPT]MOVEOUT 144 64 32 [SCRIPT]REM 到达杨戬身旁 [SCRIPT]MOVETO 56 28

-----------------

[HOTKEY]F [NAME]压镖李靖 [CONTENT] [SCRIPT]BEGINMOVE FAST [SCRIPT]MOVETO 23 14 [SCRIPT]REM 出镖局 [SCRIPT]MOVEOUT 3 13 5 [SCRIPT]REM 长安至大唐国境线路 [SCRIPT]MOVETO 500 135 [SCRIPT]MOVETO 505 190 [SCRIPT]MOVETO 395 190 [SCRIPT]MOVETO 282 138 [SCRIPT]MOVETO 125 60 [SCRIPT]MOVETO 30 20 [SCRIPT]REM 出长安 [SCRIPT]MOVEOUT 4 3 4 [SCRIPT]REM 大唐国境至大唐境外线路 [SCRIPT]MOVETO 300 88 [SCRIPT]MOVETO 255 30 [SCRIPT]MOVETO 120 43 [SCRIPT]MOVETO 23 72 [SCRIPT]REM 出大唐国境 [SCRIPT]MOVEOUT 8 86 44 [SCRIPT]REM 大唐国境至长寿郊外线路 [SCRIPT]MOVETO 622 83 [SCRIPT]MOVETO 600 65 [SCRIPT]MOVETO 575 78 [SCRIPT]MOVETO 539 102 [SCRIPT]MOVETO 525 66 [SCRIPT]MOVETO 578 28 [SCRIPT]MOVETO 560 3 [SCRIPT]MOVETO 405 10 [SCRIPT]MOVETO 330 48 [SCRIPT]MOVETO 338 82 [SCRIPT]MOVETO 318 86 [SCRIPT]MOVETO 285 83 [SCRIPT]MOVETO 282 45 [SCRIPT]MOVETO 264 20 [SCRIPT]MOVETO 200 20 [SCRIPT]MOVETO 82 48 [SCRIPT]MOVETO 55 15 [SCRIPT]REM 对话南瞻部洲土地 [SCRIPT]CLEAR TALKNPC [SCRIPT]TALKNPC 52 15 [SCRIPT]REM 长寿郊外至天宫线路 [SCRIPT]MOVETO 21 58 [SCRIPT]REM 对话天将 [SCRIPT]CLEAR TALKNPC [SCRIPT]TALKNPC 23 55 [SCRIPT]REM 天宫至灵宵宝殿线路 [SCRIPT]MOVETO 150 60 3 3 31 [SCRIPT]REM 进灵宵宝殿 [SCRIPT]MOVEOUT 144 64 32 [SCRIPT]REM 到达李靖身旁 [SCRIPT]MOVETO 32 36

-----------------

[HOTKEY]G [NAME]压镖普提老祖 [CONTENT] [SCRIPT]BEGINMOVE FAST [SCRIPT]MOVETO 23 14 [SCRIPT]REM 出镖局 [SCRIPT]MOVEOUT 2 12 5 [SCRIPT]REM 长安至大唐国境线路 [SCRIPT]MOVETO 500 135 [SCRIPT]MOVETO 505 190 [SCRIPT]MOVETO 390 195 [SCRIPT]MOVETO 282 138 [SCRIPT]MOVETO 125 60 [SCRIPT]MOVETO 30 20 [SCRIPT]REM 出长安 [SCRIPT]MOVEOUT 4 3 4 [SCRIPT]REM 大唐国境至大唐境外线路 [SCRIPT]MOVETO 300 88 [SCRIPT]MOVETO 255 30 [SCRIPT]MOVETO 120 43 [SCRIPT]MOVETO 23 72 [SCRIPT]REM 出大唐国境 [SCRIPT]MOVEOUT 8 86 44 [SCRIPT]REM 大唐国境至长寿郊外线路 [SCRIPT]MOVETO 622 83 [SCRIPT]MOVETO 600 65 [SCRIPT]MOVETO 575 78 [SCRIPT]MOVETO 539 102 [SCRIPT]MOVETO 525 66 [SCRIPT]MOVETO 578 28 [SCRIPT]MOVETO 560 3 [SCRIPT]MOVETO 405 10 [SCRIPT]MOVETO 330 48 [SCRIPT]MOVETO 338 82 [SCRIPT]MOVETO 318 86 [SCRIPT]MOVETO 285 83 [SCRIPT]MOVETO 282 45 [SCRIPT]MOVETO 264 20 [SCRIPT]MOVETO 200 20 [SCRIPT]MOVETO 82 48 [SCRIPT]MOVETO 55 15 [SCRIPT]REM 对话南瞻部洲土地 [SCRIPT]CLEAR TALKNPC [SCRIPT]TALKNPC 52 15 [SCRIPT]REM 长寿郊外至长寿村线路 [SCRIPT]MOVETO 45 30 [SCRIPT]MOVETO 60 65 [SCRIPT]MOVETO 125 90 [SCRIPT]MOVETO 150 152 [SCRIPT]REM 进长寿村 [SCRIPT]MOVEOUT 154 162 28 [SCRIPT]REM 长寿村至方寸山线路 [SCRIPT]MOVETO 132 166 [SCRIPT]MOVETO 102 195 [SCRIPT]REM 出长寿村 [SCRIPT]MOVEOUT 111 206 29 [SCRIPT]REM 方寸山至灵台宫线路 [SCRIPT]MOVETO 126 26 [SCRIPT]MOVETO 135 60 [SCRIPT]MOVETO 55 90 [SCRIPT]MOVETO 125 130 [SCRIPT]REM 进灵台宫 [SCRIPT]MOVEOUT 125 136 30 [SCRIPT]MOVETO 39 25
如果是这个脚本 请采纳我的 谢谢

‘陆’ lua语言a星寻路算法路径怎么平滑

在项目中遇到了自动寻路的需求,于是决定开始学习一下A星,对于A星我也没有深究,只能说是勉强搞定了需求,在这和大家分享一下,相互进步,

A星有个公式 f(x) = g(x) + h(x)
,搞清楚这个公式就好办了,f(x)就是当前位置到下一个位置的总价值,g(x)表示实际价,这是说这一部分代价是确定的,h(x)表示估价值,就是说我
从下一个位置到到终点的代价是未知的,所以叫估价值,如图中所示,黑色格子表示当前位置,绿色格子表示下一步可能到达的位置,即上、下、左、右这几个方
向,红色格子表示终点,褐色表示障碍物,现在要从黑色格子到达红色格子,那么黑色格子的下一步肯定是绿色格子当中的一个,黑色格子到绿色格子之间是相挨着
的,所以我们可以很明确的知道它的实际代价为1(移动一步的代价)即g(x),绿色格子到红色格子之间隔着很长的距离,中间还有障碍物,所以这个代价是未
知的,即h(x),所以总的代价就为f(x) = g(x) +
h(x),我们看到周围有4个绿色的格子,到底走那一步比较好呢,所以我们要把这4个格子的f(x)值都求出来,然后进行排序,选择f(x)值最小的,即
总代价最少的那个格子,以此方法继续下去,直到到达终点 或者 地图上没有绿色格子了

下面来看一下这个工具类,g(x)和h(x)要选的比较合适,一般就是采用的曼哈顿算法,即两点在x方向和y方向的距离之和,
-- Filename: PathUtil.lua
-- Author: bzx
-- Date: 2014-07-01
-- Purpose: 寻路

mole("PathUtil", package.seeall)

local _map_data -- 地图数据
local _open_list -- 开放节点
local _open_map -- 开放节点,为了提高性能而加
local _close_map -- 关闭节点
local _deleget -- 代理
local _dest_point -- 目标点
local _start_point -- 起点
local _path -- 路径

-- 寻找路径
--[[
deleget = {
g = function(point1, point2)
-- add your code
-- 返回点point1到点point2的实际代价
end
h = function(point1, point2)
-- add your code
-- 返回点point1到点point2的估算代价
end
getValue = function(j, i)
-- 返回地图中第i行,第j列的数据 1为障碍物,0为非障碍物
end
width -- 地图宽度
height -- 地图高度
}
--]]
function findPath(deleget, start_point, dest_point)
_deleget = deleget
_dest_point = dest_point
_start_point = start_point
init()
while not table.isEmpty(_open_list) do
local cur_point = _open_list[1]
table.remove(_open_list, 1)
_open_map[cur_point.key] = nil
if isEqual(cur_point, dest_point) then
return makePath(cur_point)
else
_close_map[cur_point.key] = cur_point
local next_points = getNextPoints(cur_point)
for i = 1, #next_points do
local next_point = next_points[i]
if _open_map[next_point.key] == nil and _close_map[next_point.key] == nil and isObstacle(next_point) == false then
_open_map[next_point.key] = next_point
table.insert(_open_list, next_point)
end
end
table.sort(_open_list, compareF)
end
end
return nil
end

function init()
_open_list = {}
_open_map = {}
_close_map = {}
_path = {}
_map_data = {}
for i = 1, _deleget.height do
_map_data[i] = {}
for j = 1, _deleget.width do
local value = _deleget.getValue(j, i)
_map_data[i][j] = value
end
end
_open_map[getKey(_start_point)] = _start_point
table.insert(_open_list, _start_point)
end

function createPoint(x, y)
local point = {
["x"] = x,
["y"] = y,
["last"] = nil,
["g_value"] = 0,
["h_value"] = 0,
["f_value"] = 0
}
point["key"] = getKey(point)
return point
end

-- 得到下一个可以移动的点
-- @param point 当前所在点
function getNextPoints(point)
local next_points = {}
for i = 1, #_deleget.directions do
local offset = _deleget.directions[i]
local next_point = createPoint(point.x + offset[1], point.y + offset[2])
next_point["last"] = point
if next_point.x >= 1 and next_point.x <= _deleget.width and next_point.y >= 1 and next_point.y <= _deleget.height then
next_point["g_value"] = _deleget.g(point, next_point)
next_point["h_value"] = _deleget.h(point, _dest_point)--math.abs(next_points.x - _dest_point.x) + math.abs(next_points.y - _dest_point.y)
next_point["f_value"] = next_point.g_value + next_point.h_value
table.insert(next_points, next_point)
end
end
return next_points
end

-- 得到路径
-- @param end_point 目标点
function makePath(end_point)
_path = {}
local point = end_point
while point.last ~= nil do
table.insert(_path, createPoint(point.x, point.y))
point = point.last
end
local start_point = point
table.insert(_path, start_point)
return _path
end

-- 两个点的代价比较器
function compareF(point1, point2)
return point1.f_value < point2.f_value
end

-- 是否是障碍物
function isObstacle(point)
local value = _map_data[point.y][point.x]
if value == 1 then
return true
end
return false
end

-- 两个点是否是同一个点
function isEqual(point1, point2)
return point1.key == point2.key
end

-- 根据点得到点的key
function getKey(point)
local key = string.format("%d,%d", point.x, point.y)
return key
end

下面是工具类PathUtil的用法
local deleget = {}
deleget.g = function(point1, point2)
return math.abs(point1.x - point2.x) + math.abs(point1.y - point2.y)
end
deleget.h = deleget.g
deleget.getValue = function(j, i)
local index = FindTreasureUtil.getIndex(j, i)
local map_info = _map_info.map[index]
if map_info.display == 0 and map_info.eid ~= 1 then
return 0
end
return 1
end
deleget.directions = {{-1, 0}, {0, -1}, {0, 1}, {1, 0}} -- 左,上,下,右
deleget.width = _cols
deleget.height = _rows

local dest_row, dest_col = FindTreasureUtil.getMapPosition(tag)
local dest_point = PathUtil.createPoint(dest_col, dest_row)
local start_row, start_col = FindTreasureUtil.getMapPosition(_player_index)
local start_point = PathUtil.createPoint(start_col, start_row)
_path = PathUtil.findPath(deleget, start_point, dest_point)

_path就是我们找到的路径,起点为最后一个元素,终点为第一个元素

‘柒’ a*寻路算法如果f值和h值都相等怎么取最优节点

首先,G值是从开始点到当前点的移动量,H值是从当前点到终点的移动估算量。既然F=G+H.如果F值和H值都相同,那么G值也是相同的,也就是说从开始点走了同样的距离,移动到两个不同的节点,而这两个节点距离重点的距离也是相同的。那就继续往下进行算法。如果继续下去之后,这两个节点还是一样的情况,那说明有两条最优路径,不然一定会有一个节点会被淘汰。

‘捌’ 按键精灵a星算法寻路怎么制作地图

你可以查找有关a星算法走路,一步步去学,别人也不知道你说的是什么地图,怎么判断

‘玖’ 有关A* 寻路算法。 看了这个算法 大致都明白。就是有点不大清楚。

1. B的G值是指从起点A开始,到达该点的最短距离,和B在不在最短路径上没有关系。

2. 不是遍历所有路径,而是所有点。对于m*n的矩阵, 遍历所有点的复杂度是m*n(多项式复杂度),而遍历所有路径的复杂度是4的(m*n)次幂(每个点都有4个可能的方向)。从幂指数复杂度降低到多项式复杂度,这就是A*算法的意义所在。

3. 最优路径是要从终点一步步倒退回来。比如终点的G值是k,那么最多需要4*k次查找,依然是多项式复杂度。但多数问题(对于纯算法题来说)只是需要知道到达终点的步骤,很少要你找出固定路径的。

‘拾’ 游戏中的常用的寻路算法有哪些

f(n)=g(n)+h(n) 从起始点到目的点的最佳评估值
– 每次都选择f(n)值最小的结点作为下一个结点,
直到最终达到目的结点
– A*算法的成功很大程度依赖于h(n)函数的构建
?;) = g(n? 在各种游戏中广泛应用 Open列表和Closed列表
– Open列表
A*算法
? h(n) = 从结点n到目的结点的耗费评估值,启发函数
?,程序返回n
else 生成结点n的每一个后继结点n;
foreach 结点n的后继结点n;{
将n’的父结点设置为n
计算启发式评估函数h(n‘)值,评估从n‘到node_goal的费用
计算g(n‘) = g(n) + 从n’到n的开销
计算f(n?? 在算法启动时,Closed列表为空 A* 算法伪代码初始化OPEN列表
初始化CLOSED列表
创建目的结点;称为node_goal
创建起始结点;称为node_start
将node_start添加到OPEN列表
while OPEN列表非空{
从OPEN列表中取出f(n)值最低的结点n
将结点n添加到CLOSED列表中
if 结点n与node_goal相等then 我们找到了路径;)
if n‘位于OPEN或者CLOSED列表and 现有f(n)较优then丢弃n’ ;) + h(n?? 包含我们还没有处理到的结点
? g(n) = 从初始结点到结点n的耗费
?? 包含我们已经处理过的结点
,处理后继n’
将结点n‘从OPEN和CLOSED中删除
添加结点n‘到OPEN列表
}
}
return failure (我们已经搜索了所有的结点?? 启发式搜索
– 在搜索中涉及到三个函数
??? 我们最开始将起始结点放入到Open列表中
– Closed列表
?

热点内容
c语言通用链表 发布:2025-05-13 19:53:04 浏览:805
lol挂机脚本后台 发布:2025-05-13 19:51:23 浏览:573
红米note3怎么锁屏密码忘了怎么办 发布:2025-05-13 19:51:03 浏览:191
sql数据库报表 发布:2025-05-13 19:49:56 浏览:519
c语言编程代码 发布:2025-05-13 19:48:17 浏览:704
安卓的AndroidAuto 发布:2025-05-13 19:41:49 浏览:358
下载安装python 发布:2025-05-13 19:39:21 浏览:28
苹果手机如何退出ad密码 发布:2025-05-13 19:35:24 浏览:353
资本论中央编译局 发布:2025-05-13 19:21:50 浏览:134
python路径是否存在 发布:2025-05-13 19:08:38 浏览:570