`

AS3的A寻路代码,了解一下

F# 
阅读更多

地形数据不属于A*寻路的范围,这里定义一个 IMapTileModel 接口,由其它(模型)类来实现地图通路的判断。其它比如寻路超时的判断这里也不介绍,具体参考 AStar类及其测试代码。这里只介绍三部分主要内容:

* 数据存储
* 寻路过程
* 列表排序

数据存储
首先看看三个关键变量: 复制内容到剪贴板
代码:
private var m_openList : Array; //开放列表,存放节点ID
private var m_openCount : int; //当前开放列表中节点数量
private var m_openId : int; //节点加入开放列表时分配的唯一ID(从0开始)开放列表 m_openList 是个二叉堆(一维数组),F值最小的节点始终排在最前。为加快排序,开放列表中只存放节点ID ,其它数据放在各自的一维数组中: 复制内容到剪贴板
代码:
private var m_xList : Array; //节点x坐标
private var m_yList : Array; //节点y坐标
private var m_pathScoreList : Array; //节点路径评分F值
private var m_movementCostList : Array; //(从起点移动到)节点的移动耗费G值
private var m_fatherList : Array; //节点的父节点(ID)这些数据列表都以节点ID为索引顺序存储。看看代码如何工作: 复制内容到剪贴板
代码:
//每次取出开放列表最前面的ID
currId = this.m_openList[0];
//读取当前节点坐标
currNoteX = this.m_xList[currId];
currNoteY = this.m_yList[currId];还有一个很关键的变量:
private var m_noteMap : Array; //节点(数组)地图,根据节点坐标记录节点开启关闭状态和ID

使用 m_noteMap 可以方便的存取任何位置节点的开启关闭状态,并可取其ID进而存取其它数据。m_noteMap 是个三维数组,第一维y坐标(第几行),第二维x坐标(第几列),第三维节点状态和ID。判断点(p_x, p_y)是否在开启列表中: 复制内容到剪贴板
代码:
return this.m_noteMap[p_y][p_x][NOTE_OPEN];寻路过程
AStar类 寻路的方法是 find() : 复制内容到剪贴板
代码:
/**
* 开始寻路
* @param p_startX        起点X坐标
* @param p_startY        起点Y坐标
* @param p_endX        终点X坐标
* @param p_endY        终点Y坐标
* @return                 找到的路径(二维数组 : [p_startX, p_startY], ... , [p_endX, p_endY])
*/   
public function find(p_startX : int, p_startY : int, p_endX : int, p_endY : int) : Array{/* 寻路 */}注意这里返回数据的形式:从起点到终点的节点数组,其中每个节点为一维数组[x, y]的形式。为了加快速度,类里没有使用Object或是Point,节点坐标全部以数组形式存储。如节点note的x坐标为note[0],y坐标为note[1]。
下面开始寻路,第一步将起点添加到开启列表: 复制内容到剪贴板
代码:
this.openNote(p_startX, p_startY, 0, 0, 0);openNote() 方法将节点加入开放列表的同时分配一个唯一的ID、按此ID存储数据、对开启列表排序。接下来是寻路过程: 复制内容到剪贴板
代码:
while (this.m_openCount > 0)
{
//每次取出开放列表最前面的ID
currId = this.m_openList[0];
//将编码为此ID的元素列入关闭列表
this.closeNote(currId);
//如果终点被放入关闭列表寻路结束,返回路径
if (currNoteX == p_endX && currNoteY == p_endY)
       return this.getPath(p_startX, p_startY, currId);
//...每轮寻路过程
}
//开放列表已空,找不到路径
return null;每轮的寻路: 复制内容到剪贴板
代码:
//获取周围节点,排除不可通过和已在关闭列表中的
aroundNotes = this.getArounds(currNoteX, currNoteY);
//对于周围每个节点
for each (var note : Array in aroundNotes)
{
//计算F和G值
cost = this.m_movementCostList[currId] + (note[0] == currNoteX || note[1] == currNoteY) ? COST_STRAIGHT : COST_DIAGONAL;
score = cost + (Math.abs(p_endX - note[0]) + Math.abs(p_endY - note[1])) * COST_STRAIGHT;
if (this.isOpen(note[0], note[1])) //如果节点已在开启列表中
{
       //测试节点的ID
checkingId = this.m_noteMap[note[1]][note[0]][NOTE_ID];
//如果新的G值比节点原来的G值小,修改F,G值,换父节点
if(cost < this.m_movementCostList[checkingId])
{
       this.m_movementCostList[checkingId] = cost;
       this.m_pathScoreList[checkingId] = score;
       this.m_fatherList[checkingId] = currId;
       //对开启列表重新排序
       this.aheadNote(this.getIndex(checkingId));
}
} else //如果节点不在开放列表中
{
//将节点放入开放列表
this.openNote(note[0], note[1], score, cost, currId);
}
}从终点开始依次沿父节点回到到起点,返回找到的路径: 复制内容到剪贴板
代码:
/**
* 获取路径
* @param p_startX 起始点X坐标
* @param p_startY 起始点Y坐标
* @param p_id        终点的ID
* @return          路径坐标数组
*/   
private function getPath(p_startX : int, p_startY : int, p_id: int) : Array
{
var arr : Array = [];
var noteX : int = this.m_xList[p_id];
var noteY : int = this.m_yList[p_id];
while (noteX != p_startX || noteY != p_startY)
{
arr.unshift([noteX, noteY]);
p_id = this.m_fatherList[p_id];
noteX = this.m_xList[p_id];
noteY = this.m_yList[p_id];
}
arr.unshift([p_startX, p_startY]);
this.destroyLists();
return arr;
}列表排序
这部分看代码和注释就可以了,不多说: 复制内容到剪贴板
代码:
/** 将(新加入开放别表或修改了路径评分的)节点向前移动 */
private function aheadNote(p_index : int) : void
{
var father : int;
var change : int;
//如果节点不在列表最前
while(p_index > 1)
{
//父节点的位置
father = Math.floor(p_index / 2);
//如果该节点的F值小于父节点的F值则和父节点交换
if (this.getScore(p_index) < this.getScore(father))
{
       change = this.m_openList[p_index - 1];
       this.m_openList[p_index - 1] = this.m_openList[father - 1];
       this.m_openList[father - 1] = change;
       p_index = father;
} else
{
       break;
}
}
}
/** 将(取出开启列表中路径评分最低的节点后从队尾移到最前的)节点向后移动 */
private function backNote() : void
{
//尾部的节点被移到最前面
var checkIndex : int = 1;
var tmp : int;
var change : int;
while(true)
{
tmp = checkIndex;
//如果有子节点
if (2 * tmp <= this.m_openCount)
{
       //如果子节点的F值更小
       if(this.getScore(checkIndex) > this.getScore(2 * tmp))
       {
       //记节点的新位置为子节点位置
       checkIndex = 2 * tmp;
       }
       //如果有两个子节点
       if (2 * tmp + 1 <= this.m_openCount)
       {
       //如果第二个子节点F值更小
       if(this.getScore(checkIndex) > this.getScore(2 * tmp + 1))
       {
         //更新节点新位置为第二个子节点位置
         checkIndex = 2 * tmp + 1;
       }
       }
}
//如果节点位置没有更新结束排序
if (tmp == checkIndex)
{
       break;
}
//反之和新位置交换,继续和新位置的子节点比较F值
else
{
       change = this.m_openList[tmp - 1];
       this.m_openList[tmp - 1] = this.m_openList[checkIndex - 1];
       this.m_openList[checkIndex - 1] = change;
}
}
}其中 getScore() 方法: 复制内容到剪贴板
代码:
/**
* 获取某节点的路径评分F值
* @param p_index 节点在开启列表中的索引(从1开始)
*/   
private function getScore(p_index : int) : int
{
//开启列表索引从1开始,ID从0开始,数组索引从0开始
return this.m_pathScoreList[this.m_openList[p_index - 1]];
}

 

 

 

 

 

 

 

//别人写得很细节

//我的简单实现方法

 

 

1.生成地图表

 

2.循环检查角色每一步,并作出每一步的优先级别,再分别检查地图表是否可行.

 

附代码

 

   var direct:String="cc";
   //角色的方向
   if(gx<ox){lcr="l";}else if(gx==ox){lcr="c";}else{lcr="r";}
   if(gy<oy){tcd="t";}else if(gy==oy){tcd="c";}else{tcd="d";}
   direct=lcr+""+tcd
   //trace(direct)
   //移動優先級
   switch(direct){
    case "lt" : rl=[[-1,-1],[-1,0],[0,-1],[-1,1],[1,-1],[1,0],[0,1],[1,1]]; break;
    case "lc" : rl=[[-1,0],[-1,-1],[-1,1],[0,-1],[0,1],[1,-1],[1,1],[1,0]]; break;
    case "ld" : rl=[[-1,1],[-1,0],[0,1],[-1,-1],[1,1],[0,-1],[1,0],[1,-1]]; break;
    case "ct" : rl=[[0,-1],[-1,-1],[1,-1],[-1,0],[1,0],[-1,1],[1,1],[0,1]]; break;
    case "cc" : rl=[]; break;
    case "cd" : rl=[[0,1],[-1,1],[1,1],[-1,0],[1,0],[-1,-1],[1,-1],[0,-1]]; break;
    case "rt" : rl=[[1,-1],[0,-1],[1,0],[-1,-1],[1,1],[-1,0],[0,1],[-1,1]]; break;
    case "rc" : rl=[[1,0],[1,-1],[1,1],[0,-1],[0,1],[-1,-1],[-1,1],[-1,0]]; break;
    case "rd" : rl=[[1,1],[1,0],[0,1],[1,-1],[-1,1],[0,-1],[-1,0],[-1,-1]]; break;
   }

 

   if(trole.direct!=direct){
    trole.direct=direct
    trole.getChildAt(1).gotoAndStop("run_"+direct)
   }
   if(rl.length==0){
    //完成了
    trole.getChildAt(1).gotoAndStop(trole.direct)
    //nowmp.cb(nowmp.tid,nowmp.name)  //<<<<  nowmp.name
    return;
   }
   //計算下一步移動的XY,遇到block就下一个
   for(var i=0;i<rl.length;i++){
    rnx=rox-rl[i][0]
    rny=roy-rl[i][1]
    if(typeof main.m_mapb.block["x"+rnx+"y"+rny]=="undefined"){
     break;
    }
   }
   trole.x=rnx*10
   trole.y=rny*10

 

 

 

 

 

 

 

 

 

分享到:
评论

相关推荐

    as3 寻路源代码

    总之,A*算法是寻路问题的强大工具,而在AS3中实现这一算法,可以帮助开发者创建高效的游戏逻辑和动态路径规划。通过深入研究提供的源代码,不仅可以学习到A*算法的工作原理,还能提升AS3编程技巧,对游戏开发和其他...

    flex as3游戏寻路源码+详解

    本资源包“flex as3游戏寻路源码+详解”聚焦于使用Adobe Flex和ActionScript 3(AS3)实现游戏中的路径寻找功能。Flex是一种基于开放源代码的、用于构建富互联网应用(RIA)的开发框架,而AS3是Flash平台上广泛使用...

    AS3 A星算法以及实例

    描述中提到这是一个包含源文件和源代码的实际例子,这为我们提供了学习和理解A星算法在AS3中的具体应用提供了宝贵的资源。通过查看和运行这些源代码,我们可以深入理解算法的内部工作原理,以及如何在实际项目中有效...

    flash actionscript3游戏开发之 as3斜45度可移动物品可AStar寻路算法.rar

    本压缩包提供的资源着重于AS3中如何实现这些功能,特别是A*(A-Star)寻路算法的应用。 ActionScript3是Adobe Flash平台的主要编程语言,它支持面向对象编程,提供了强大的性能和灵活性,是制作互动内容和游戏的...

    A*寻路算法

    A*寻路算法是一种在图形或网格环境中寻找最短路径的经典算法,被广泛应用于游戏开发、地图导航等领域。...在提供的`Astar.as`和`Game.as`文件中,我们可以深入研究这些概念,了解具体的代码实现细节。

    actionscript RPG 寻路算法游戏源码

    首先,让我们了解ActionScript 3.0(AS3)。AS3是ActionScript的最新版本,它引入了许多改进,如面向对象编程的支持、更强大的类型系统以及更高效的性能。在游戏开发中,AS3提供了一个强大且灵活的平台,可以创建...

    AS3 AStar优化版.rar

    AS3 AStar优化版是一个基于ActionScript 3(AS3)的A*寻路算法的改进版本。A*算法是一种广泛应用在游戏开发、路径规划、网络路由等领域中的搜索算法,它能够有效地找到两点间的最短路径,同时兼顾了效率和准确性。在...

    AS3游戏实战(有源码)

    AS3游戏实战(有源码)是针对Adobe Flash平台中ActionScript 3.0(AS3)编程语言的游戏开发教程,特别关注高级应用和自动寻路算法。在这款游戏中,开发者利用AS3的强大功能实现了一个高效的角色移动系统,使得人物能够...

    TDS 基于flash(as3)开发的塔防游戏【源码】

    AS3可以利用图形库或自定义算法绘制路径,如A*寻路算法,确保敌人能够准确地沿设定路线行进。 2. **敌人生成**:敌人以一定的频率和数量出现,源码会包含一个定时器(Timer类)来控制生成节奏,以及敌人的状态机...

    as3(cs5) 植物大战僵尸源码可运行

    通过对源码的深入研究,不仅可以了解游戏开发的基本流程,还能掌握AS3编程的各种技术细节,对于提升自身的编程技能和创新能力具有极大的价值。如果你对这个游戏或AS3编程有兴趣,不妨下载这个源码,亲自探索其中的...

    Flash版本在线五子棋游戏,使用PHP+AS3.0开发,代码注释比较完善.zip

    对于游戏开发,还需要熟悉游戏设计原则和算法,如A*寻路算法或五子棋的AI策略。 标签“flash 动画 游戏”表明该项目不仅涉及基础的动画制作,还涵盖了游戏开发的各个方面。动画在Flash中通常通过关键帧和补间动画来...

    塔防游戏程序(as3.0源码)

    通过深入研究这个塔防游戏的AS3.0源码,初学者不仅可以掌握基本的游戏编程概念,还能了解到面向对象编程和A*寻路算法的实际应用,对于提升编程技能和理解游戏开发流程大有裨益。同时,通过对`library.swf`和`catalog...

    ai.zip_as3.0_flex

    在Astar.fla中,开发者可能使用Flash的图形工具绘制了游戏地图或其他可视化的界面元素,并将AS3.0代码嵌入到时间轴上,或者链接到外部的AS3类库。 3. **Astar.html**:这是一个HTML文件,通常用来嵌入生成的Astar....

    Advanced+AS3.0+Animation高级动画编程+源文件+中英文PDF.rar

    5. **算法详解**:教程中可能会详细讲解各种算法,如寻路算法(A*)、物理引擎算法、碰撞检测算法等。这些算法在游戏场景中的应用能提升游戏的趣味性和挑战性。 6. **源代码分析**:通过阅读和分析提供的源代码,...

    坦克大战(移植了最早任天堂游戏)

    AS3相比其前身AS2有更严格的类型系统和面向对象的特性,这使得代码更加健壮和可维护。游戏的核心是逻辑控制,AS3提供了丰富的事件处理和时间管理功能,这对于游戏循环和用户交互至关重要。 游戏共设有20个关卡,这...

    Flash ActionScript 3.0 动画高级教程 源码

    在AS3.0中实现A*算法,可以帮助创建具有智能行为的角色,如自动寻路的敌人或玩家。A*算法通过评估每个节点的代价,找到从起点到终点的最短路径,同时考虑到障碍物和其他限制。 书中提供的源码可能涵盖了以下主题: ...

    flash 3d塔防源码

    这部分源码会包含敌人的移动逻辑、路径查找算法,例如A*寻路算法的应用。 通过对这款Flash 3D塔防源码的深入学习,你可以了解并掌握上述各个技术点,从而有能力开发出属于自己的塔防游戏或其他类型的游戏。同时,...

    Foundation_Game_Design_with_Flash_code

    7. **游戏逻辑与算法**:游戏规则的实现往往涉及各种算法,如寻路算法(A*算法)、碰撞检测算法、状态机设计等。这些算法的掌握能让你编写出更加高效和智能的游戏。 8. **网络通信**:随着在线游戏的流行,...

    flash迷宫源码下载

    碰撞检测确保玩家只能在空格(即通道)上移动,而路径寻找算法(如A*寻路算法)则用于帮助玩家找到从起点到终点的最佳路径。这些功能的实现都依赖于ActionScript的事件驱动模型和面向对象编程特性。 在学习Flash...

    24层魔塔游戏flash源码下载

    如,A*寻路算法用于角色自动寻路,动态规划或贪心算法用于解决最优装备组合问题。 4. **图形与动画**:Flash提供了丰富的图形和动画工具,开发者可以通过ActionScript控制元件的显示和动画效果,创建出丰富多彩的...

Global site tag (gtag.js) - Google Analytics