- 浏览: 5819626 次
- 性别:
- 来自: 上海
文章分类
- 全部博客 (890)
- WindowsPhone (0)
- android (88)
- android快速迭代 (17)
- android基础 (34)
- android进阶 (172)
- android高级 (0)
- android拾遗 (85)
- android动画&效果 (68)
- Material Design (13)
- LUA (5)
- j2me (32)
- jQuery (39)
- spring (26)
- hibernate (20)
- struts (26)
- tomcat (9)
- javascript+css+html (62)
- jsp+servlet+javabean (14)
- java (37)
- velocity+FCKeditor (13)
- linux+批处理 (9)
- mysql (19)
- MyEclipse (9)
- ajax (7)
- wap (8)
- j2ee+apache (24)
- 其他 (13)
- phonegap (35)
最新评论
-
Memories_NC:
本地lua脚本终于执行成功了,虽然不是通过redis
java中调用lua脚本语言1 -
ZHOU452840622:
大神://处理返回的接收状态 这个好像没有监听到 遇 ...
android 发送短信的两种方式 -
PXY:
拦截部分地址,怎么写的for(int i=0;i<lis ...
判断是否登录的拦截器SessionFilter -
maotou1988:
Android控件之带清空按钮(功能)的AutoComplet ...
自定义AutoCompleteTextView -
yangmaolinpl:
希望有表例子更好。。。,不过也看明白了。
浅谈onInterceptTouchEvent、onTouchEvent与onTouch
import javax.microedition.midlet.*; import javax.microedition.lcdui.*; import java.lang.Thread; public class MainMid extends MIDlet { MainPit myScreen; boolean first = true; public MainMid() { myScreen = new MainPit(this); } protected void destroyApp(boolean unconditional) { } protected void pauseApp() { } protected void startApp()// J2ME程序的执行线程,自动执行响应按键。 { Display.getDisplay(this).setCurrent(myScreen);// myScreen获得当前屏幕的显示权 if (first)// 限定执行线程只执行一次 { try { Thread myThread = new Thread(myScreen);// 开启一个线程用来实现游戏的逻辑与绘制 myThread.start();// 打开线程 } catch (Error e) { destroyApp(false); notifyDestroyed(); } first = false; } } // 游戏结束 public void exit()// 关闭执行线程,整体程序退出 { destroyApp(true); notifyDestroyed(); } }
import java.lang.*; import javax.microedition.lcdui.*; import java.util.Random; import javax.microedition.rms.*; import java.io.*; class MainPit extends Canvas implements Runnable { MainMid myMid; // 按键表 private static final byte KEY_NONE = 0; private static final byte KEY_UP = -1; private static final byte KEY_DOWN = -2; private static final byte KEY_LEFT = -3; private static final byte KEY_RIGHT = -4; private static final byte KEY_FIRE = -5; private static final byte KEY_GAM_LEFT = -6; private static final byte KEY_GAM_RIGHT = -7; private static final byte KEY_NUM5 = 53; private int hangfire = 300;// 延时大小 Graphics gb; private Image bufImg;// 缓存 // 屏幕大小 private int nWidth; private int nHeight; public MainPit(MainMid mid) { myMid = mid; nWidth = getWidth();// 屏幕大小 nHeight = nWidth;// getHeight(); cw = nWidth / mWidth;//列 ch = nHeight / mHeight;//行 try { bufImg = Image.createImage(nWidth, nHeight);// 申请缓存空间 gb = bufImg.getGraphics(); } catch (Exception e) { } } public void paint(Graphics g) { g.setColor(0); g.fillRect(0, 0, nWidth, getHeight()); g.drawImage(bufImg, 0, 0, 0); g.setColor(0xff00); g.drawString("" + ttime, 0, getHeight(), 36); } private void showBegin() { gb.setColor(0x0000ff00); gb.fillArc(begin_x * cw, begin_y * ch, cw, ch, 0, 360); } int state = 0; public void run() { while (true) { switch (state) { case 0: showMap(); showCursor(); break; case 1: showMap(); showBegin(); showCursor(); break; case 2: showMap(); showBegin(); showfather(end_x, end_y); showCursor(); break; } repaint(); serviceRepaints(); try { Thread.sleep(hangfire); System.gc(); Thread.yield(); } catch (Exception e) { } } } private int cx=10, cy=0; private void showCursor() { gb.setColor(0x000000ff); gb.drawRect(cx * cw + 2, cy * ch + 2, cw - 4, ch - 4); } private int cw, ch; private void showMap() { clearScreen(0x00ffffff); for (int i = 0; i < mHeight; i++) { for (int j = 0; j < mWidth; j++) { switch (moveSpace[i][j]) { case 1: gb.setColor(0x00000000); gb.drawRect(j * cw, i * ch, cw, ch); break; case 2: gb.setColor(0x00ffff00); gb.fillRect(j * cw, i * ch, cw, ch); break; case 8: gb.setColor(0x00cccccc); gb.fillRect(j * cw, i * ch, cw, ch); break; case 9: gb.setColor(0x00000000); gb.fillRect(j * cw, i * ch, cw, ch); break; default: break; } } } } private void clearScreen(int c)// 用颜色c刷新屏幕 { gb.setColor(c); gb.fillRect(0, 0, nWidth, nHeight); } public void keyPressed(int keyCode) { switch (keyCode) { case KEY_UP: case 50: if (cy > 0) cy--; break; case 56: case KEY_DOWN: if (cy < mHeight - 1) cy++; break; case 52: case KEY_LEFT: if (cx > 0) cx--; break; case 54: case KEY_RIGHT: if (cx < mWidth - 1) cx++; break; case KEY_FIRE: case KEY_GAM_LEFT: case KEY_NUM5: switch (state) { case 0: begin_x = cx; begin_y = cy; state = 1; break; case 1: end_x = cx; end_y = cy; ttime = System.currentTimeMillis(); AAsterisk(begin_x, begin_y, end_x, end_y); ttime = System.currentTimeMillis() - ttime; state = 2; break; case 2: state = 0; break; } break; case KEY_GAM_RIGHT: myMid.exit(); break; } } long ttime; private int begin_x = 0; private int begin_y = 9; private int end_x = 0; private int end_y = 0; public int mWidth = 20, mHeight = 20; private int moveSpace[][] = { { 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, { 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, { 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, { 1, 8, 9, 9, 9, 9, 9, 9, 1, 1, 1, 1, 9, 9, 9, 9, 9, 9, 1, 1 }, { 1, 9, 8, 1, 1, 1, 1, 9, 1, 1, 1, 9, 1, 1, 1, 1, 1, 9, 1, 1 }, { 1, 9, 1, 1, 9, 9, 1, 9, 1, 1, 1, 9, 1, 1, 9, 9, 1, 9, 1, 1 }, { 9, 9, 9, 1, 9, 1, 1, 9, 1, 1, 9, 9, 9, 1, 9, 1, 1, 9, 1, 1 }, { 1, 1, 9, 1, 9, 9, 9, 9, 1, 1, 1, 1, 9, 1, 9, 9, 9, 9, 1, 1 }, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, { 1, 1, 9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 1, 1, 1, 1, 1, 1, 1 }, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 1, 2, 2, 2, 2, 2, 2, 2 }, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1 }, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, { 1, 1, 9, 9, 9, 9, 9, 9, 1, 2, 1, 1, 9, 9, 9, 9, 9, 9, 1, 1 }, { 1, 9, 1, 1, 1, 1, 1, 9, 1, 2, 2, 9, 1, 1, 1, 1, 1, 9, 1, 1 }, { 1, 9, 1, 1, 9, 9, 1, 9, 1, 1, 1, 9, 1, 1, 9, 9, 1, 9, 1, 1 }, { 9, 9, 9, 1, 9, 1, 1, 9, 1, 2, 9, 9, 9, 1, 9, 1, 1, 9, 1, 1 }, { 1, 1, 9, 1, 9, 9, 9, 9, 1, 2, 1, 1, 9, 1, 9, 9, 9, 9, 1, 1 }, { 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, { 1, 1, 9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 1, 1, 1, 1, 1, 1, 1 } }; private int openListLength = 0; private int closeListLength = 0; // “关闭列表”,列表中保存所有不需要再次检查的方格。 private boolean closeList[][]; private void addInCloseList(int x, int y) { closeList[y][x] = true; closeListLength++; } /* * 开启列表就像一张购物清单。 你的路径可能会通过它包含的方格,也可能不会。 基本上,这是一个待检查方格的列表。 */ private int[][][] openList; private void addInOpenList(int x, int y) { openList[y][x][0] = 1; openListLength++; } private void removeFromOpenList(int x, int y) { openList[y][x][0] = 0; openListLength--; } private boolean isBalk(int x, int y) { if (x < 0 || x >= mWidth || y < 0 || y >= mHeight) { return true; } if (closeList[y][x])//不需要再次检查的方格 return true; switch (moveSpace[y][x]) {//所有障碍物 case 8: case 9: return true; } return false; } // 设置父节点,f:0本身,1,上,2,下,3 左,4,右 private void setFather(int x, int y, int f) { openList[y][x][4] = f; } private void getGHF(int x, int y, int tx, int ty) { openList[y][x][1] = getG(x, y); openList[y][x][2] = getH(x, y, tx, ty); openList[y][x][3] = openList[y][x][1] + openList[y][x][3]; } // * G = 从起点A,沿着产生的路径,移动到网格上指定方格的移动耗费。 // 父节点的G+自身耗费 private int getG(int x, int y) { switch (openList[y][x][4]) { default: return moveSpace[y][x]; case 1: return openList[y - 1][x][1] + moveSpace[y][x]; case 2: return openList[y + 1][x][1] + moveSpace[y][x]; case 3: return openList[y][x - 1][1] + moveSpace[y][x]; case 4: return openList[y][x + 1][1] + moveSpace[y][x]; } } // * H = 从网格上那个方格移动到终点B的预估移动耗费。 // 这经常被称为启发式的,可能会让你有点迷惑。这样叫的原因是因为它只是个猜测。 // H值可以用不同的方法估算。 // 我们这里使用的方法被称为曼哈顿方法, // 它计算从当前格到目的格之间水平和垂直的方格的数量总和,忽略对角线方向。 private int getH(int x, int y, int tx, int ty) { return Math.abs(x - tx) + Math.abs(y - ty); } private void AAsterisk_t(int ttx, int tty, int tx, int ty) { /* * 把目标格添加进了开启列表,这时候路径被找到,或者 没有找到目标格,开启列表已经空了。这时候,路径不存在。 */ if ((ttx == tx && tty == ty) || openListLength == 0) return; // 4,把它从开启列表中删除,然后添加到关闭列表中。 removeFromOpenList(ttx, tty); addInCloseList(ttx, tty); /* * 5,检查所有相邻格子。 跳过那些已经在关闭列表中的或者不可通过的 (有墙,水的地形,或者其他无法通过的地形), * 把他们添加进开启列表,如果他们还不在里面的话。 把选中的方格作为新的方格的父节点。 */ if (!isBalk(ttx + 1, tty)) { if (openList[tty][ttx + 1][0] == 0) { addInOpenList(ttx + 1, tty); setFather(ttx + 1, tty, 3); getGHF(ttx + 1, tty, tx, ty); } else /* * 如果某个相邻格已经在开启列表里了, 检查现在的这条路径是否更好。 换句话说,检查如果我们用新的路径到达它的话, * G值是否会更低一些。如果不是,那就什么都不做。 另一方面,如果新的G值更低, 那就把相邻方格的父节点改为目前选中的方格 */ if (openList[tty][ttx + 1][0] == 1) { if (openList[tty][ttx][1] + moveSpace[tty][ttx + 1] < openList[tty][ttx + 1][1]) { setFather(ttx + 1, tty, 3); getGHF(ttx + 1, tty, tx, ty); } } } if (!isBalk(ttx - 1, tty)) { if (openList[tty][ttx - 1][0] == 0) { addInOpenList(ttx - 1, tty); setFather(ttx - 1, tty, 4); getGHF(ttx - 1, tty, tx, ty); } else /* * 如果某个相邻格已经在开启列表里了, 检查现在的这条路径是否更好。 换句话说,检查如果我们用新的路径到达它的话, * G值是否会更低一些。如果不是,那就什么都不做。 另一方面,如果新的G值更低, 那就把相邻方格的父节点改为目前选中的方格 */ if (openList[tty][ttx - 1][0] == 1) { if (openList[tty][ttx][1] + moveSpace[tty][ttx - 1] < openList[tty][ttx - 1][1]) { setFather(ttx - 1, tty, 4); getGHF(ttx - 1, tty, tx, ty); } } } if (!isBalk(ttx, tty + 1)) { if (openList[tty + 1][ttx][0] == 0) { addInOpenList(ttx, tty + 1); setFather(ttx, tty + 1, 1); getGHF(ttx, tty + 1, tx, ty); } else /* * 如果某个相邻格已经在开启列表里了, 检查现在的这条路径是否更好。 换句话说,检查如果我们用新的路径到达它的话, * G值是否会更低一些。如果不是,那就什么都不做。 另一方面,如果新的G值更低, 那就把相邻方格的父节点改为目前选中的方格 */ if (openList[tty + 1][ttx][0] == 1) { if (openList[tty][ttx][1] + moveSpace[tty + 1][ttx] < openList[tty + 1][ttx][1]) { setFather(ttx, tty + 1, 1); getGHF(ttx, tty + 1, tx, ty); } } } if (!isBalk(ttx, tty - 1)) { if (openList[tty - 1][ttx][0] == 0) { addInOpenList(ttx, tty - 1); setFather(ttx, tty - 1, 2); getGHF(ttx, tty - 1, tx, ty); } else /* * 如果某个相邻格已经在开启列表里了, 检查现在的这条路径是否更好。 换句话说,检查如果我们用新的路径到达它的话, * G值是否会更低一些。如果不是,那就什么都不做。 另一方面,如果新的G值更低, 那就把相邻方格的父节点改为目前选中的方格 */ if (openList[tty - 1][ttx][0] == 1) { if (openList[tty][ttx][1] + moveSpace[tty - 1][ttx] < openList[tty - 1][ttx][1]) { setFather(ttx, tty - 1, 2); getGHF(ttx, tty - 1, tx, ty); } } } // 从开启列表中选择F值最低的方格。 int bx = ttx, by = tty, minf = 255; for (int i = 0; i < mHeight; i++) { for (int j = 0; j < mWidth; j++) { if (openList[i][j][0] == 1) { if (minf > openList[i][j][3]) { minf = openList[i][j][3]; bx = j; by = i; } } } } AAsterisk_t(bx, by, tx, ty); } public void pause(long l) { try { Thread.sleep(l); System.gc(); Thread.yield(); } catch (Exception e) { } } /** * 核心算法 * @param bx * @param by * @param tx * @param ty */ private void AAsterisk(int bx, int by, int tx, int ty) { closeList = null; openList = null; closeList = new boolean[mHeight][mWidth]; openList = new int[mHeight][mWidth][5]; closeListLength = 0; openListLength = 0; for (int i = 0; i < mHeight; i++) { for (int j = 0; j < mWidth; j++) { // 加入标志 openList[i][j][0] = 0; // * G = 从起点A,沿着产生的路径,移动到网格上指定方格的移动耗费。 openList[i][j][1] = moveSpace[i][j]; // * H = 从网格上那个方格移动到终点B的预估移动耗费。 // 这经常被称为启发式的,可能会让你有点迷惑。这样叫的原因是因为它只是个猜测。 // H值可以用不同的方法估算。 // 我们这里使用的方法被称为曼哈顿方法, // 它计算从当前格到目的格之间水平和垂直的方格的数量总和,忽略对角线方向。 openList[i][j][2] = Math.abs(i - ty) + Math.abs(j - tx); // F = G+H openList[i][j][3] = openList[i][j][1] + openList[i][j][2]; // 父节点,记录方向 openList[i][j][4] = 0; } } /* * 1,从点A开始,并且把它作为待处理点存入一个“开启列表”。 开启列表就像一张购物清单。 尽管现在列表里只有一个元素,但以后就会多起来。 * 你的路径可能会通过它包含的方格,也可能不会。 基本上,这是一个待检查方格的列表。 */ addInOpenList(bx, by); /* * * 2,寻找起点周围所有可到达或者可通过的方格,跳过有墙,水,或其他无法通过地形的方格。 也把他们加入开启列表。 * 为所有这些方格保存点A作为“父方格”。 当我们想描述路径的时候,父方格的资料是十分重要的。 后面会解释它的具体用途。 */ if (!isBalk(bx + 1, by)) {//往右检查障碍物等,如果不是障碍物 addInOpenList(bx + 1, by);//加入OpenList setFather(bx + 1, by, 3);//记录方向 getGHF(bx + 1, by, tx, ty); } if (!isBalk(bx - 1, by)) { addInOpenList(bx - 1, by); setFather(bx - 1, by, 4); getGHF(bx - 1, by, tx, ty); } if (!isBalk(bx, by + 1)) { addInOpenList(bx, by + 1); setFather(bx, by + 1, 1); getGHF(bx, by + 1, tx, ty); } if (!isBalk(bx, by - 1)) { addInOpenList(bx, by - 1); setFather(bx, by - 1, 2); getGHF(bx, by - 1, tx, ty); } // 3,从开启列表中删除点A,把它加入到一个“关闭列表” removeFromOpenList(bx, by); addInCloseList(bx, by); // 从开启列表中选择F值最低的方格。 int ttx = bx, tty = by, minf = 255; for (int i = 0; i < mHeight; i++) { for (int j = 0; j < mWidth; j++) { if (openList[i][j][0] == 1) { if (minf > openList[i][j][3]) { minf = openList[i][j][3]; ttx = j; tty = i; } } } } AAsterisk_t(ttx, tty, tx, ty); } public void showOpenList() { for (int i = 0; i < mHeight; i++) { for (int j = 0; j < mWidth; j++) { System.out.print("(" + openList[i][j][0] + "," + openList[i][j][1] + "," + openList[i][j][2] + "," + openList[i][j][3] + "," + openList[i][j][4] + ")"); } System.out.println(); } } public void showCloseList() { for (int i = 0; i < mHeight; i++) { for (int j = 0; j < mWidth; j++) { System.out.print("(" + closeList[i][j] + ")"); } System.out.println(); } } protected void showfather(int x, int y) { if (x == begin_x && y == begin_y) { //搜索结束 return; } gb.setColor(0x00ff0000); gb.fillArc(x * cw, y * ch, cw, ch, 0, 360); switch (openList[y][x][4]) { case 1: showfather(x, y - 1); break; case 2: showfather(x, y + 1); break; case 3: showfather(x - 1, y); break; case 4: showfather(x + 1, y); break; default: break; } } }
[翻译]A*寻路初探
http://blog.vckbase.com/panic/archive/2005/03/20/3778.html
- A寻路算法J2ME版本实现.rar (4.8 KB)
- 下载次数: 6
发表评论
-
3个RPG练习,最后一个是卡马克卷轴
2010-12-11 18:02 2361import javax.microedition.lcd ... -
j2me小练习,教学用
2010-12-07 20:42 1844有用的J2ME功能函数 ... -
自己早期做的一个基于j2me的飞行射击类游戏
2010-12-07 20:23 2129早期的代码,MVC思想 -
自己早期做的一个基于j2me的魔塔
2010-12-07 20:13 2102上面一个不完整,但代码好(MVC),但没抽出类; 下面一个比 ... -
j2me代理连接返回码总是400的问题
2010-09-21 16:24 2768400是因为错误的语法导致服务器无法理解请求信息。 Con ... -
当显示内容过多时的滚屏类Container.java
2010-09-16 11:32 2168很多时候,由于手机屏幕太小,一下子显示不了那么多内容,这个时候 ... -
j2me读取中文的配置文件
2010-09-14 20:25 2166还可以参考这篇文章: http://gundumw100.it ... -
使用jsr172解析xml
2010-09-14 10:40 1962基类: import java.io.ByteArrayI ... -
面向对象的RMS操作
2010-09-14 10:29 1714将需要保存的数据集中起来形成一个model类,并且要实现序列化 ... -
Java版数独算法实现
2010-09-10 16:32 16360数独的历史: 数独前身为“九宫格”,最早起源于中国。数千 ... -
使用KXML解析xml数据
2010-09-10 13:05 9334最近做项目,服务器传过来的都是Xml格式的数据,需要解析xml ... -
类似小球列表的选择控件(9宫格)
2010-08-27 15:50 1762import javax.microedition.lcd ... -
j2me工具类:TextUtil.java
2010-08-11 21:24 1710import java.util.Vector; i ... -
j2me工具类:Database.java
2010-08-11 21:18 2022/** * <p>Title: & ... -
j2me工具类:ReadFromFile.java
2010-08-11 21:15 4340import java.io.*; import jav ... -
j2me竖向滚动菜单的基本做法
2010-08-11 16:58 2031public class AppCanvas extend ... -
j2me工具类:声音播放类SoundUtil
2010-06-04 23:21 2134用法: 将需要播放的音乐都罗列在name,type数组中,需要 ... -
j2me工具类:PalettedImage调色板类
2010-06-04 22:57 1807该方法网上可以找到,我添加了一个重载函数: public Im ... -
地图编辑器Mappy下载
2010-05-25 22:30 3330简单的手机游戏地图编辑器,共享之。。。 eclipseme下 ... -
将Image对像转换为png格式的byte数组
2010-04-15 12:48 2626原理上说 1 获取Image 的ARGB数据 2将ARGB ...
相关推荐
在J2ME环境中实现A*算法,需要关注以下关键点: 1. **数据结构**:首先,你需要一个数据结构来存储地图或网格,这通常是一个二维数组或者一个邻接列表。此外,还需要一个开放列表(未完全探索的节点集合)和一个...
在这个特定的场景中,我们讨论的是A*算法的一个J2ME(Java Micro Edition)版本,这表明该算法已经被优化以适应移动设备和嵌入式系统的资源限制。 J2ME是Java平台的一个子集,主要用于开发运行在移动设备和嵌入式...
A*(A-star)算法是一种在图形搜索中用于找到两点之间最短路径的启发式搜索算法。在J2ME(Java Micro Edition...通过理解A*算法的工作原理和在J2ME中的实现细节,开发者可以灵活地调整和优化算法以适应不同的场景需求。
在J2ME环境中,A*算法常用于移动设备的游戏开发,如迷宫求解或角色的路径规划。`MainPit.java`和`MainMid.java`可能是实现A*算法的主程序文件,分别对应不同的平台或设备配置。`www.pudn.com.txt`可能是一个链接或者...
根据提供的文件信息,我们可以深入探讨A*算法在J2ME平台上的实现方法和技术要点。首先,需要明确的是,A*算法是一种广泛应用于路径查找和图遍历中的算法...希望以上内容能帮助您更好地理解如何在J2ME环境中实现A*算法。
A*(发音为 "A-star")寻路算法是一种在图形...总的来说,A*寻路算法在J2ME中的应用是一项技术挑战,需要对算法有深入理解并能适应移动平台的限制。通过合理的实现和优化,可以在有限的资源下实现高效的路径规划功能。
A*寻路算法是计算机图形学和游戏开发中常用的一种路径搜索算法,尤其在有限的网格...总的来说,掌握A*寻路算法及其在J2ME环境中的应用,将有助于提升你在游戏开发、路径规划或任何需要解决类似问题的领域的专业技能。
综上所述,J2ME版A星寻路算法是移动游戏开发中的重要工具,它利用了启发式方法来快速找到最优路径,同时在资源有限的J2ME环境中进行了适当的优化,确保了在RPG等类型游戏中实现流畅的自动寻路功能。
这个经典算法集合显然专注于在J2ME环境中实现的各种算法,特别是其中包含了A*(A-Star)算法。A*算法是一种用于路径查找和图形搜索的高效算法,广泛应用于游戏开发、导航系统以及任何需要寻找最优路径的场景。 A*...
标题中的“初识A*寻路算法”表明我们要探讨的是计算机科学中的一种路径搜索算法——A*(A-star)算法。...了解并掌握A*算法对于解决各种寻路问题具有重要意义,特别是在资源受限的环境中,如J2ME平台。
3. **性能优化**:尽管是模拟器,但J2ME-Loader通过优化算法和内存管理,尽力提供接近原生应用的运行效率。 4. **开源**:J2ME-Loader是基于Apache 2.0许可的开源项目,开发者可以查看源代码,对其进行自定义修改...
在Java或J2ME环境中,A*算法同样可以被广泛运用,帮助程序找到两点间的最短路径。下面我们将深入探讨A星算法的核心原理以及如何在Java中实现它。 一、A星算法原理 1. **启发式函数**:A*算法的关键在于启发式函数...
- **路径寻找**:A*算法等用于计算角色在地图上的最短路径。 5. **角色和NPC** - **角色属性**:包括生命值、攻击力、防御力等,以及相应的升级系统。 - **AI行为**:简单NPC的行为模式可以通过有限状态机实现,...
"j2me--手机游戏寻经算法"这个主题聚焦于游戏中的一个重要技术环节——路径查找算法,它是让游戏中的敌人角色能够在不同图层之间有效地找到并追踪英雄的关键。这种算法对于游戏的动态性和趣味性至关重要。 路径查找...
对于Java或J2ME游戏开发,实现A*算法时,可以选择使用C++或Blitz Basic的实现作为参考,根据游戏需求进行必要的调整。通常,算法实现不依赖于特定编程语言,因此可以轻松地移植到Java环境。 总结来说,A*算法是一种...
- **初始化状态变量**:代码中定义了四个状态变量`state[0]`至`state[3]`,分别对应MD5算法中的A、B、C、D四个缓冲区。 - **计数器**:`count`数组用于跟踪输入数据的位数,以便于正确处理数据块边界。 - **缓冲...
《J2ME老鼠走迷宫智能AI:Java手机游戏中的路径搜索算法解析》 在移动设备上开发游戏,特别是基于Java Micro Edition (J2ME) 平台的游戏,常常需要处理资源有限、性能受限的问题。然而,这并不妨碍开发者利用人工...
5. **数据结构与算法**:游戏中可能使用数组或链表存储地图布局、坦克和子弹的位置。路径查找算法,如BFS(宽度优先搜索)或A*,可能用于智能敌方坦克的移动策略。 6. **多线程**:为了保证游戏流畅,通常会使用多...
在J2ME环境中,客户端的实现涉及到多个关键模块,包括网络通信、用户界面、安全等,通过相互协作来完成支付流程。 首先,客户端的逻辑架构可以分为多个功能模块。这些模块包括: 1. **用户请求交易/交易操作结果...