📄 34720.htm
字号:
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE><P> package HuaRongDao;<BR> import java.io.InputStream;<BR> import javax.microedition.lcdui.*;<BR> /**<BR> *<BR> * @author lin<BR> */<BR> public class Map <BR> {<BR> //处理游戏的地图,负责从外部文件加载地图数据,存放地图数据,并按照地图数据绘制地图<BR> public byte Grid[][];//存放地图数据<BR> public Map() {//构造函数,负责初始化地图数据的存储结构<BR> this.Grid = new byte[Images.HEIGHT][Images.WIDTH];<BR> //用二维数组存放地图数据,注意第一维是竖直坐标,第二维是水平坐标<BR> }<BR> public int[] read_map(int i) <BR> {<BR> //从外部文件加载地图数据,并存放在存储结构中,返回值是光标点的位置<BR> //参数是加载地图文件的等级<BR> int[] a = new int[2];//光标点的位置,0是水平位置,1是竖直位置<BR> try <BR> {<BR> InputStream is = getClass().getResourceAsStream(</P><P> "/levels/level".concat(String.valueOf(i)));<BR> if (is != null) <BR> {<BR> for (int k = 0; k < Images.HEIGHT; k++) <BR> {<BR> for (int j = 0; j < Images.WIDTH; j++) <BR> {<BR> this.Grid[k][j] = (byte) is.read();<BR> if ( this.Grid[k][j] == Images.CURSOR ) <BR> {<BR> //判断出光标所在位置<BR> a[0] = j;//光标水平位置<BR> a[1] = k;//光标竖直位置<BR> this.Grid[k][j] = Images.BLANK;//将光标位置设成空白背景<BR> }<BR> }<BR> is.read();//读取回车(13),忽略掉<BR> is.read();//读取换行(10),忽略掉<BR> }<BR> is.close();<BR> }<BR> else <BR> {<BR> //读取文件失败<BR> a[0] = -1;<BR> a[1] = -1;<BR> }<BR> }<BR> catch (Exception ex) <BR> {<BR> //打开文件失败<BR> a[0] = -1;<BR> a[1] = -1;<BR> }<BR> return a;<BR> }<BR> public boolean draw_map(Graphics g) <BR> {<BR> //调用Draw类的静态方法,绘制地图<BR> try <BR> {<BR> for (int i = 0; i < Images.HEIGHT; i++) <BR> {<BR> for (int j = 0; j < Images.WIDTH; j++) <BR> {<BR> Draw.paint(g, this.Grid[j], j, i);//绘制地图<BR> }<BR> }<BR> return true;<BR> }<BR> catch (Exception ex) <BR> {<BR> return false;<BR> }<BR> }<BR> }</P></PRE></TD></TR></TBODY></TABLE></P>
<P>注意这里的读文件操作的文件位置同样是相对于res文件夹的。<BR> <BR>(5) 建立主逻辑控制:</P>
<P>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE><P> package HuaRongDao;<BR> /**<BR> *<BR> * @author lin<BR> */<BR> import javax.microedition.lcdui.*;<BR> public class ControlLogic extends Canvas implements CommandListener <BR> {<BR> private int[] loc = new int[2]; //光标的当前位置,0是水平位置,1是竖直位置<BR> private int[] SelectArea = new int[4];//被选定的区域,即要移动的区域<BR> private int[] MoveArea = new int[4];//要移动到的区域<BR> private Map MyMap = new Map();//地图类<BR> private boolean selected;//是否已经选中要移动区域的标志<BR> private int level;//当前的关<BR> public ControlLogic() <BR> {<BR> //构造函数<BR> try <BR> {<BR> jbInit();//JBuilder定义的初始化函数<BR> }<BR> catch (Exception e) <BR> {<BR> e.printStackTrace();<BR> }<BR> }<BR> private void Init_game()<BR> {<BR> //初始化游戏,读取地图,设置选择区域,清空要移动到的区域<BR> this.loc = MyMap.read_map(this.level);//读取地图文件,并返回光标的初始位置<BR> //0为水平位置,1为竖直位置<BR> this.SelectArea[0] = this.loc[0];//初始化选中的区域<BR> this.SelectArea[1] = this.loc[1];<BR> this.SelectArea[2] = 1;<BR> this.SelectArea[3] = 1;<BR> this.MoveArea[0] = -1;//初始化要移动到的区域<BR> this.MoveArea[1] = -1;<BR> this.MoveArea[2] = 0;<BR> this.MoveArea[3] = 0;<BR> }<BR> private void jbInit() throws Exception <BR> {<BR> //JBuilder定义的初始化函数<BR> //初始化实例变量<BR> this.selected = false;//设置没有被选中的要移动区域<BR> this.level = 1;<BR> Images.init();//初始化图片常量<BR> Init_game();//初始化游戏,读取地图,设置选择区域,清空要移动到的区域<BR> //setCommandListener(this);//添加命令监听,这是Displayable的实例方法<BR> //addCommand(new Command("", Command.EXIT, 1));//添加“退出”按钮<BR> }<BR> public void commandAction(Command command, Displayable displayable) <BR> {<BR> //命令处理函数<BR> if (command.getCommandType() == Command.EXIT) {//处理“退出”<BR> //HuaRongDaoMidlet.quitApp();<BR> }<BR> }<BR> protected void paint(Graphics g) <BR> {<BR> //画图函数,用于绘制用户画面,即显示图片,勾画选中区域和要移动到的区域<BR> try <BR> {<BR> g.drawImage(Images.image_Frame, 0, 0,Graphics.TOP | Graphics.LEFT);//画背景<BR> MyMap.draw_map(g);//按照地图内容画图<BR> if ( this.selected )<BR> g.setColor(0,255)<BR> }<BR> }</P></PRE></TD></TR></TBODY></TABLE></P>
<P>#p#</P>
<P><STRONG>4.改进程序<BR></STRONG> <BR>(1)记录历史步骤,以便可以悔棋:<BR>记录历史步骤的方法是实现一个History类,这个类实际上是一个Vector的封装,用来保存每一步的走法,走法被定义为一个包含5个元素的数组,分别是</P>
<P>X,Y,width,height,direction.<BR> <BR>这里需要注意的是,Java当中实际上是没有局部变量的,每一个局部变量都需要new出来,所以在使用Vector的addElement()函数时,由于它是传引用,我们必须要新创建一个element,而不能使用全局的,因为如果使用全局的,下一次addElement时,会因为该变了变量的值使得刚才加到Vector中的值也改变了。</P>
<P>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE><P> import java.util.Vector;<BR> /**<BR> *<BR> * @author lin<BR> */<BR> public class History <BR> {<BR> private static Vector steps = new Vector();<BR> /** Creates a new instance of History */<BR> public History() <BR> {<BR> clear();<BR> }<BR> public static void addStep(Object step)<BR> {<BR> steps.addElement(step);<BR> }<BR> public static void removeLastStep()<BR> {<BR> steps.removeElement(steps.lastElement());<BR> }<BR> public static Object getLastStep()<BR> {<BR> return steps.lastElement();<BR> } <BR> public static Object getStepAt(int index)<BR> {<BR> return steps.elementAt(index);<BR> }<BR> public static int getSize()<BR> {<BR> return steps.size();<BR> }<BR> private void clear()<BR> {<BR> if (!steps.isEmpty())<BR> steps.removeAllElements();<BR> }<BR> }</P></PRE></TD></TR></TBODY></TABLE></P>
<P>在每一步移动结束后,记录这一步的信息:</P>
<P>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE><P> ContorlLogic.java: Move()<BR> ......<BR> moves++;// 增加移动的步骤<BR> byte[] step = new byte[5]; //五个参数分别为,</P><P> 前四个和SelectArea一样,最后一个表示上1,下2,左3,右4。<BR> //将此次移动记录到历史记录当中;<BR> step[0]= this.SelectArea[0];<BR> step[1]= this.SelectArea[1];<BR> step[2]= this.SelectArea[2];<BR> step[3]= this.SelectArea[3];<BR> step[4]= this.getMoveDirection();<BR> history.addStep(step);<BR> ......</P></PRE></TD></TR></TBODY></TABLE></P>
<P>增加一个悔棋的按钮,增加一个unMove()函数:</P>
<P>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE><P> public void unMove()<BR> {<BR> if ( moves == 0 )<BR> return;<BR> byte[] step = new byte[5]; //五个参数分别为,</P><P> 前四个和SelectArea一样,最后一个表示上1,下2,左3,右4。<BR> step = (byte []) history.getLastStep();//取得上一步移动<BR> history.removeLastStep();//减少一步;<BR> moves--;<BR> for (int i= 0; i< 4;i++)<BR> {<BR> this.MoveArea = step;//重设MoveArea<BR> this.SelectArea = step;//重设SelectArea<BR> }<BR> if (step[4] == 1)<BR> {<BR> this.SelectArea[1] = (byte) (step[1]-1);<BR> this.loc[1]++;<BR> }<BR> else if (step[4] == 2)<BR> {<BR> this.SelectArea[1] = (byte) (step[1]+1);<BR> this.loc[1]--;<BR> }<BR> else if (step[4] == 3)<BR> {<BR> this.SelectArea[0] = (byte) (step[0]-1);<BR> this.loc[0]++;<BR> }<BR> else if (step[4] == 4)<BR> {<BR> this.SelectArea[0] = (byte) (step[0]+1);<BR> this.loc[0]--;<BR> }<BR> //移动回来.<BR> byte[][] temp = new byte[this.SelectArea[3]][this.SelectArea[2]];<BR> //复制要移动的区域,因为这块区域可能会被覆盖掉<BR> for (int i = 0; i < this.SelectArea[2]; i++) <BR> {<BR> for (int j = 0; j < this.SelectArea[3]; j++) <BR> {<BR> temp[j] = this.MyMap.Grid[this.SelectArea[1] +j]</P><P> [this.SelectArea[0] + i];<BR> }<BR> }<BR> //将要移动的区域移动到刚选中的区域(即要移动到的区域)<BR> for (int i = 0; i < this.SelectArea[2]; i++) <BR> {<BR> for (int j = 0; j < this.SelectArea[3]; j++) <BR> {<BR> this.MyMap.Grid[this.MoveArea[1] + j][this.MoveArea[0] + i] = temp[j];<BR> }<BR> }<BR> //将要移动的区域中无用内容置成空白<BR> for (int i = 0; i < this.SelectArea[3]; i++) <BR> {<BR> for (int j = 0; j < this.SelectArea[2]; j++) <BR> {<BR> if (!isInRange2(this.SelectArea[0] + j,this.SelectArea[1] + i)) <BR> {<BR> //该点是不在要移动到的区域之内,需置空<BR> this.MyMap.Grid[this.SelectArea[1] + i][this.SelectArea[0] + j] </P><P> = Images.BLANK;<BR> }<BR> }<BR> }<BR> //交换SelectArea和MoveArea<BR> byte tempbyte;<BR> tempbyte= SelectArea[0];<BR> SelectArea[0]=MoveArea[0];<BR> MoveArea[0]=tempbyte;<BR> tempbyte= SelectArea[1];<BR> SelectArea[1]=MoveArea[1];<BR> MoveArea[1]=tempbyte;<BR> this.selected = false;<BR> repaint();<BR> }</P></PRE></TD></TR></TBODY></TABLE></P>
<P>增加处理悔棋的按钮:</P>
<P>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE><P> HuaRongDaoMidlet.java:<BR> private final static Command CMD_UNDO = </P><P> new Command("上一步", Command.SCREEN, 1);<BR> ......<BR> else if (c == CMD_UNDO) <BR> {<BR> //处理“上一步”<BR> logic.unMove();<BR> }<BR> ......</P></PRE></TD></TR></TBODY></TABLE></P>
<P>注意:A.在NetBeans当中,有许多方便的按钮,当编辑代码的时候,代码编辑区上面的最右边有两个注释和反注释的按钮,和VS的功能一样,只是没有/* */形式的注释,还有缩进反缩进等按钮,编辑很方便,而且当函数参数输入完成后,直接按“;”就可以自动在行尾加入分号。同样,可以加入标签: BookMark,使得快速回到上一个位置成为可能。</P>
<P>#p#<BR> <BR>B.NetBeans把搜索也加到这个工具栏里面,可以搜索,标记,非常方便。<BR> <BR>(2)改变移动方式,程序提供的移动方块的方式非常难操作,我希望能够点一下方块他就智能地自己寻找能够移动的位置。这里还有一点需要注意,就是不能绕弯,也就是A-B-A-B这样来回走,如果还有其他走法,因此算法中加入了许多判断,但是比原来的代码要简单清晰易懂,操作也比原来简单多了。<BR> <BR>代码如下:</P>
<P>
<TABLE cellSpacing=0 borderColorDark=#ffffff cellPadding=2 width=400 align=center borderColorLight=black border=1>
<TBODY>
<TR>
<TD class=code bgColor=#e6e6e6><PRE><P> public class ControlLogic extends Canvas implements CommandListener <BR> {<BR> public static final byte DIRECTION_UP = (byte) '1'; //方向常量<BR> public static final byte DIRECTION_DOWN = (byte) '2'; //方向常量<BR> public static final byte DIRECTION_LEFT = (byte) '3'; //方向常量<BR> public static final byte DIRECTION_RIGHT = (byte) '4'; //方向常量<BR> private byte[] currentCursor = new byte[4]; //当前光标所在位置,</P><P> 四个参数分别是X,Y,width,height.<BR> private byte[] nextCursor= new byte[4]; //要移动到的位置的光标区域,参数同上.<BR> private Map MyMap = new Map();//地图类<BR> private int level;//当前的关<BR> public int moves=0;//所用的步数.<BR> private History history = new History();<BR> public boolean isWin=false;<BR> public ControlLogic(int gameLevel) {//构造函数<BR> try <BR> {<BR> this.level = gameLevel;<BR> isWin=false;<BR> nbInit();//NetBeans定义的初始化函数<BR> }<BR> catch (Exception e) <BR> {<BR> e.printStackTrace();<BR> }<BR> }<BR> private void Init_game()<BR> {<BR> //初始化游戏,读取地图,设置选择区域,清空要移动到的区域<BR> this.currentCursor = MyMap.read_map(this.level);//读取地图文件,</P><P> 并返回光标的初始位置<BR> //0为水平位置,1为竖直位置, 2为宽,3为高.<BR> nextCursor[0]=currentCursor[0]; //初始化要移动到的区域<BR> nextCursor[1]=currentCursor[1];<BR> nextCursor[2]=currentCursor[2];<BR> nextCursor[3]=currentCursor[3];<BR> }<BR> private void nbInit() throws Exception <BR> {<BR> //NetBeans定义的初始化函数<BR> //初始化实例变量<BR> Images.init();//初始化图片常量<BR> Init_game();//初始化游戏,读取地图,设置选择区域,清空要移<BR> }</P></PRE></TD></TR></TBODY></TABLE></P>
<P align=right> (责任编辑 火凤凰 <A href="mailto:sunsj@51cto.com">sunsj@51cto.com</A> TEL:(010)68476636-8007)</P> </td> </tr> <tr> <td class="d_font4"> </td> </tr> </table>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -