`
univasity
  • 浏览: 811598 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

A*寻路(J2ME实现)

    博客分类:
  • J2me
阅读更多

这是很久前另一个BLOG上的,现在不用了。转过来吧,方便查看...

 

找工作未果, 闲来无事,先学学一些感兴趣的算法和弄些小东西~~

 

参考文章:

http://blog.vckbase.com/panic/archive/2005/03/20/3778.html

写得真的非常棒,翻译得也很好,整个实现就是跟着他来的。

 

直接上代码,效率问题没有仔细研究过,我是每次寻路完毕都进行一次资源释放,进一步的优化可以继续参考以上连接作者BLOG的其他关于A*的文章。

 

/***
 * A*寻路
 * @author univasity
 * 2008-10-01 0:19
 * QQ:595920004
 */
public class PF_A_Start {
 
 /**构造函数*/
 public PF_A_Start(byte[][] map, byte[] blocks) {
  this.map = map;
  this.blocks = blocks;
 }

 /**
  * 根据指定的起始位置和目标寻路
  * @param sx 起始点X坐标
  * @param sy 起始点Y坐标
  * @param tx 目标点X坐标
  * @param ty 目标点Y坐标
  * @return 可行的路径,如果没有则返回空
  */
 public int[][] findPath(int sx, int sy, int tx, int ty){
  
  init();
  
  setFatherNode(sx, sy, sx, sy); // 起始点的父节点设置为自身
  value_G[sy][sx] = 0;
  value_H[sy][sx] = CalculationValueH(sx, sy, tx, ty);
  addToOpenList(sx, sy); // 把起始点加入开放列表
  
  while(num_open>0 && !(sucess = isInCloseList(tx, ty))){
   
   // 获取具有最小F值的节点,作为下一个移动目标
   int node1 = openList[0];
   int nx = node1%10;
   int ny = node1/10;
   for(int i=1; i<num_open-1; i++){
    int node2 = openList[i+1];
    int x2 = node2%10;
    int y2 = node2/10;
    if(ValueF(x2, y2)<ValueF(nx, ny)){
     nx = x2;
     ny = y2;
    }
   }
   
   // 把四周可到的节点加入开放列表,以待检测
   for(int i=0; i<8; i++){
    if(isBlock(nx+px[i], ny+py[i])) // 如果是障碍,跳过
     continue;
    if(isInCloseList(nx+px[i], ny+py[i])) // 如果已存在关闭列表中,跳过
     continue;
    if(isInOpenList(nx+px[i], ny+py[i])){ // 如果已存在开放列表中
     int fatherNode = FatherNode(nx+px[i], ny+py[i]);
     // 判断以当前节点为父节点,G值是否比原来小
     setFatherNode(nx+px[i], ny+py[i], nx, ny);
     if(CalculationValueG(nx+px[i], ny+py[i])<value_G[ny+py[i]][nx+px[i]]){ // 如果只是
      value_G[ny+py[i]][nx+px[i]] = CalculationValueG(nx+px[i], ny+py[i]); // 更新G值,令父节点为当前节点
     }else{ // 否则
      setFatherNode(nx+px[i], ny+py[i], fatherNode%10, fatherNode/10); // 恢复父节点为初始值
     }
    }else{ // 未被添加到开放列表
     // 设置父节点为当前节点,计算G值和H值,并添加到开放列表中
     setFatherNode(nx+px[i], ny+py[i], nx, ny);
     value_G[ny+py[i]][nx+px[i]] = CalculationValueG(nx+px[i], ny+py[i]);
     value_H[ny+py[i]][nx+px[i]] = CalculationValueH(nx+px[i], ny+py[i], tx, ty);
     addToOpenList(nx+px[i], ny+py[i]);
    }
   }
   // 从开放列表删除该节点
   deleteFromOpenList(nx, ny);
   // 添加到关闭列表
   addToCloseList(nx, ny);
  } // 搜索结束
  
  // 读取路径
  int[][] path = null;
  if(sucess){
   int[][] temp = new int[num_open][2];
   int index = num_open-1;
   int nx = tx;
   int ny = ty;
   while(nx!=sx || ny!=sy){
    int node = FatherNode(nx, ny);
    nx = node%10;
    ny = node/10;
    temp[index][0] = nx;
    temp[index][1] = ny;
    index--;
   }
   path = new int[num_open-index-1][2];
   System.arraycopy(temp, index+1, path, 0, path.length);
  }
  
  release();
  
  return path;
 }
 
 /**资源初始化*/
 private void init() {
  num_open = num_close = 0;
  openList = new int[map.length*map[0].length]; // 开放列表
  closeList = new int[map.length*map[0].length]; // 关闭列表
  fatherNode = new int[map.length][map[0].length]; // 父节点列表
  value_G = new int[map.length][map[0].length]; // G值表
  value_H = new int[map.length][map[0].length]; // H值表
 }
 
 /**释放资源*/
 private void release() {
  openList = null;
  closeList = null;
  for(int i=0; i<fatherNode.length; i++){
   fatherNode[i] = null;
  }
  fatherNode = null;
  for(int i=0; i<value_G.length; i++){
   value_G[i] = null;
  }
  value_G = null;
  for(int i=0; i<value_H.length; i++){
   value_H[i] = null;
  }
  value_H = null;
  System.gc();
 }

 /**添加到开放列表*/
 private int addToOpenList(int x, int y){
  return (openList[num_open++] = y*10+x);
 }
 
 /**添加到关闭列表*/
 private int addToCloseList(int x, int y){
  return (closeList[num_close++] = y*10+x);
 }
 
 /**从开放列表中删除*/
 private void deleteFromOpenList(int x, int y){
  if(num_open<=0)
   return;
  int i;
  for(i=0; i<num_open; i++){
   if(openList[i]==y*10+x){
    openList[i] = 0;
    break;
   }
  }
  for(; i<num_open-1; i++){
   openList[i] = openList[i+1];
  }
  num_open--;
 }
 
 /**获取F值*/
 private int ValueF(int x, int y){
  return value_G[y][x]+value_H[y][x];
 }
 
 /**获取父节点*/
 private int FatherNode(int x, int y){
  return fatherNode[y][x];
 }
 
 private void setFatherNode(int x, int y, int fx, int fy){
  fatherNode[y][x] = fy*10+fx;
 }
 
 /**是否已存在于开放列表*/
 private boolean isInOpenList(int x, int y){
  for(int i=0; i<num_open; i++){
   if(openList[i]==y*10+x)
    return true;
  }
  return false;
 }
 
 /**是否已存在于关闭列表*/
 private boolean isInCloseList(int x, int y){
  for(int i=0; i<num_close; i++){
   if(closeList[i]==y*10+x)
    return true;
  }
  return false;
 }
 
 /**计算G值*/
 private int CalculationValueG(int x, int y){
  int node = FatherNode(x, y);
  int fx = node%10;
  int fy = node/10;
  for(int i=0; i<4; i++){
   if(fx+px[4+i]==x && fy+py[4+i]==y)
    return value_G[fy][fx] + 14;
  }
  return value_G[fy][fx] + 10;
 }
 
 /**计算H值*/
 private int CalculationValueH(int x, int y, int tx, int ty){
  return (Math.abs(y-ty)+Math.abs(x-tx))*10;
 }
 
 /**判断是否是障碍*/
 private boolean isBlock(int x, int y){
  if(x<0 || x>=map[0].length || y<0 || y>=map.length)
   return true;
  if(blocks==null)
   return false;
  for(int i=0; i<blocks.length; i++){
   if(map[y][x]==blocks[i])
    return true;
  }
  return false;
 }
 
 // 四周8个方位的位置偏移量
 private static final byte[] px = {-1,1,0,0,-1,-1,1,1};
 private static final byte[] py = {0,0,-1,1,-1,1,-1,1};
 
 private byte[][] map; // 地图数据
 private byte[] blocks; // 障碍ID
 
 private int[] openList;// 开放列表
 private int[] closeList; // 关闭列表
 private int num_open, num_close; // 数量标记
 
 private int[][] fatherNode; // 父节点列表
 private int[][] value_G; // G值表
 private int[][] value_H; // H值表
 
 private boolean sucess;
}

分享到:
评论

相关推荐

    A*寻路算法(j2me版)

    在J2ME环境下实现A*寻路算法,需要关注以下几个关键点: 1. **数据结构**:通常使用二维数组或图表示地图,其中每个节点代表地图上的一个位置。节点存储其邻居信息以及上述提到的g值和h值。 2. **启发式函数**:...

    j2me版A*寻路算法

    总之,J2ME版A*寻路算法实现了在移动设备上寻找最短路径的功能,通过优化的数据结构和启发式方法,能够在资源有限的环境中高效地找到目标。理解并掌握这个算法的实现细节,对移动开发和游戏编程具有重要的实践价值。

    j2me版A星寻路算法

    3. **J2ME实现**: - **内存管理**:J2ME平台资源有限,因此需要优化数据结构以减少内存占用,可能采用紧凑的数据结构和节点表示。 - **性能优化**:可能通过减少计算量、使用位运算加速比较和更新操作,以及适时...

    j2me版本A*四向寻路算法

    A*四向寻路算法在J2ME中的实现意味着它只考虑了四个基本方向:上、下、左、右,而不是八向(包括对角线)寻路,这样可以减少计算复杂度,提高性能。 A*算法的核心在于其使用了启发式函数(通常为曼哈顿距离或...

    j2me中的A*算法

    `readme.txt`很可能是项目介绍和使用说明,而`j2me版A寻路算法`可能是源代码文件夹,其中可能包含了以下文件: - `PathFinder.java`: A*算法的实现类,包括节点管理、启发式函数计算、搜索逻辑等。 - `Node.java`: ...

    j2me A*算法

    在J2ME实现中,关键步骤包括: 1. **数据结构**:通常使用网格表示环境,每个节点代表地图上的一个位置,连接节点表示可以移动的路径。每个节点存储与其相邻的节点信息、代价g(n)和启发式值h(n)。 2. **开放列表和...

    j2me版A寻路算法

    在J2ME(Java 2 Micro Edition)平台上实现A*寻路算法,主要是因为J2ME是Java的一个轻量级版本,适用于移动设备和嵌入式系统。虽然资源有限,但J2ME平台依然能够处理复杂的算法,如A*,以支持游戏和其他需要路径规划...

    手机迷宫游戏

    解决迷宫的算法通常采用A*寻路算法或Dijkstra算法,它们能够在保证找到最短路径的同时,优化计算效率。 4. **游戏设计与交互** 在手机屏幕上实现迷宫游戏需要考虑触摸屏或按键的交互方式。玩家可能通过滑动屏幕或...

    初识A寻路算法

    标题中的“初识A*寻路算法”表明我们要探讨的是计算机科学中的一种路径搜索算法——A*(A-star)算法。...了解并掌握A*算法对于解决各种寻路问题具有重要意义,特别是在资源受限的环境中,如J2ME平台。

    J2ME_PopTang_By_Cpiz.rar_毕业设计 游戏_泡泡堂_泡泡堂 java

    这涉及到复杂的算法设计和实现,如A*寻路算法用于角色智能移动,四边形碰撞检测用于判断角色与环境或敌人的接触。 3. **事件处理**:游戏需要响应用户的输入,例如按键操作。开发者需要编写事件监听代码,将用户...

    java手机游戏文档教程

    6. **游戏设计与实现**:这部分可能包含了游戏设计原则,如游戏规则设计、关卡设计、用户体验优化,以及如何将这些设计理念转化为实际的代码实现。此外,文档可能还会讨论测试和调试技巧,确保游戏的质量。 总的来...

    java a星算法

    A星(A*)算法是一种在图形搜索中非常有效的路径查找算法,尤其适用于解决游戏中的寻路问题、地图导航等。在Java或J2ME环境中,A*算法同样可以被广泛运用,帮助程序找到两点间的最短路径。下面我们将深入探讨A星算法的...

    随机迷宫(源码)

    寻路算法如A*或Dijkstra算法可以帮助角色找到迷宫出口。 6. **资源管理**:包括图像、音频和数据文件的加载和释放,有效管理内存以适应有限的移动设备资源。 7. **状态管理**:游戏可能有多个状态(如开始、游戏进行...

    Java仙剑奇侠传源代码

    这通常涉及复杂的算法和数据结构,如状态机、寻路算法(如A*算法)和简单的AI策略。 6. **用户界面设计**:J2ME提供了一些UI组件,如Form、Displayable和Alert,用于创建游戏的菜单、对话框等界面。源代码将展示...

    15个j2me手机游戏项目源代码

    7. AI和物理模拟:简单的AI算法或碰撞检测,如A*寻路算法或Box2D轻量级物理引擎的实现。 8. 性能优化:由于移动设备资源有限,需要关注代码效率,避免内存泄漏,减少绘制开销。 三、学习方法与实践 1. 阅读源代码:...

    精华游戏算法整理.doc

    对于Java或J2ME游戏开发,实现A*算法时,可以选择使用C++或Blitz Basic的实现作为参考,根据游戏需求进行必要的调整。通常,算法实现不依赖于特定编程语言,因此可以轻松地移植到Java环境。 总结来说,A*算法是一种...

    J2ME 圆和矩形绘制的追逐游戏

    例如,敌人可以简单地朝着玩家的方向直线移动,或者使用更复杂的算法如A*寻路。而玩家在吃到食物后变大,可以调整其半径,使得敌人需要更接近才能触发碰撞,增加了游戏的挑战性。 在J2ME中实现这些功能时,需要注意...

    J2ME老鼠走迷宫智能AI

    "J2ME老鼠走迷宫智能AI"就是一个很好的例子,它展示了如何在小型设备上实现简单的寻路算法。本文将深入探讨这一主题,解析这个Java手机游戏中的路径搜索算法。 首先,我们来看标签中提到的关键技术——Java、人工...

    MicroTankMIDlet_2_Java游戏_java_

    6. 数据结构与算法:坦克大战涉及到物体碰撞检测、路径规划等,这些都需要高效的数据结构(如数组、队列)和算法(如Bresenham线画法、A*寻路算法)来实现。 7. 存储与资源管理:由于手机内存有限,J2ME游戏通常将...

    征途Java游戏

    例如,A*寻路算法、碰撞检测、物理模拟等。 8. **资源管理**:游戏中涉及的图片、音频、动画等资源需要有效管理和加载,Java提供了流式I/O来处理这些内容。 9. **性能优化**:对于J2ME平台,内存和CPU资源有限,...

Global site tag (gtag.js) - Google Analytics