??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲一区二区三区日本久久九,国产精品亚洲一区二区在线观看,亚洲一区二区三区高清不卡http://m.tkk7.com/buaacaptain/category/12808.html只有偏执狂才能生?/description>zh-cnTue, 27 Feb 2007 12:58:28 GMTTue, 27 Feb 2007 12:58:28 GMT60J2ME 游戏E序开发实例精讲详解(转蝲Q?/title><link>http://m.tkk7.com/buaacaptain/archive/2006/07/05/56855.html</link><dc:creator>舚w</dc:creator><author>舚w</author><pubDate>Wed, 05 Jul 2006 13:29:00 GMT</pubDate><guid>http://m.tkk7.com/buaacaptain/archive/2006/07/05/56855.html</guid><wfw:comment>http://m.tkk7.com/buaacaptain/comments/56855.html</wfw:comment><comments>http://m.tkk7.com/buaacaptain/archive/2006/07/05/56855.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://m.tkk7.com/buaacaptain/comments/commentRss/56855.html</wfw:commentRss><trackback:ping>http://m.tkk7.com/buaacaptain/services/trackbacks/56855.html</trackback:ping><description><![CDATA[ <p>一、序a</p> <p>昨天在网上闲逛,发现一讲解用delphi实现华容道游戏的文章Q颇受启发.于是Q生了华定w游戏UL到手Zȝ冲动Q现在手机游戏琳琅满目,不一而Q华定w的实现版本也很多Q正巧不久前W者对J2ME下了一番功夫,正想借这个机会小试牛刀。选用J2ME的原因还有一个就是目前Java开发大行其刎ͼ无线增殖业务q猛发展QJ2ME的应用日渐活跃v来,也希望我的这文章能够ؓJ2ME知识的普及和开发团队的壮大推L助澜。由于长期受ISO规范的媄响,q次试牛刀我也打算늅软g工程的要求,q取瀑布式的开发模式来规划目Q也希望借此Z向各位没有机会参与正式项目开发的读者介l一下Y件开发的程?/p> <p>q里我们先定义项目组的h员体?其实只有我一个h)Q技术调研、需求分析、概要设计、详l设计、编码、测试均有笔者一人担任;工q里我找了个捷径Q盗用网上现成的囄Q然后用ACDSee把它由BMP转换成PNG格式(我出于讲座的目的Q未做商业应用,应该不算侉|?Q至于发布工作,׃~少OTA服务器,此项工作不做(但是我会介绍q步如何??/p> <p>接下来,我们规划一下项目实现的旉表,以我个hl验Q设惛_下:技术调研用2?q部分解决项目的可行性和重大技术问题,旉会长一?Q需求分析用半天(毕竟有现成的东东可以参照Q只要理清思\p了,况且q有很多以前用过的设计模式和写好的代?Q概要设计再用半?有了需求,概要只不够是照方抓药)Q详l设计要??q一步要把所有的问题x楚,q要可能的准确描述出来)Q编码用2?其实1天就够了Q技术已l不是问题,多计划出一天来应付H发事g)Q测试用2?试应该臛_占全部项目的四分之一Q不q这个项目只是一个DemoQ也太简单了)Q发布也要用上半?管我们不去实际发布它,但是q要q旉搞清楚应该如何做)Q最后就是项目ȝ和开庆功?旉待定)?/p> <p>二、利其器</p> <p>“公Ʋ善其事Q必先利其器”,做项目之前第一步是前期调研Q我们要做的华容道这个东东随处可见,我们要调研的是两个方面:</p> <p>1. 游戏的内容:游戏本n很简单,是有几个格子,Ҏ占据其中一个较大的格子Q然后被几个格子包围Q这些格子Ş状不一定相同,但是挡住了曹操移动的方向Q游戏者需要挪动这些格子最l把ҎUdC个指定的位置才算是过养I更具体的分析我们攑֜后面需求分析和概要设计中讨论?/p> <p>2. 技术储备:谈到技术,q里单介l一下J2ME.Java有三个版本,分别是J2MEQ微型版Q?J2SEQ标准版Q?J2EEQ企业版Q.J2ME是一个标准,采用Q层l构设计Q最低层是配|层QConfigurationQ也是讑֤层,其上是简表层QProfileQ?再上是应用层QApplicationQ?MIDP是Ud信息讑֤表,目前L手机支持MIDP1.0Q最新的是MIDP2.0,它比前一个版本增加了Ҏ戏的支持Q在javax.microedition.lcdui.game包中提供了一些类来处理游戏中的技术,比如我们后面会用到的Spritec,它是用来{囄?权衡再三Q笔者决定用MIDP2.0来做开发.首先需要安装一个J2ME的模拟器Q我们就用Sun公司的WTK2.0Q我觉得Sun的东西最权威Q当然你也可以用Nokia.Siemens或是Motolora{其他模拟器Q但是他们的JDK不尽相同Q写出来的程序移植是比较ȝ的.</p> <p>Sun公司的WTK2.0可以到搜索引擎寻找下载,当然要想成功下蝲的前提是你要先注册成为Sun的会员(其实q样对你是有好处的)Q当下来之后是按照提示一步一步的安装Q安装好了之后,我们用一?Hello World"E序开始你的J2ME之旅Q我们启动WTK2.0工具集中的KToolBarQ然后点击New Project按钮Q在弹出的输入框中输入Project Name为HelloWorld,MIDlet Class Name为Hello,然后点击Create ProjectQ开始生成项目,工具会弹出MIDP配置表,q里接受生成的默认|以后q可以修改)点击OKQ工hC我们把写好的Java源程序放到[WTK_HOME]\apps\HelloWorld\src目录之下Q我们编辑如下代码,q保存在上述目录之下Q文件名为Hello.java?/p> <p> <br />import javax.microedition.midlet.*; <br />import javax.microedition.lcdui.*; <br />public class Hello extends MIDlet <br />{ <br />private Display display; <br />public Hello(){ <br />display =Display.getDisplay(this); <br />} <br />public void startApp(){ <br />TextBox t = new TextBox("Hello","Hello",256,0); <br />display.setCurrent(t); <br />} <br />public void pauseApp(){ <br />} <br />public void destroyApp(boolean unconditional){ <br />} <br />}<br /> </p> <p> </p> <p>保存好了之后Q点击Build按钮Q工具会Z~译E序Q如无意外再点击Run按钮Q会弹出一个手机界面,剩下的就不用我教了吧Q用鼠标Ҏ机按键一狂点)。呵呵,你的W一个J2MEE序已经OK?什么?你还一炚w没懂呢(真是厉害Q不懂都能写出J2MEE序来,果然是高手)Q我q里主要是介lWTK2.0工具的用,E序q不是目的,不懂的话后面q会有详l的解说Q这里只是带你上路.什么?你不懂JavaQ那也没有关p,后面我再讲得l一炏V?</p> <p>跌J2MEQ我们先来讲Ҏ戏的理论Q具体到华容道这个游戏,主要有三个方面,贴图Q游戏操作.逻辑判断Q这里讲讲脓图,其他两方面放在概要设计和详细设计里讲Q所谓的贴图Q其实就是画图,是在要昄囑Ş的位|上输出一副图片,Q要是牵扯到动画pȝ一些,可以使用TimerTask.Thread或Rannable之类的技?Q这副图片可以是事先准备好的也可以是临时处理的.在J2ME中有一个Imagec?专门用于理囄Q它有createImage()ҎQ可以直接读取图片文ӞJ2ME只支持PNG格式的图片)Q也可以截取已有的图片的一部分Q这h们可以把很多囄攑֜一P然后一张一张的截下来,好处是节省存储空间和文gd旉Q对于手两者都是性能的瓶颈)Q?</p> <p>J2MEq有一个Graphicsc,专门用于l图Q它有drawImage()ҎQ可以把一副图片在指定的位|上昄出来Q它q有drawRect()Ҏ和setColor()ҎQ这两个Ҏ在后面我们进行游戏操作时׃用到Q这里先交代一下.有了囄和绘囄ҎQ还需要知道把囄到谁w上QJ2ME提供了一个Canvasc,字面意思就是画布,它有一个paint()Ҏ用于h面Q还有一个repaint()Ҏ用于调用paint()ҎQ听着有些p涂是吧Q不要紧Q我来结合具体程序讲解一下.Z今后~程的方便,我们创徏两个cImages和Draw,Images用于保存一些常量值和囄QDraw主要是用于画图,q两个类的源代码如下?</p> <p>Imagescȝ源代码如下: </p> <p> <br />package huarongroad; <br />import javax.microedition.lcdui.*; <br />import javax.microedition.lcdui.game.*; <br />public class Images {//保存帔R <br />//l图位置帔R <br />public static final int UNIT = 32;//方块的单位长?<br />public static final int LEFT = 10;//d的左边界点 <br />public static final int TOP = 9;//d的上边界点 <br />//地图位置帔R <br />public static final int WIDTH = 4;//地图的宽?<br />public static final int HEIGHT = 5;//地图的高?<br />//地图标记帔R <br />public static final byte CAOCAO = (byte) ′a? QA href="file://?Qfile://曹</AQ操的地图标?<br />public static final byte MACHAO = (byte) ′b?//马超的地图标?<br />public static final byte HUANGZHONG = (byte) ′c?//黄忠的地图标?<br />public static final byte GUANYU = (byte) ′d?//关羽的地图标?<br />public static final byte ZHANGFEI = (byte) ′e?//张飞的地图标?<br />public static final byte ZHAOYUN = (byte) ′f?//赵云的地图标?<br />public static final byte ZU = (byte) ′g?//卒的地图标记 <br />public static final byte BLANK = (byte) ′h?//I白的地图标?<br />public static final byte CURSOR = (byte) ′i?//光标的地图标?<br />//地图l合标记帔R <br />public static final byte DLEFT = (byte) ?? QA href="file://l?Qfile://l</AQ合囑Ş左边标记 <br />public static final byte DUP = (byte) ?? QA href="file://l?Qfile://l</AQ合囑Ş上边标记 <br />public static final byte DLEFTUP = (byte) ?? QA href="file://l?Qfile://l</AQ合囑Ş左上标记 <br />//囄帔R <br />public static Image image_base;//基本囄 <br />public static Image image_Zhaoyun;//赵云的图?<br />public static Image image_Caocao;//Ҏ的图?<br />public static Image image_Huangzhong;//黄忠的图?<br />public static Image image_Machao;//马超的图?<br />public static Image image_Guanyu;//关羽的图?<br />public static Image image_Zhangfei;//张飞的图?<br />public static Image image_Zu;//卒的囄 <br />public static Image image_Blank;//I白的图?<br />public static Image image_Frame;//游戏框架的图?<br />public Images() {//构造函?<br />} <br />public static boolean init() {//初始化游戏中用到的图?<br />try { <br />image_base = Image.createImage("/huarongroad/BITBACK.png"); <br />image_Frame = Image.createImage(image_base, 126, 0, 145, 177, <br />Sprite.TRANS_NONE); <br />//SpritecL用来{囄的,是MIDP2.0新新增加的支持游戏的Ҏ?<br />image_Zhaoyun = Image.createImage(image_base, 0, 0, UNIT, 2 * UNIT, <br />Sprite.TRANS_NONE); <br />image_Caocao = Image.createImage(image_base, UNIT, 0, 2 * UNIT, <br />2 * UNIT, Sprite.TRANS_NONE); <br />image_Huangzhong = Image.createImage(image_base, 3 * UNIT, 0, UNIT, <br />2 * UNIT, <br />Sprite.TRANS_NONE); <br />image_Machao = Image.createImage(image_base, 0, 2 * UNIT, UNIT, <br />2 * UNIT, <br />Sprite.TRANS_NONE); <br />image_Guanyu = Image.createImage(image_base, UNIT, 2 * UNIT, <br />2 * UNIT, UNIT, <br />Sprite.TRANS_NONE); <br />image_Zhangfei = Image.createImage(image_base, 3 * UNIT, 2 * UNIT, <br />UNIT, 2 * UNIT, <br />Sprite.TRANS_NONE); <br />image_Zu = Image.createImage(image_base, 0, 4 * UNIT, UNIT, UNIT, <br />Sprite.TRANS_NONE); <br />image_Blank = Image.createImage(image_base, 1 * UNIT, 4 * UNIT,UNIT, <br />UNIT, <br />Sprite.TRANS_NONE); <br />return true; <br />}catch (Exception ex) { <br />return false; <br />} <br />} <br />}<br /> </p> <p> </p> <p>Drawcȝ源代码如下: </p> <p> <br />package huarongroad; <br />import javax.microedition.lcdui.*; <br />public class Draw { <br />//l制游戏中的囄 <br />public Draw(Canvas canvas) {//构造函?<br />} <br />public static boolean paint(Graphics g, byte img, int x, int y) { <br />//在地囄x,y点绘制img指定的图?<br />try { <br />paint(g, img, x, y, Images.UNIT);//把地图x,y点{化成d的绝对坐标,l图 <br />return true; <br />} <br />catch (Exception ex) { <br />return false; <br />} <br />} <br />public static boolean paint(Graphics g, byte img, int x, int y, int unit) { <br />try { <br />switch (img) { <br />case Images.CAOCAO://L?<br />//变成l对坐标Qƈ做调?<br />g.drawImage(Images.image_Caocao, Images.LEFT + x * unit, <br />Images.TOP + y * unit, <br />Graphics.TOP | Graphics.LEFT); <br />break; <br />case Images.GUANYU://d?<br />g.drawImage(Images.image_Guanyu, Images.LEFT + x * unit, <br />Images.TOP + y * unit, <br />Graphics.TOP | Graphics.LEFT); <br />break; <br />case Images.HUANGZHONG://画黄?<br />g.drawImage(Images.image_Huangzhong, Images.LEFT + x * unit, <br />Images.TOP + y * unit, <br />Graphics.TOP | Graphics.LEFT); <br />break; <br />case Images.MACHAO://画马?<br />g.drawImage(Images.image_Machao, Images.LEFT + x * unit, <br />Images.TOP + y * unit, <br />Graphics.TOP | Graphics.LEFT); <br />break; <br />case Images.ZHANGFEI://d?<br />g.drawImage(Images.image_Zhangfei, Images.LEFT + x * unit, <br />Images.TOP + y * unit, <br />Graphics.TOP | Graphics.LEFT); <br />break; <br />case Images.ZHAOYUN://画n?<br />g.drawImage(Images.image_Zhaoyun, Images.LEFT + x * unit, <br />Images.TOP + y * unit, <br />Graphics.TOP | Graphics.LEFT); <br />break; <br />case Images.ZU://d <br />g.drawImage(Images.image_Zu, Images.LEFT + x * unit, <br />Images.TOP + y * unit, <br />Graphics.TOP | Graphics.LEFT); <br />break; <br />case Images.BLANK://ȝ?<br />g.drawImage(Images.image_Blank, Images.LEFT + x * unit, <br />Images.TOP + y * unit, <br />Graphics.TOP | Graphics.LEFT); <br />break; <br />case Images.CURSOR://d?<br />g.drawRect(Images.LEFT + x * unit, <br />Images.TOP + y * unit,Images.UNIT,Images.UNIT); <br />break; <br />} <br />return true; <br />}catch (Exception ex) { <br />return false; <br />} <br />} <br />}<br /> </p> <p> </p> <p>其中Imagescd的是l图位置帔RQ也是在画图时每个格子的长度和相对坐标原点位置要进行的调整Q、地图位|常量(地图的长、宽Q,地图标记帔RQh物对应的记号Q,地图l合标记帔RQ后面会l说Q,囄帔RQ存放h物的囄Q;DrawcM要负责在制定的位|画Zh物图片。下面我来说说ImagescM的地图标记常量和地图l合标记帔R。ؓ了能够灵zȝ安排各个关面的布局Q我们决定把游戏布局的信息存储在外部文g中,然后E序启动后把它读q来?</p> <p>q样我们制定了一套存储图片的代码Q这是地图标记帔RQ如上面ImagescM定义的Caocao(Ҏ)用a字符来表C,当程序读到a字符时就能将它{化成Ҏ对应的图片,q在da字符的位|上q行昄。但是从实际观察中我们发现所有的囄q不是统一大小的,有的?个格子,有的?个格子,q有的占1个格子,而且即便同是占两个格子的囄q有横、竖之分。有鉴于此,我们引入了地囄合标记常量,是说在遇到占有多个格子的时候,?(也就是Images.LEFT)表示它的左边是一个真正的地图标记Q?(也就是Images.UP)表示它的上边是一个真正的地图标记Q?(也就是Images.LEFTUP)表示它的左上Ҏ一个真正的地图标记。地囄合标记常量其实就是用来占位置的,与实际显C无养I当后面我们将到移动时q会再来分析l合标记的用?</p> <p>DrawcM要是用来在画布上d囑ŞQ它有两个paintҎQ这是很常见的函数重载。但是程序中实际上只用到?个参数的paintҎQ它直接获得要画囄的相对坐标位|信息,然后调用5个参数的paintҎ?个参数的paintҎ相对坐标位|信息{换成l对位置Qƈ实际调用Graphics.drawImage()ҎQ将Images中的囄M出来。这U实现方法的好处是灵zd便于扩展Q但你需要画囄位置q不能够对应到格子中的相对坐标位|时Q你可以直接调?个参数的paintҎQ而不必再M改这各类Q但你添加新的图片时Q只要在Images中增加对应的帔RQ然后向Draw?个参数的paintҎd一条处理就可以了。写到这里,两天的时间刚好用完?</p> <p>三、需求分?</p> <p>q部分叫做需求分析,听v来挺吓h的,其实是搞清楚我们要做什么,做成什么样Q那些不做。下面我引领着大家共同来完成这一步骤。首先,我们要做一个华定w的游戏,华容道的故事q里不再赘述了,但其中的人物在这里限定一下,如上面Imagesc里的定义,我们q个版本只提供曹?Caocao)、关?Guanyu)、张?Zhangfei)、n?Zhaoyun)、黄?Huangzhong)、马?Machao)和卒(Zu)。我们这里也限定一下游戏的操作ҎQ首先要通过方向键选择一个要Ud的区?是一张图?Q被选择的区域用黑色Ҏ框住Q选好后按Fire?是定?这块区域选中Q被选中的区域用l色Ҏ框住Q然后选择要移动到的区域,此时用红色方框框住被选择的区域;选好要移动到的区域之后按Fire键将要移动的区域(囄)Ud要移动到的区域,q去掉绿色和U色的方框。这里需要强调的概念有选择的区域、选中的区域、要Ud的区域和要移动到的区域,q四个概念请读者注意区分,当然也应当把q一部分记入数据字典之中?</p> <p>Z使文章的重点H出(介绍如何制作一个J2ME的收集游?Q我们这里限定一些与本主题无关的内容暂不d玎ͼq关之后的动?实现时要用到TimerTask或Threadc,后箋的系列文章中我会详细介绍动画斚w的知?、关面之间的切换(其实很简单,当完成Q务之后重新再做一?、暂停和保存{操?q部分的内容介绍的资料很多,我也写不Z么新的东东来Q难免抄袭,故此免掉)?</p> <p>需求分析基本完成,M午还有一D|_马上动手用ACDSee把从|上找来的BMP文gQ调整其大小?71*177(我的q个囄是两个部分合在一P所以比手机实际屏幕大了)Q另存ؓPNG格式。半天时间刚刚好Q不但搞清楚了要做的东东Q还把要用的囄准备好了?</p> <p>四、概要设?</p> <p>概要设计是从需求分析过渡到详细设计的桥梁和U带Q这一部分中我们确定项目的实现Ҏ和模块的划分。我们决定将整个目分成五个部分Q分别是前面介绍的Images、DrawQ还有Map和Displayable1和MIDlet1。Images和Drawcd能简单、结构固定,因此很多目我们都用这两各c,q里直接拿来Ҏp用了Q前面已l介l过q里不再赘述。MapcL用来从外部文件读入地图,然后保存在一个数l之中,q部分的内容是我们在本阶D讨论的重点。Displayable1是一个承了CanvascȝdQ它用来处理E序的主要控刉辑和一部分控制逻辑所需的辅助函敎ͼ主要函数应该包括用来l图的paint()函数、用来控制操作的keyPressed()函数、用来控刉择区域的setRange()函数、用来控刉择要移动到区域的setMoveRange()函数、用来移动选中区域的Move()函数和判断是否完成Q务的win()函数Q更具体的分析,我们攑ֈ详细设计中去l化。MIDlet1实际上就是一个控制整个J2ME应用的控制程序,其实也没有什么可特别的,它和我们前面介绍?Hello World"E序大同异Q这里就不展开来说了,后面会脓出它的全部代码?</p> <p>MapcM要应该有一个Grid[][]的二l数l,用来存放华容道的地图Q还应该有一个read_map()函数用来从外部文件读取地囑ֆ容填充Grid数据l构Q再是要有一个draw_map()函数用来把Grid数据l构中的地图内容转换成图片显C出?当然要调用DrawcȝpaintҎ)。说到读取外部文ӞW者知道有两种ҎQ一U是传统的定义一个InputStream对象Q然后用getClass().getResourceAsStream()Ҏ取得输入,然后再从输入中取得外部文g的内容,例如 </p> <p> <br />InputStream is = getClass().getResourceAsStream("/filename"); <br />if (is != null) { <br />byte a = (byte) is.read(); <br />}<br /> </p> <p> </p> <p>q里h意文件名中的根\径是相对于便以后的class文g攄的位|,而不是源文g(java)。第二种Ҏ是用onnector.openInputStreamҎQ然后打开的协议是ResourceQ但是这U方法笔者反复尝试都没能调通,报告的错误是~少Resource协议Q估计第二种Ҏ用到J2ME的某些扩展类包,此处不再q。由于以前已l做q一些类似华定wq样的地图,q里直接l出Mapcȝ代码Q后面就不再详细解释MapcMQ以便于我们可以集中_֊处理Displayable1中的逻辑?</p> <p>Mapcȝ代码如下Q?</p> <p> <br />package huarongroad; <br />import java.io.InputStream; <br />import javax.microedition.lcdui.*; <br />public class Map { <br />//处理游戏的地图,负责从外部文件加载地图数据,存放地图数据Qƈ按照地图数据l制地图 <br />public byte Grid[][];//存放地图数据 <br />public Map() {//构造函敎ͼ负责初始化地图数据的存储l构 <br />this.Grid = new byte[Images.HEIGHT][Images.WIDTH]; <br />//用二l数l存攑֜图数据,注意W一l是竖直坐标Q第二维是水q_?<br />} <br />public int[] read_map(int i) { <br />QA href="file://?Qfile://从</AQ外部文件加载地图数据,q存攑֜存储l构中,q回值是光标点的位置 <br />//参数是加载地图文件的{ <br />int[] a = new int[2];//光标点的位置Q?是水q位|,1是竖直位|?<br />try { <br />InputStream is = getClass().getResourceAsStream( <br />"/huarongroad/level".concat(String.valueOf(i))); <br />if (is != null) { <br />for (int k = 0; k Q?Images.HEIGHT; k++) { <br />for (int j = 0; j Q?Images.WIDTH; j++) { <br />this.Grid[k][j] = (byte) is.read(); <br />if ( this.Grid[k][j] == Images.CURSOR ) { <br />//判断出光标所在位|?<br />a[0] = j;//光标水^位置 <br />a[1] = k;//光标竖直位置 <br />this.Grid[k][j] = Images.BLANK;//光标位|设成空白背?<br />} <br />} <br />is.read();//d回RQ?3Q?忽略?<br />is.read();//d换行Q?0Q?忽略?<br />} <br />is.close(); <br />}else { <br />//d文gp| <br />a[0] = -1; <br />a[1] = -1; <br />} <br />}catch (Exception ex) { <br />//打开文gp| <br />a[0] = -1; <br />a[1] = -1; <br />} <br />return a; <br />} <br />public boolean draw_map(Graphics g) { <br />//调用Drawcȝ静态方法,l制地图 <br />try { <br />for (int i = 0; i Q?Images.HEIGHT; i++) { <br />for (int j = 0; j Q?Images.WIDTH; j++) { <br />Draw.paint(g, this.Grid[i][j], j, i);//l制地图 <br />} <br />} <br />return true; <br />}catch (Exception ex) { <br />return false; <br />} <br />} <br />}<br /> </p> <p> </p> <p>对于像华定wq样的小型地囑֏以直接用手工来绘制地囄内容Q比如: </p> <p>fa1c </p> <p>2232 </p> <p>bd1e </p> <p>2gg2 </p> <p>gihg </p> <p>但是Q如果遇到像坦克大战或超U玛莉那L地图Q就必须另外开发一个地囄辑器?我会在后l的文章中介l用vb来开发一个地囄辑器)?</p> <p>五、详l设?</p> <p>详细设计是程序开发过E中臛_重要的一个环节,好在我们在前面的各个阶段中已l搭建好了项目所需的一些工P现在q个阶段中我们只需集中_֊设计好Displayable1中的逻辑?两天的时间当然不只干q点z,q要把其他几个类的设计修改一? </p> <p>Displayable1q个c负责处理程序的控制逻辑。首先,它需要有表示当前关面的变量level、表C当前光标位|的变量loc、表CUd区域的变量SelectArea、表CUd到的区域的变量MoveArea、表C是否已有区域被选中而准备移动的变量Selected和Mapcȝ实例MyMap。然后,我们Ҏ用户按不同的键来处理不同的消息,我们要实现keyPressed()函数Q在函数中我们处理按键的上下左右和选中(Fire)Q这里的处理需要我展开来讲一Ԍ后面我很快会把这一部分详细展开?</p> <p>接下来,是实现paint()函数Q我们打在q一部分中反复的重画背景、地囑֒选择区域Q这个函数必d理好区域被选中之后的画W颜色的切换Q具体讲是在没有选中M区域时要用黑色画W,当选重要移动的区域时用绿色画W,当选择要移动到的区域时改用U色ȝ(当然附加一张流E图是必不可的)?</p> <p>再下面要实现的setRange()函数和setMoveRange()函数Q这两个函数用来讄要移动的区域和要Ud到的区域Q我的思\是利用前面在ImagescM介绍q的地图l合标记帔RQ当Ud到地囄合标记常量时Q根据该点地图中的值做逆向变换扑ֈ相应的地图标记常量,然后讄相应的loc、SelectArea和MoveArea,其中setMoveRange()函数q用C一个辅助函数isInRange(),isInRange()函数是用来判断给定的Ҏ否在已选中的要Ud的区域之?如果isInRange()的返回值是假ƈ且该点处的g是空白就表明要移动到的区域R犯了其他以被占用的区域。有了setRange()和setMoveRange()函数QMove()函数水到渠成了,Move()函数要Ud的区域移动到要移动到的区?在移动过E中分ؓ三步q行: </p> <p>W一.复制要移动的区域Q?</p> <p>W二.复制出的要Ud区域复制到要Ud到的区域(q两步分开q行的目的是防止在复制过E中覆盖掉要Ud的区?Q?</p> <p>W三.用isInRange2()判断l定的点是否在要Ud到的区域?不在要Ud到的区域内的点设|成I白?下面我们详细的分析一下keyPressed()函数的实现方?首先,keyPressed()函数要处理按键的上下左右和选中(Fire),在处理时需要用CanvascȝgetGameAction函数来将按键的键D{换成游戏的方?q样可以提高游戏的兼Ҏ?因ؓ不同的J2ME实现,其方向键的键g一定是相同??</p> <p>接下?分别处理四个方向和选中.当按下向上时,先判断是否已l选定了要Ud的区?即this.selected是否为真),如果没有选中要移动区域则让光标向上移动一?然后调用setRange()函数讄选择要移动的区域,再调用repaint()函数h屏幕,否则如果已经选中了要Ud的区?p光标向上Ud一?然后调用setMoveRange()函数判断是否能够向上Ud已选中的区?如果能移动就调用repaint()函数h屏幕,如果不能Udp光标向下退回到原来的位|?</p> <p>当按下向下时,先判断是否已l选定了要Ud的区?如果没有选中要移动的区域则判断当前所处的区域是否Z个格?如果是两个格高则向下Ud两格,如果是一个格高则向下Ud一?接着再调用setRange()函数讄选择要移动的区域,而后调用repaint()函数h屏幕,否则如果已经选中了要Ud的区?p光标向下Ud一?然后调用setMoveRange()函数判断是否能够向下Ud已选中的区?如果能移动就调用repaint()函数h屏幕,如果不能Udp光标向上退回到原来的位|?按下向左时情况完全类似向上的情况,按下向右时情况完全类似向下的情况,因此q里不再赘述,详细情况请参见程序的源代码?</p> <p>当按下选中键时,先判断是否已l选中了要Ud的区?如果已经选中了要Ud的区域就调用Move()函数完成pUd的区域到要移动到的区域的Udq程,接着调用repaint()函数h屏幕,然后已选择标记|成false,l箋调用win()函数判断是否完成了Q?否则如果q没有选定要移动的区域则再判断当前选中区域是否为空?如果不是I白将选中标记|成true,然后h屏幕.q里介绍一个技?在开发程序遇到复杂的逻辑的时?可以构造一格打印函数来所兛_的数据结构打印出来以利调?q里我们构造一个PrintGrid()函数,q个函数Ua是ؓ了调试之?效果q得不错.x我们完成了编码前的全部工作?</p> <p>六、编?</p> <p>整个目共有五个c?有四个类的代码前面已l介l过?而且是在其他目中用过的相Ҏ熟的代码.现在只需全力d现Displayable1c?Displayable1cȝ代码如下: </p> <p> <br />package huarongroad; <br />import javax.microedition.lcdui.*; <br />public class Displayable1 extends Canvas implements CommandListener { <br />private int[] loc = new int[2]; QA href="file://?Qfile://光</AQ标的当前位|,0是水q位|,1是竖直位|?<br />private int[] SelectArea = new int[4];//被选定的区域,卌Ud的区?<br />private int[] MoveArea = new int[4];//要移动到的区?<br />private Map MyMap = new Map();//地图c?<br />private boolean selected;//是否已经选中要移动区域的标志 <br />private int level;//但前的关?<br />public Displayable1() {//构造函?<br />try { <br />jbInit();//JBuilder定义的初始化函数 <br />}catch (Exception e) { <br />e.printStackTrace(); <br />} <br />} <br />private void Init_game(){ <br />//初始化游戏,d地图Q设|选择区域Q清IUd到的区域 <br />this.loc = MyMap.read_map(this.level);//d地图文gQƈq回光标的初始位|?<br />//0为水q位|,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;//初始化要Ud到的区域 <br />this.MoveArea[1] = -1; <br />this.MoveArea[2] = 0; <br />this.MoveArea[3] = 0; <br />} <br />private void jbInit() throws Exception {//JBuilder定义的初始化函数 <br />QA href="file://?Qfile://初</AQ始化实例变?<br />this.selected = false;//讄没有被选中的要Ud区域 <br />this.level = 1; <br />Images.init();//初始化图片常?<br />Init_game();//初始化游戏,d地图Q设|选择区域Q清IUd到的区域 <br />setCommandListener(this);//d命o监听Q这是Displayable的实例方?<br />addCommand(new Command("Exit", Command.EXIT, 1));//d“退出”按?<br />} <br />public void commandAction(Command command, Displayable displayable) { <br />//命o处理函数 <br />if (command.getCommandType() == Command.EXIT) {//处理“退出?<br />MIDlet1.quitApp(); <br />} <br />} <br />protected void paint(Graphics g) { <br />//d函数Q用于绘制用L面,xC图片,勄选中区域和要Ud到的区域 <br />try { <br />g.drawImage(Images.image_Frame, 0, 0, <br />Graphics.TOP | Graphics.LEFT);//画背?<br />MyMap.draw_map(g);//按照地图内容d <br />if ( this.selected ) <br />g.setColor(0,255,0);//如果被选中Q改用绿色画选中的区?<br />g.drawRect(this.SelectArea[0] * Images.UNIT + Images.LEFT, <br />this.SelectArea[1] * Images.UNIT + Images.TOP, <br />this.SelectArea[2] * Images.UNIT, <br />this.SelectArea[3] * Images.UNIT);//d选择区域Q?<br />QA href="file://?Qfile://如</AQ果被选中Q就用绿?<br />QA href="file://?Qfile://否</AQ则Q用黑?<br />g.setColor(255,255,255);//恢复ȝ颜色 <br />if (this.selected) {//已经选中了要Ud的区?<br />g.setColor(255, 0, 255);//改用U色 <br />g.drawRect(this.MoveArea[0] * Images.UNIT + Images.LEFT, <br />this.MoveArea[1] * Images.UNIT + Images.TOP, <br />this.MoveArea[2] * Images.UNIT, <br />this.MoveArea[3] * Images.UNIT);//d要移动到的区?<br />g.setColor(255, 255, 255);//恢复ȝ颜色 <br />} <br />}catch (Exception ex) { <br />} <br />System.out.println(Runtime.getRuntime().freeMemory()); <br />System.out.println(Runtime.getRuntime().totalMemory()); <br />} <br />private void setRange() { <br />//讄Ud后能够选中的区?<br />//调整当前光标位置到地囄M|,卌录h物信息的位置 <br />if (this.MyMap.Grid[this.loc[1]][this.loc[0]] == Images.DLEFT) { <br />this.loc[0] -= 1;//向左?<br />}else if (this.MyMap.Grid[this.loc[1]][this.loc[0]] == Images.DUP) { <br />this.loc[1] -= 1;//向上?<br />}else if (this.MyMap.Grid[this.loc[1]][this.loc[0]] == Images.DLEFTUP) { <br />this.loc[0] -= 1;//向左?<br />this.loc[1] -= 1;//向上?<br />} <br />this.SelectArea[0] = this.loc[0];//讄光标的水q位|?<br />this.SelectArea[1] = this.loc[1];//讄光标的竖直位|?<br />//讄光标的宽?<br />if (this.loc[0] + 1 Q?Images.WIDTH) { <br />this.SelectArea[2] = this.MyMap.Grid[this.loc[1]][this.loc[0] + 1] != (byte) ??? <br />1 : 2; <br />}else { <br />this.SelectArea[2] = 1; <br />} <br />//讄光标的高?<br />if (this.loc[1] + 1 Q?Images.HEIGHT) { <br />this.SelectArea[3] = this.MyMap.Grid[this.loc[1] + 1][this.loc[0]] != (byte) ??? <br />1 : 2; <br />}else { <br />this.SelectArea[3] = 1; <br />} <br />} <br />private boolean setMoveRange() { <br />//讄要移动到的区域,能够Udq回true,否则q回false <br />for (int i = 0; i Q?this.SelectArea[2]; i++) { <br />for (int j = 0; j Q?this.SelectArea[3]; j++) { <br />if (this.loc[1] + j Q? Images.HEIGHT || <br />this.loc[0] + i Q? Images.WIDTH || <br />(!isInRange(this.loc[0] + i, this.loc[1] + j) && <br />this.MyMap.Grid[this.loc[1] + j][this.loc[0] + i] != <br />Images.BLANK)) { <br />return false; <br />} <br />} <br />} <br />this.MoveArea[0] = this.loc[0]; <br />this.MoveArea[1] = this.loc[1]; <br />this.MoveArea[2] = this.SelectArea[2]; <br />this.MoveArea[3] = this.SelectArea[3]; <br />return true; <br />} <br />private boolean isInRange(int x, int y) { <br />//判断l定的(xQyQ点是否在选定区域之内Qx是水q_标,y是竖直坐?<br />if (x Q? this.SelectArea[0] && <br />x Q?this.SelectArea[0] + this.SelectArea[2] && <br />y Q? this.SelectArea[1] && <br />y Q?this.SelectArea[1] + this.SelectArea[3]) { <br />return true; <br />}else { <br />return false; <br />} <br />} <br />private boolean isInRange2(int x, int y) { <br />//判断l定的(xQyQ点是否在要Ud到的区域之内Qx是水q_标,y是竖直坐?<br />if (x Q? this.MoveArea[0] && <br />x Q?this.MoveArea[0] + this.MoveArea[2] && <br />y Q? this.MoveArea[1] && <br />y Q?this.MoveArea[1] + this.MoveArea[3]) { <br />return true; <br />}else { <br />return false; <br />} <br />} <br />protected void keyPressed(int keyCode) { <br />//处理按下键盘的事Ӟq是Canvas的实例方?<br />switch (getGameAction(keyCode)) {//按键的D{化成方向帔R <br />case Canvas.UP://向上 <br />if (!this.selected) {//q没有选定要移动的区域 <br />if (this.loc[1] - 1 Q? 0) {//向上q有UdI间 <br />this.loc[1]--;//向上Ud一?<br />setRange();//讄光标Ud的区域,该函数能光标移动到地图M|?<br />repaint();//重新l图 <br />} <br />}else {//已经选定了要Ud的区?<br />if (this.loc[1] - 1 Q? 0) {//向上q有UdI间 <br />this.loc[1]--;//向上Ud一?<br />if (setMoveRange()) {//能够UdQ该函数能够讄要移动到的区?<br />repaint();//重新l图 <br />}else {//不能Ud <br />this.loc[1]++;//退回来 <br />} <br />} <br />} <br />break; <br />case Canvas.DOWN://向下 <br />if (!this.selected) {//q没有选定要移动的区域 <br />if (this.loc[1] + 1 Q?Images.HEIGHT) {//向下q有UdI间 <br />if (this.MyMap.Grid[this.loc[1] + 1][this.loc[0]] == <br />Images.DUP){//该图片有两个格高 <br />this.loc[1]++;//向下Ud一?<br />if (this.loc[1] + 1 Q?Images.HEIGHT) {//向下q有 <br />QA href="file://U?Qfile://U</AQ动I间 <br />this.loc[1]++;//向下Ud一?<br />setRange();//讄光标Ud的区域, <br />QA href="file://?Qfile://该</AQ函数能光标移动到地图M|?<br />repaint();//重新l图 <br />}else {//向下没有UdI间 <br />this.loc[1]--;//退回来 <br />} <br />}else {//该图片只有一个格?<br />this.loc[1]++;//向下Ud一?<br />setRange();//讄光标Ud的区域, <br />QA href="file://?Qfile://该</AQ函数能光标移动到地图M|?<br />repaint();//重新l图 <br />} <br />}else { <br />} <br />}else {//已经选定了要Ud的区?<br />if (this.loc[1] + 1 Q?Images.HEIGHT) {//向下q有UdI间 <br />this.loc[1]++;//向下Ud一?<br />if (setMoveRange()) {//能够UdQ该函数能够讄要移动到的区?<br />repaint();//重新l图 <br />}else {//不能Ud <br />this.loc[1]--;//退回来 <br />} <br />} <br />} <br />break; <br />case Canvas.LEFT://向左 <br />if (!this.selected) {//q没有选定要移动的区域 <br />if (this.loc[0] - 1 Q? 0) {//向左q有UdI间 <br />this.loc[0]--;//向左Ud一?<br />setRange();//讄光标Ud的区域,该函数能光标移动到地图M|?<br />repaint();//重新l图 <br />} <br />}else {//已经选定了要Ud的区?<br />if (this.loc[0] - 1 Q? 0) {//向左q有UdI间 <br />this.loc[0]--;//向左Ud一?<br />if (setMoveRange()) {//能够UdQ该函数能够讄要移动到的区?<br />repaint();//重新l图 <br />}else {//不能Ud <br />this.loc[0]++;//退回来 <br />} <br />} <br />} <br />break; <br />case Canvas.RIGHT://向右 <br />if (!this.selected) {//q没有选定要移动的区域 <br />if (this.loc[0] + 1 Q?Images.WIDTH) {//向右q有UdI间 <br />if (this.MyMap.Grid[this.loc[1]][this.loc[0] + 1] == <br />Images.DLEFT) {//该图片有两个格宽 <br />this.loc[0]++;//向右Ud一?<br />if (this.loc[0] + 1 Q?Images.WIDTH) {//向右q有 <br />QA href="file://U?Qfile://U</AQ动I间 <br />this.loc[0]++;//向右Ud一?<br />setRange();//讄光标Ud的区域, <br />QA href="file://?Qfile://该</AQ函数能光标移动到地图M|?<br />repaint();//重新l图 <br />}else {//向右没有UdI间 <br />this.loc[0]--;//退回来 <br />} <br />}else {//该图片只有一个格?<br />this.loc[0]++;//向右Ud一?<br />setRange();//讄光标Ud的区域, <br />QA href="file://?Qfile://该</AQ函数能光标移动到地图M|?<br />repaint();//重新l图 <br />} <br />}else { <br />} <br />}else {//已经选定了要Ud的区?<br />if (this.loc[0] + 1 Q?Images.WIDTH) {//向右q有UdI间 <br />this.loc[0]++;//向右Ud一?<br />if (setMoveRange()) {//能够UdQ该函数能够讄要移动到的区?<br />repaint();//重新l图 <br />}else {//不能Ud <br />this.loc[0]--;//退回来 <br />} <br />} <br />} <br />break; <br />case Canvas.FIRE: <br />if (this.selected) {//已经选定了要Ud的区?<br />Move();//要Ud的区域移动到刚选中的区?<br />repaint();//重新l图 <br />this.selected = false;//清除已选定要移动区域的标志 <br />if ( win()) { <br />System.out.println("win"); <br />} <br />}else {//q没有选定要移动的区域 <br />if (this.MyMap.Grid[this.loc[1]][this.loc[0]] == <br />Images.BLANK) {//要移到的位置是一个空?<br />}else {//要移到的位置不是I白 <br />this.selected = true;//讄已选定要移动区域的标志 <br />} <br />repaint();//重新l图 <br />} <br />break; <br />} <br />} <br />private boolean win(){ <br />QA href="file://?Qfile://判</AQ断是否已经救出了曹?<br />if ( this.MyMap.Grid[Images.HEIGHT - 2 ][Images.WIDTH - 3 ] == Images.CAOCAO ) <br />return true; <br />else <br />return false; <br />} <br />private void PrintGrid(String a) { <br />QA href="file://?Qfile://打</AQ印当前地图的内容,用于调试 <br />System.out.println(a); <br />for (int i = 0; i Q?Images.HEIGHT; i++) { <br />for (int j = 0; j Q?Images.WIDTH; j++) { <br />System.out.print( (char)this.MyMap.Grid[i][j]); <br />} <br />System.out.println(""); <br />} <br />} <br />private void Move() { <br />QA href="file://?Qfile://</AQ要Ud的区域移动到刚选中的区?<br />if (this.MoveArea[0] == -1 || this.MoveArea[1] == -1 || <br />this.SelectArea[0] == -1 || this.SelectArea[1] == -1) {//没有选中区域 <br />}else {//已经选中了要Ud的区域和要移动到的区?<br />byte[][] temp = new byte[this.SelectArea[3]][this.SelectArea[2]]; <br />QA href="file://?Qfile://复</AQ制要移动的区域Q因块区域可能会被覆盖掉 <br />for (int i = 0; i Q?this.SelectArea[2]; i++) { <br />for (int j = 0; j Q?this.SelectArea[3]; j++) { <br />temp[j][i] = <br />this.MyMap.Grid[this.SelectArea[1] +j] <br />[this.SelectArea[0] + i]; <br />} <br />} <br />QA href="<a href="file://PrintGrid/">file://PrintGrid</a>"Q?a href="file://PrintGrid/">file://PrintGrid</a>Q?AQ?"1"); // 调试信息 <br />QA href="file://?Qfile://</AQ要Ud的区域移动到刚选中的区域(卌Ud到的区域Q?<br />for (int i = 0; i Q?this.SelectArea[2]; i++) { <br />for (int j = 0; j Q?this.SelectArea[3]; j++) { <br />this.MyMap.Grid[this.MoveArea[1] + j] <br />[this.MoveArea[0] + i] = temp[j][i]; <br />} <br />} <br />QA href="<a href="file://PrintGrid/">file://PrintGrid</a>"Q?a href="file://PrintGrid/">file://PrintGrid</a>Q?AQ?"2");// 调试信息 <br />QA href="file://?Qfile://</AQ要Ud的区域中无用内容|成I白 <br />for (int i = 0; i Q?this.SelectArea[3]; i++) { <br />for (int j = 0; j Q?this.SelectArea[2]; j++) { <br />if (!isInRange2(this.SelectArea[0] + j, <br />this.SelectArea[1] + i)) {//该点是不在要Ud?<br />QA href="file://?Qfile://的</AQ区域之内,需|空 <br />this.MyMap.Grid[this.SelectArea[1] + i] <br />[this.SelectArea[0] + j] = Images.BLANK; <br />}else { <br />} <br />} <br />} <br />QA href="<a href="file://PrintGrid/">file://PrintGrid</a>"Q?a href="file://PrintGrid/">file://PrintGrid</a>Q?AQ?"3");// 调试信息 <br />this.SelectArea[0] = this.MoveArea[0];//重置选中位置的水q_?<br />this.SelectArea[1] = this.MoveArea[1];//重置选中位置的竖直坐?<br />this.MoveArea[0] = -1;//清空要移动到的位|?<br />this.MoveArea[1] = -1;//清空要移动到的位|?<br />this.MoveArea[2] = 0;//清空要移动到的位|?<br />this.MoveArea[3] = 0;//清空要移动到的位|?<br />} <br />} <br />}<br /> </p> <p> </p> <p>代码的相兛_?在详l设计阶D已l讲q?代码中有比较相近的注?误者自行研d?全部的代码写好,用wtk2.0自带的Ktoolbar工具建立一个工E?接下来把M源文件放到正位|下,然后点击build,再点run,完成了E序的编?当然如果有错误还要修改和调试?</p> <p>七、测?</p> <p>作ؓ一个真正的产品要经q单体测试、结合测试和pȝ试。由于项目本w简?而且大部分代码已l是相对成熟?我们跌单体试Q又׃W者的实际环境所?无法搞到Java手机,无法架设OTA服务?因此我们也只能放弃系l测试。那么就让我们开始结合测试吧。测试之前要先出一个测试式样书,也就是测试的计划。我们将它简化一?只测试如下几U情?W一、对各种形状的区域的选择和移?W二、͘q边界区域的选择和移?W三、同一区域的反复选择和反复移?W四、非法选择和非法移动。有了测试的目标,接下来的工作是用wtk2.0自带的Run MIDP Application工具q行试。打开q个工具,加蝲huarongRoad的jad文g,E序׃自动q行,选择launch上MIDlet1q个E序,华容道游戏就会跃然屏q之?接下来的工作是左三?右三?拇指扭扭,来做试。测试过E中发现M的问?立刻发一个bug给自己,然后又是痛苦的调试和修正bug,如此如此?</p> <p>八、发?</p> <p>谈到发布,其实是个关键,再好的品不能很好的发布出去也只是个产品而已,变不成商品也得不到回报.׃W者的条g所?q里只能是纸上谈?不过q是希望能够使读者对q一q程有所了解(|上的资料也很多)?</p> <p>J2ME的程序发布一般都是通过OTA(Over The Air),你只需要一台有公网IP的主机和一个普通的web Server可以了(管要求很低,但笔者还是没?Q这里我们以apacheZ介绍一下OTA服务的配|,首先是安装好了apache服务器,然后在conf目录下找到mime.types文gQ在该文件中加入如下两行 </p> <p>application/java-archive jar </p> <p>text/vnd.sun.j2me.app-descriptor jad </p> <p>然后重vapache服务器就可以了。接下来的工作就是修改jad文g中MIDlet-Jar-URL:后面的参敎ͼ它改ؓURL的绝对\径,卻IA href="<a href="http://***/">http://***/</a>"Q?a href="http://***/">http://***/</a>Q?AQhuarongroad.jar(其中***是你的域名或IP地址)。在下面是用java手机下蝲jad文gQ它会自动部|相应的jar文gq加载它。剩下的工作和在模拟器上操作是一L了?</p> <p>九、项目ȝ </p> <p>xQ我们已l完成了一个J2ME游戏的全部开发过E,E序中涉及到了调研、分析、设计、编码、测试和发布{方面的问题Q其实在实际的工作中q有很多更ؓ具体的问题,毕竟技术只在Y件开发过E中占据很有限的一部分Q这里限于篇q的限制无法一一具体展开。今后,W者计划再写一用J2ME开发手机屏保的文章Q借此Z向读者展CJ2ME动画技术;然后再写一J2ME|络应用的文章,做一个类似开心辞兔RL知识问答游戏Q以便向读者展CJ2ME的网l技术;待这两方面的技术交待清楚之后,我将引领读者制作一个稍大一些的游戏?/p> <img src ="http://m.tkk7.com/buaacaptain/aggbug/56855.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://m.tkk7.com/buaacaptain/" target="_blank">舚w</a> 2006-07-05 21:29 <a href="http://m.tkk7.com/buaacaptain/archive/2006/07/05/56855.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>J2MEE序开发新手入门九大要?http://m.tkk7.com/buaacaptain/archive/2006/07/05/56854.html舚w舚wWed, 05 Jul 2006 13:10:00 GMThttp://m.tkk7.com/buaacaptain/archive/2006/07/05/56854.htmlhttp://m.tkk7.com/buaacaptain/comments/56854.htmlhttp://m.tkk7.com/buaacaptain/archive/2006/07/05/56854.html#Feedback0http://m.tkk7.com/buaacaptain/comments/commentRss/56854.htmlhttp://m.tkk7.com/buaacaptain/services/trackbacks/56854.html一、J2ME中需要的Java基础知识
  
  现在有大部分人,都是从零开始学J2ME的,学习J2ME的时候,L从Java基础开始学习,而且现在讲Java基础的书c中都是以J2SE来讲基础Q这q学习造成了一些不必要的麻烦,下面J2ME中用到的和不需要的Java基础知识做一个简单的说明?br />  
  J2ME中用到的Java基础知识Q?br />  
  1、Java语法基础Q包括基本数据类型、关键字、运符{等
  
  2、面向对象的思想Q类和对象的概念Q承和多态等{?br />  
  3、异常处?br />  
  4、多U程
  
  J2ME中没有用到的Java基础知识Q?br />  
  1、JDK中javac和java命o的?br />  
  2、Java基础中的很多cdJ2ME中没有,或者类中的Ҏ做了大量的精。所以徏议在J2ME中熟悉类库?br />  
  3、Applet、AWT、Swingq些知识在J2ME中根本用不到?br />  
  单说q么多,希望学J2ME的朋友们能少C些弯路,不之处希望大家U极指正和补充?br />  
  二、J2ME中暂时无法完成的功能
  
  列一些J2ME中暂时无法完成的功能Q希望大家能U极补充Q?br />  
  1、在手机中不更改代码实现ULQ主要指游戏?br />  
  2、动态修Ҏ钮文字?br />  
  3、在Canvas上接受中文输入?br />  
  4、操作本地资源、例如地址本、已收短信息{?br />  
  5、制作破坏性的手机病毒?br />  
  6、其他等待大家来补充?br />  
  三、J2ME的跨q_?/b>
  
  J2ME技术源于JavaQ所以也hJVM的优势,可以在支持Java的^Cq行ULQ但是现在的J2ME技术在跨^C却做的很p糕Q我们来单看一下原因:
  
  1、手机的屏幕寸不一Q?br />  
  q个主要在界面制作上。如果你使用的是高用户界面Q比如你做的是应用开发或者用L陆、用h册这L通用功能Ӟ一般没有什么问题?br />  
  如果你用的是低U用L面,比如你做的是游戏Q那么你需要考虑q个问题了?br />  
  2、厂商的扩展API不统一Q?br />  
  例如Nokia的扩展APIcdUIpdQ在别的手机上或者没有实玎ͼ或者包名不同等{?br />  
  3、手机^C实现的bugQ?br />  
  例如Nokia?650在实现双~冲上有bugQ那么在q种机型上运行的软g׃能用双~冲。其他NOKIA上的一些bugQ可以参看:http://blog.csdn.net/Mailbomb/archive/2005/03/24/329123.aspx
  
  4、手机性能问题?br />  
  不同手机的可用内存、最大jar文g都有要求Q例如Nokia S40的大部分手机支持的最大jar文g?4KQ最大可用内容ؓ210K?br />  
  所以现在的手机软gQ特别是游戏都提供支持的机型列表Q也才有了手机游戏移植h员的存在?br />  
  四、学习J2ME可以从事的工作种c?/b>
  
  现在J2ME技术可以说相当的火_q里介绍一些学好了J2ME之后可以从事的工作的U类Q?br />  
  1、J2ME游戏开发h?br />  
  Ҏ游戏{划或者文档要求,在某U特定的机型(以Nokia S40或S60居多)开发游戏程序。这是现在大部分J2MEE序员从事的工作?br />  
  需要熟l掌握:高用户界面、低U用L面、线E,如果是网l游戏,q需要熟l网l编E?br />  
  2、J2ME应用开发h?br />  
  现在的移动应用还不是很多Q但是还是出C一些,特别是移动定位以及移动商务相关的内容。需要熟l掌握:高用户界面、线E和|络~程?br />  
  3、J2ME游戏UL人员
  
  参照源代码,可以在一个^C可以q行的游戏移植到其他q_上去。例如将Nokia S40的游戏移植到S60上,或者烦qT618{等。主要是控制屏幕坐标Q有些可能需要替换一些API?br />  
  需要熟悉各q_之间的差异以及相关的技术参敎ͼ比如屏幕大小、最大jar文g寸{等?br />  
  五、J2MEE序设计的几个原?/b>
  
  1、用面向对象编E?br />  
  虽然使用面向q程~程可以减小文g的尺寸,但是Z以后l护的方便和利于扩展Q还是要使用面向对象~程?br />  
  2、用MVC模式
  
  模型、界面和控制分离。现在很多的E序三者合一Q但是如果你做的E序比较大的话,q是你进行分R?br />  
  3、自动存储用戯?br />  
  使用RMS来存储用L信息Q例如存储用户上ơ输入的用户名、密码、用户对于系l的讑֮{,q样不仅可以减少用户的输入,而且对用户友好。很多程序甚臛_了自动登陆等?br />  
  4、一些系l设|允许用户关闭。如背景音乐、背景灯昄{?br />  
  5、将低用户界面的绘制动作放在一个独立的U程里面厅R?br />  
  6、在需要大量时间才能完成的工作Ӟl用户一个等待界面?br />  
  六、从模拟器到真机试
  
  对于J2ME开发者来_模拟器给我们带来了很多方便,比如可以在模拟器中调试程序以及很方便的察看程序的效果Q但是模拟器也给我们带来了一些问题,比如模拟器实现的bug{等Q所以进行真机测试是必须的?br />  
  1、ؓ什么要q行真机试Q?br />  
  因ؓ模拟器程序可能存在bugQ以及真机的性能有限Q所以必进行真机测试?br />  
  2、如何将E序传输到机器中Q?br />  
  程序传输到机器中有如下方式Q?br />  
  a) OTA下蝲
  b) 使用数据U传?br />  c) U外传输
  d) 蓝牙
  
  你可以根据条Ӟ选择合适的方式?br />  
  3?真机试主要什么?
  
  真机试的内容很多,主要试以下几个斚wQ?br />  
  a) E序的功?br />  b) E序的操作性,是否易操?br />  c) E序的大?比如Nokia S40pd的手机大部分接受的最大文件尺ؓ64K
  d) E序q行速度Q速度是否可以忍受?br />  
  七、从WTK到厂商SDK
  
  对于J2ME爱好者来_基本上大安是从SUN的WTK(J2ME Wireless Toolkit)开始的Q但是对于实际应用来_仅仅使用WTK是远q不够的Q所以在学习q程中,必须完成从WTK到SDK的跨?br />  
  1、厂商SDK的下载地址Q?br />  
  ·Nokia
  Nokia不愧为手业的老大Q对于j2me的支持也是一的Q有专门的网站提供SDK和各U文档说明?br />  |址是:http://forum.nokia.com.cn/sch/index.html
  
  ·Siemens
  Siemens对于J2ME的支持也不错Q它提供了SDKQ模拟器需要独立安装。下载地址如下Q?br />  https://communication-market.siemens.de/portal/main.aspx?LangID=0&MainMenuID=2&LeftID=2&pid=1&cid=0&tid=3000&xid=0
  
  ·SonyEricsson
  SonyEricsson SDK以及自己的模拟器Q下载地址为:
  http://developer.sonyericsson.com/site/global/docstools/java/p_java.jsp
  http://mobilityworld.ericsson.com.cn/development/download_hit.asp
  
  ·Motorola
  Motorola提供了专门的SDKQ内部包含模拟器Q下载地址为:
  http://www.motocoder.com/motorola/pcsHome.jsp
  
  ·SamSung
  SamSung也提供了专门的SDK和模拟器Q下载地址为:
  http://developer.samsungmobile.com/eng/front_zone/bbs/bbs_main.jsp?p_menu_id=1500
  
  ·NECQ?br />  NEC也提供了集成模拟器的SDKQ下载地址为:
  http://www.nec-mfriend.com/cn
  
  2、厂商SDK和WTK有什么不同?
  
  厂商SDK最单的理解是在WTK的基上增加了自己的模拟器和自q扩展API。也是_你在使用厂商的SDKӞ可以使用厂商的扩展类库,例如Nokia的UIcdQ和厂商自己的模拟器而已。每个厂商的扩展API都不多,而且不尽相同?br />  
  3、如何用?
  
  有些厂商SDK的用都和WTK相同Q例如SamSung。Nokia提供了独立的界面来开发,但是q个界面在实际开发中使用不多?br />  
  4、厂商SDK的问?br />  
  厂商SDK实现q程中,有一些bugQ而且和真机实C一致。例如NOKIA的؜xN题等{?br />  
  八、在J2ME中获得手机IMEI的方?/b>
  
  IMEI是Internation mobile entity identification的简Uͼ在手Z输入*#06#可以昄该数字,长度?5位,全球唯一Q永q不会冲H,所以可以作别用L一个标志?br />  
  下面是在J2ME中获得IMEI的方法:
  
  1、MOTOpd的手机可以通过dpȝ的IMEI属性获得,代码如下Q?br />  
  String imei = System.getProperty("IMEI");
  
  2、SIEMENSpd的手机可以通过dpȝ的com.siemens.IMEI属性获得,代码如下Q?br />  
  String imei = System.getProperty("com.siemens.IMEI");
  
  九、J2ME|络q接中显C问题的解决办法
  
  在网l编E中Q有些时候会出现一些在没有接收到网l数据就昄界面的,造成界面昄不符合要求(例如公告昄Q会先显C公告的背景囄再显C公告信息)Q这里提一个简单的解决办法l大Ӟ
  
  解决q种情况的方法分成三个步骤:
  
  1、在需要显C的界面中,调用发送网l数据的Ҏ。每ơ显C时调用该构造方法,不调用Display的setCurrentҎ昄?br />  
  2、显C等待界?例如q度条等)Q给用户提示Q在q行|络q接?br />  
  3、在处理|络反馈的数据完以后Q调用Display的setCurrentҎ昄昄当前界面?img src ="http://m.tkk7.com/buaacaptain/aggbug/56854.html" width = "1" height = "1" />

舚w 2006-07-05 21:10 发表评论
]]>
վ֩ģ壺 ޾ƷóƬAV߲| һaëƬƵ| պĻۺ| ޹Ʒþ66| ޾Ʒtvþþþ| ĻӰԺ߲| 18Ůȴ| AëƬëƬ| ŮһëƬѹۿ | 뾫Ʒþþþ| ˳վ߲| þAV鶹| ޾ƷӰ߲Ʒ| һƵѹۿ | ޺ݺady޾Ʒ| ޾ƷƬ| ɫͼۺ| ѾƷԲĹۿ| պҹƵ| ѵɬɬƵ߲| ƵС˵| ŮƵվ| Ʒþþþù| Ļվ| 黨ýmvѹۿ| þùɫAVѹۿ| 99þ޾Ʒһ| պѸƬ| һng| ҹѿƬڵ | | ŷһ| ޵һAVվþþƷ˵AV | 99reƵѹۿ| ؼƷëƬѹۿ| պƷרѲ| þþƷվ| 2019Ļ6| 91ƷѹƬ| ӰƬ鶹ӰƬѹۿ| 18ڵվ|