返回列表 发帖

[J2ME][转帖]用Eclipse开发J2ME手机游戏入门讲座

(部分图片丢失)
什么是Eclipse

  Eclipse是一个开放源代码的、与NetBeans、Sun ONE Studio和Borland Jbuilder类似的一种基于Java的整合型可扩展开发平台,也是目前最著名的开源项目之一,IBM在最近几年里也一直在大力支持该项目的发展,目标是将其做成用以替代IBM Visual Age for Java(简称IVJ)的下一代IDE开发环境,并于2001年11月宣布投入4千万美元资金到该项目的研发。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。幸运的是,Eclipse 附带了一个标准的插件集,包括 Java 开发工具(Java Development Tools,JDT)。其未来的目标不仅仅是成为专门开发Java程序的IDE环境,根据Eclipse的体系结构,通过开发插件,它能扩展到任何语言的开发,甚至能成为图片绘制的工具。

  目前,Eclipse已经开始提供C语言开发的功能插件。更难能可贵的是,Eclipse是一个开放源代码的项目,任何人都可以下载Eclipse的源代码,并且在此基础上开发自己的功能插件。也就是说未来只要有人需要,就会有建立在Eclipse之上的COBOL,Perl,Python等语言的开发插件出现。同时可以通过开发新的插件扩展现有插件的功能,比如本系列文章为了进行手机应用程序的开发就是通过J2ME插件的扩展来加以实现的。可以无限扩展,而且有着统一的外观,操作和系统资源管理,这也正是Eclipse的潜力所在。

  Eclipse的主要组成

  Eclipse是一个开放源代码的软件开发项目,专注于为高度集成的工具开发提供一个全功能的、具有商业品质的工业平台。它主要由Eclipse项目、Eclipse工具项目和Eclipse技术项目三个项目组成,具体包括四个部分组成--Eclipse Platform、JDT、CDT和PDE。JDT支持Java开发、CDT支持C开发、PDE用来支持插件开发,Eclipse Platform则是一个开放的可扩展IDE,提供了一个通用的开发平台。它提供建造块和构造并运行集成软件开发工具的基础。Eclipse Platform允许工具建造者独立开发与他人工具无缝集成的工具从而无须分辨一个工具功能在哪里结束,而另一个工具功能在哪里开始。

  Eclipse SDK(软件开发者包)是Eclipse Platform、JDT和PDE所生产的组件合并,它们可以一次下载。这些部分在一起提供了一个具有丰富特性的开发环境,允许开发者有效地建造可以无缝集成到Eclipse Platform中的工具。Eclipse SDK由Eclipse项目生产的工具和来自其它开放源代码的第三方软件组合而成。Eclipse项目生产的软件以 CPL发布,第三方组件有各自自身的许可协议。


 特性简介


  上图为Eclipse的软件界面,看上去有点象Jbilder,但是实际操作还是更象IVJ,毕竟还是由开发IVJ的原班人马主刀完成了Eclipse的开发。另外还值得一提的是Eclipse项目的参与者除了IBM以外,还有象Borland,Rational Software,RedHat,Merant等一大批业界姣姣者,这也为Eclipse的未来奠定了良好的基础。正所谓好酒不怕巷子深,Eclipse刚推出不久就创造了6个月内100万次的下载记录,还被业界推崇为工具集成平台的标准并夺得Jolt最佳IDE奖、JDJ编辑推荐IDE等殊荣。目前Eclipse联盟拥有12个成员,其中包括Borland、Fujitsu、IBM、MERANT、QNX Software Systems、Rational Software、RedHat、Serena Software、SuSE、Sybase、TogetherSoft和WebGain,此外,有超过175家的工具厂商已经或计划在Eclipse平台之上开发工具。那么Eclipse究竟是凭什么取得如此不俗的成绩呢?下面就分别从文件存放,开发环境,编译与运行,版本管理以及使用插件等方面对Eclipse的各种特性作一个简单的介绍,之后相信读者一定不会再怀疑Eclipse的能力了。

  大多IVJ的初学者都对找不到Java源代码感到非常不适应,因为IVJ把所有的源代码都存储到一个reponsitory库文件中,想要得到文本格式的源代码必须用Export功能从reponsitory中导出源代码。使用了reponsitory的IVJ对源代码的管理功能几乎达到极致,正是这一点使得许多程序员对IVJ钟爱有加。而Eclipse虽然是将源代码以文本方式保存,却仍然实现了IVJ对源代码管理的几乎全部功能,并且还增加了一些新的功能,这不能不说是Eclipse的一个亮点。

  在Eclipse的安装目录下会有一个workspace文件夹。每当新建一个项目,都会在该目录中产生和项目同名的文件夹以存放与该项目相关的全部文件。将已有的文件加入到一个项目中目前有三种方式:第一种是象在IVJ中的一样,用IDE的"文件"菜单中的"导入"功能将文件导入到项目中。这也是推荐的方式。第二种是从Windows的资源管理器中直接拖动文件到项目中。第三种就是直接将文件拷贝到项目文件夹中,然后在Eclipse的资源浏览窗口中选择项目或文件夹并执行从本地刷新功能。需要说明的一点是,项目文件夹可以放在计算机的任何位置,并且可以在Eclipse中用新建项目的方法将项目路径指定到已经存在的项目文件夹,然后在Eclipse中刷新即可。但要注意的是,任何项目文件夹建立或指定,目前都只能在Eclipse中用新建项目的方法来实现,即使是在缺省存储项目文件夹的workspace路径下新建立一个文件夹,在Eclipse环境中也是无法将它变成一个项目,也就是说,这个文件夹对Eclipse是不可视的。

  与IVJ一样,Eclipse开发环境也被称作工作台,主要由三部分组成:视图、编辑窗口和观察窗口。下图为工作台的关系结构略图:

  可以看出工作台包含多个视图,而每个视图又包含不同的窗口。每个编辑窗口有很大的共性,而且缺省情况它们都在同一区域中显示。所有文件的显示和编辑都包含在编辑窗口里。缺省情况下打开的多个文件以标签形式在同一个窗口中排列,可以用拖动方式将这些文件排列成各种布局。当有文件被加入到项目中后,在资源浏览或Java包浏览窗口双击文件,Eclipse就会试图打开这个文件:其中Eclipse内嵌的编辑器能缺省打开一些文件,如*.java,*.txt,*.class等。如果是其它类型的文件,Eclipse会调用操作系统相应的缺省编辑器打开,如word文档,PDF文件等。同时Eclipse也可以象IVJ一样用指定的编辑器打开相应的文件。Eclipse还提供了只显示所选单元的代码显示切换功能,这在编辑Java程序的时候可以以方法为单位进行编辑,不仅代码的显示更加简捷,而且还有助于编写封装性更好的类。

  浏览窗口和Java浏览窗口是观察窗口核心部分。前者和Windows的浏览器差不多,能浏览项目文件夹中的所有文件,后者用来浏览项目中的Java包,包中的类,类中的变量和方法等信息。在Java浏览窗口中可以通过用鼠标右键菜单打开层次浏览窗口,这个窗口非常实用,它能非常清晰的查看类的层次结构。类中的编译出错信息可以在任务窗口中查到,同时它也可以成为名符其实的任务窗口:向其中添加新的任务描述信息,来跟踪项目的进度。控制台则主要用来显示程序的输出信息。在调试程序的时候,会有更丰富的观察窗口来帮助程序员进行调试,如变量值察看窗口,断点窗口等等。

  观察窗口是任何IDE开发环境的核心,Eclipse也提供了丰富的观察窗口,不过要真正用好这些窗口恐怕还要经过一段时间的练习。
至于视图,实际是包括一个或多个编辑窗口和观察窗口。在开发环境的最左侧的快捷栏中的上部分显示的就是当前所打开的视图图标。视图是Eclipse的最灵活的部分,可以自定义每个视图中包含的观察窗口种类,也可以自定义一个新视图。在Eclipse的Java开发环境中提供了几种缺省视图,如资源视图、Java视图、调试视图、小组同步视图等等。每一种视图都对应不同种类的观察窗口。可以从菜单栏中的"打开透视图"看到与该视图对应的观察窗口。当然,每个视图的观察窗口都是可配置的,多样化的视图不但可以帮助程序员以不同角度观察代码,也可以满足不同的编程习惯。

  IVJ具有非常强大的调试功能,有多种跟踪方式,断点设置,变量值察看窗口等。这些在Eclipse中都也有提供。而且会根据所安装插件的不同而存在多种运行/调试程序的方式。

  Eclipse还提供了强大的个人版本管理机制,每一次被保存的更改都可以得到恢复。而且可以精确到每一个方法的版本恢复。操作也十分方便,在任何一个能看到所要操作文件的观察窗口都可以按照用户的需求找到相应的版本。强大的个人版本管理功能为程序员提供了更多的信心:只管编下去,因为任何不小心的错误都是可以恢复的。Eclipse缺省为版本管理工具CVS提供了接口,可以非常方便的连接到CVS服务器上。通过CVS版本管理,Eclipse可以为团队开发提供良好的环境。

  至于Eclipse最大的闪光点--强大的插件加载功能在文章开始就有详细的介绍,这里就不在赘述。

  小结

  正是由于Eclipse的种种优秀特性,使得Eclipse在众多整合型开发平台中脱颖而出。成为不少从事手机软件开发的程序员的首选开发工具。限于篇幅,本篇文章仅从多个方面对Eclipse作了一个大体的介绍,至于Eclipse软件的获取方式、环境配置方法等具体技术细节将在下一篇文章中进行详细介绍。

[ 本帖最后由 一生逍遥 于 2007-3-16 08:10 编辑 ]
永远的激情,永远的动力,永远的自信!

引言

  在上一篇文章中介绍了Eclipse是一款非常出色和著名的开源项目。开放源代码软件是这样一种软件,它们在发布时附带了旨在确保将某些权利授予用户的许可证。当然,最明显的权利就是源代码必须可用,以便用户能自由地修改和再分发该软件。尽管大多数开发人员不会使用Eclipse来开发插件,或创建基于Eclipse的新产品,但是由Eclipse的开放源代码性质所决定,我们在使用Eclipse 时是完全免费可用的。只需登陆Eclipse官方网站www.eclipse.org就可以获得这款优秀的IDE。

  Eclipse的下载与安装

  进入Eclipse项目的主页后点击Downloads,将出现一个镜像列表,其中大多是欧美地区的,选择一个距离比较近的镜像点(这样速度能快些)并进入下载页,笔者选择的是台湾地区的一个镜像站点http://eclipse.cdpa.nsysu.edu.tw/downloads/。目前最新版本为3.0.1。一般Eclipse同时提供几个下载版本:Release,Stable Build,Integration Build和Nightly Build,建议下载Release或Stable版本,笔者用的是Release版本。进入该版本的下载页面后Eclipse提供多种操作系统的版本,读者可以根据实际情况下载相应的压缩包。如果使用的是是在Windows平台,需要下载的正确版本为eclipse-SDK-3.0.1-win32.zip。Eclipse支持多国语言,只要下载与SDK相应的多国语言包插件就可以实现软件的本地化。对于上述版本的SDK,相应的多国语言包插件版本为eclipse3.0.1-SDK-win-LanguagePackFeature.zip。

  安装Eclipse的步骤非常简单:只需将下载的压缩包按原路径直接解压既可,可以说是一款"环保"软件。由于Eclipse版本升级比较快,如果有了更新的版本,要先删除老的版本重新安装,而不能直接解压到原来的路径覆盖老版本。之后,将多国语言包解压并将解压出来的plugins文件夹和features文件夹去覆盖eclipse文件夹下的同名文件夹即可。如果当前操作系统的JRE环境安装正确无误,现在运行Eclipse.exe将会闪现如下所示的很酷的月蚀启动画面并进入其缺省界面。



  注意,这里的前提是JRE环境的安装正确无误,由于Eclipse本身是用Java语言编写的,而下载的压缩包中并不包含Java运行环境,因此需要用户自己另行安装JRE,并且要在操作系统的环境变量中指明JRE中bin的路径。如果上述设置不正确,Eclipse是无法正常运行的。



  Eclipse的缺省欢迎界面如上图所示,中间四个按钮分别是"概述"、"教程"、"样本"和"新增内容"。这几个按钮都是帮助性质的,用户通过这些按钮可以分别了解Eclipse的所有内容、Eclipse端到端的教程、样本代码和此发行版中的新增内容。位于界面右上方的是"工作台"图标按钮,点击将转入如下所示的工作台界面:



  关于这一界面,在上一篇文章中已有简单介绍,这里就不再重复,更详细的资料可参阅Eclipse联机帮助。由于有多国语言包插件的安装,使得软件界面为全中文界面,与Visual Studio的本地化不一样,Eclipse的联机帮助也全部实现了本地化,阅读起来是非常方便的。

  环境的搭建

  如果需要配置JRE,可以安装Sun 的JDK或IBM的JDK,应该安装1.3以上版本,推荐使用1.4以上版本,因为只有使用1.4以上版本的JDK才可以享受到新增的HotSwap功能对于调试带来的方便。笔者使用的是Sun公司的1.5.0版本的 JDK,可以从Sun公司官方网站http://java.sun.com免费下载。安装完成后,可以在添加/删除程序的已安装程序列表中看见"Java 2 SDK, SE v1.5.0"和"Java 2 Runtime Environment, SE v1.5.0"项目。

  到此为止,应该能够保证Eclipse的正常运行了,但我们的最终目的是开发手机应用程序,上述搭建的环境还不能满足开发所需要的要求。Sun于1999年6月推出了Java 2袖珍版(J2ME)来满足消费电子和嵌入设备的需要。J2ME是为了那些使用有限的能源、有限的网络连接(常常是无线连接)以及有限图形用户界面能力的设备开发的。它最初的目标是 16位或32位处理器,16 MHz时钟频率,512K或更少内存的设备。 显然,现在的手机正是J2ME的一个支持方向,J2ME的标准相当多,先简单介绍几个非常重要的概念:
CLDC(Connected limited device configuration,有限连接设备配置):这个配置定义了 Java应用程序接口以及支持手持设备的技术,就像Sun的文档中所描述的那样,"devices that you hold in your hand(你握在手中的设备)"。CLDC是为使用较小的存储容量的设备设计的,用于内存在128到 512K之间的消费电子设备,智能手机、Palm序列手持设备可能是这一领域的设备的最好的例子。

  MIDP(Mobile information devices profile,移动信息设备简表):第一个实现的简表,补充了CLDC并且提供应用程序语义和控件、用户界面、持久存储器、网络和用于移动电话的计时器、双通道呼叫器和其他无线电设备。类似于J2SE中的Applet框架,它提供了基于javax、microedition、midlet包的MIDLet应用程序框架。

  MIDLet:MIDP应用程序称为 MIDlet,为了创建一个MIDlet,就必须写一个扩展基本 MIDlet类的类。这有点类似常见的Applet或Servlet。MIDlets独有的东西是把多个MIDlet组成一个MIDlet套件的能力。这就允许MIDlet在一个单独的JVM环境中共享资源,比如一个数据库等等。

  为使用J2ME开发手机应用程序还必须安装J2ME SDK,常用的有Sun公司的J2ME Wireless Toolkit(WTK)。WTK提供了运行J2ME应用程序所需要的库以及模拟器等,通过它可以进行程序的编译、校验、运行。有关WTK的信息可查询如下网址http://java.sun.com/products/j2mewtoolkit。目前J2ME Wireless Toolkit共分三个版本:1.0.4、2.0和2.1。其中,1.0.4版只能开发MIDP 1.0程序,2.0版可以开发MIDP 2.0应用程序,2.1版则可以同时开发MIDP 1.0、JTWI(CLDC 1.0、MIDP 2.0、WMA 1.1,可改用CLDC 1.1或加入MMAPI 1.1)、自定义(用户可随意组合Configuration、Profile、Optional Package)三种环境。需要注意的是,并非版本越高越好,必须视需求不同而选择适当的版本,才能开发出可以在真机上运行的MIDP应用程序。这里选用的是WTK 2.1,可以从Sun公司官方网站免费下载,按默认方式安装该工具包并记下其安装路径以便以后在安装EclipseMe插件时使用。在成功安装完毕后将在添加删除程序的已安装程序列表中看到"J2ME Wireless Toolkit 2.1"。

  这里之所以选用Sun公司的J2ME Wireless Toolkit产品,是因为这样开发出来的手机软件可以具有更大的通用性。如果用户只是出于为自己的爱机DIY应用软件的目的而非进行商业化的通用软件开发,则完全可以根据自己使用手机的型号从相应厂商网站下载与之对应的J2ME SDK,这样开发出来的手机软件能够以更优的方式在真机运行。目前,一些大的手机厂商开发的特定J2ME SDK主要有:Nokia的Nokia DEveloper's Suite与Nokia各款手机专属SDK;SonyEricsson的SonyEricsson J2ME SDK;Siemens的Siemens Mobility Toolkits等。例如,笔者使用的机型是SonyEricsson T628,相应的J2ME SDK便是SonyEricsson J2ME SDK 2.0.0_Beta版,其安装过程与前面介绍的J2ME Wireless Toolkit 2.1的安装过程类似,也同样需要记下其安装路径以备后用。如果需要更加详细的内容,请登陆手机厂商的网站查阅相关资料。

  下一步的工作

  本篇文章主要对Eclipse的工作环境进行了安装与配置,配置后的Eclipse将可以用来开发一些基本的应用程序,但离手机软件的开发还是有一段距离。下一篇文章将对手机软件开发所要用到的EclipseMe插件的安装过程进行介绍,并完成J2ME开发手机软件的全部准备工作。
永远的激情,永远的动力,永远的自信!

TOP

引言

  在上一篇文章中对Eclipse的运行环境作了配置,同时也对J2ME开发作了简要的介绍。通过上述介绍,读者应该理解:对手机应用程序的开发实际也就是进行J2ME项目的开发。虽然在上一篇文章对环境进行了配置,使其能够支持J2ME的开发,但是目前安装的Ecilpse作为一个Java应用的IDE,使用是非常方便,可是对于J2ME的开发支持还是远远不够的。为此,本文将为Eclipse安装一个开发J2ME程序的插件EclipseMe,以完成开发手机应用程序的最后一项准备工作。

  EclipseMe插件的获取

  目前EclipseMe的最新版本为0.5.5(eclipseme.feature_0.5.5_site.zip),可以登陆SourceForge网站http://eclipseme.sourceforge.net/免费下载,EclipseMe插件的版本更新速度较快,用户可以通过该网站及时获取最新版本的EclipseMe插件。

  进入SourceForge网站后点击Downloads进入产品下载页面,该页面列有全部版本的EclipseMe插件及部分版本的源程序代码。点击需要下载的eclipseme.feature_0.5.5_site.zip,将弹出一个下载镜像列表页面,可以从中选取一个距离比较近的镜像站点进行下载,不过列表中基本都是欧美地区的站点,速度也都不是很快。下载的插件大小为4240KB。

  EclipseMe插件的安装

  对于EclipseMe 0.5.0版本及更早版本的安装,可以下载后直接将其解压到Eclipse安装目录下的plugin文件夹下即可很方便的完成对插件的安装。但是到了0.5.5版本以后,EclipseMe的安装方式发生了较大变化,再用以前的方法将不能成功安装插件。下面将给出EclipseMe这一最新版本插件的具体安装过程:

  首先进入Eclipse界面并通过其"帮助"菜单下的"软件更新"弹出的"查找并安装……"菜单项弹出如下所示的"安装/更新"对话框:



  在选中"搜索要安装的新功能部件"后进入下一步安装界面:



  开始在"要包括在搜索中的站点"列表中只有"Eclipse.org更新站点"一项,为了将下载的插件安装到Eclipse,点击"新建本地站点……"按钮,这将弹出一个浏览窗口,从中指定EclipseMe压缩包的当前解压路径。虽然Eclipse对此并没有作特殊说明,但根据笔者的经验,最好将EclipseMe压缩包解压到一个路径名中不包含汉字的文件夹下,如"E:\EclipsMe\"下,否则可能会在安装过程中出现一些奇怪的小插曲而妨碍安装过程的顺利的进行。在上述操作顺利执行完毕之后,将会在站点列表中出现以当前指定目录为名称的站点项目。选中该项目前面的复选框,展开该树型结构项目,可以看见其子项EclipseME也被同时选中(见上图)。这时可以进入下一步操作:



  选中"EclipseME"前面的复选按钮,继续下一步:



  这个界面相信不用多说,点选接受版权协议即可,进入最后一个页面:



  在这个页面中,将指定Eclipse插件要安装到的路径,可以点击"添加站点"选择其他路径,不过最好还是安装到Eclipse的安装目录下,确定点击完成即可。之后,系统会弹出如下界面以提醒用户目前安装的软件没有经过数字签名。这主要是由于目前EclipseME插件包没有通过数字签名而已(维持该签名需要400美圆/年)因此对于这个提醒不用担心,继续点击安装按钮以完成程序的安装。



  随后,将随着进度条的前进开始文件安装,在安装完成后将看到如下所示的对话框请求用户重新启动工作台。点击"是"按钮将自动完成重启。


 对EclipseMe插件的配置

  为查看EclipseMe插件是否成功安装进来,可在重启Eclipse后点击"窗口"菜单下的"首选项"菜单项,将弹出如下所示配置窗口:



  只要能在左侧窗口看到J2ME项就标明EclipseMe插件已经成功安装。为了使新安装的EclipseMe插件能够正常工作,需要对其进行配置。展开J2ME项目,选中Platform Components子项,在右侧窗体将同步显示其详细配置。在Wireless Toolkits项目上单击鼠标右键,通过弹出的Add Wireless Toolkit菜单启动如下窗口:



  在该窗口点击"浏览"按钮,在弹出的浏览对话框中指定先前安装的Wireless Toolkit路径。如果路径指定正确且Wireless Toolkit也安装正确的话,此时EclipseMe将自动检测出该目录所安装的Wireless Toolkit的版本,并显示在编辑框的下方(对于本例,显示的版本为"J2ME Wireless Toolkit 2.1"),否则,说明此前安装的Wireless Toolkit有问题,需要重新安装。在点击完成按钮后,右侧的配置窗体中将显示该Wireless Toolkit所支持的一些特性,如下图所示。如果用户是针对某一机型的手机进行开发,可以重复上面的步骤将其他厂商的无线开发工具包如sonyErisson J2ME SDK添加其中。



  小结

  到此为止,对EclipseME插件的配置算是大功告成了,虽然EclipseME 0.5.5的安装比早期版本要复杂一些,但用户仍可深刻体会到Eclipse最富有魅力的插件体系结构所带来的几乎无限的扩展能力。随着EclipseME的成功安装与配置,开发手机应用程序的所有前期准备工作也都准备就绪了。接下来的文章将开始对J2ME应用程序的开发进行介绍。
永远的激情,永远的动力,永远的自信!

TOP

引言

  前面几篇文章已经介绍了Eclipse及其工作环境的安装、配置过程,并完成各项相关准备工作。因此从本文开始将讲述如何使用前面配置好的Eclipse开发环境来创建J2ME项目,开始真正的J2ME开发之旅。由于这是创建的第一个J2ME程序,按照程序开发的惯例,这头把交椅自然又是非"Hello World"莫属了。HelloWorld虽然功能简单,但是麻雀虽小,五脏俱全,通过这个小程序的开发,完全能够达到让读者熟悉J2ME程序开发一般流程的目的。

  创建J2ME项目

  与其他语言应用程序的开发类似,在开发一个J2ME程序时也要首先新建一个项目(工程)所有后续的编码、调试和运行都是在这个工程中进行。在启动Eclipse后,点击"文件"菜单下"新建"菜单弹出的"项目"菜单项。将弹出如下所示的新建项目向导对话框:



  首先需要指定创建的是什么项目,展开J2ME项目,选中J2ME Midlet Suite子项后进入下一步。该向导页(如下所示)用来设置项目名称和项目存放路径。一般取缺省路径即可,项目名称自然是经典的"HelloWorld"了。设置完毕后继续下一步的设置。







  此向导页需要对应用程序所支持的MIDP版本进行指定。如果考虑兼容性的话可以选择J2ME Wireless Toolkit 2.1 MIDP 1.0 platform。当然也可以选择MIDP 2.0,但是目前支持MIDP 2.0的手机毕竟还是少数。点击下一步对Java构建设置进行定义,通常取默认值就可以了。点击完成按钮后EclipseMe将会自动设置好项目的编辑及运行环境。可以在导航器视图中点击HelloWorld.jad项,在右侧编辑视图中将可以查看EclipseMe生成的项目结构:


 创建J2ME应用程序

         

  刚才创建的是MIDlet Suite,一般也称作MIDlet应用程序套件,可以包含一个或多个MIDlet,只是在发布时是以MIDlet Suite为单位进行。实质性的工作都是在MIDlet中完成的。因此,需要继续添加MIDlet到项目。在导航器上点击鼠标右键,从弹出菜单中选择"新建"、"其他"菜单项启动上图所示对话框,选择J2ME下的J2ME Midlet子项后进入下一步:

           

  这里需要指定包(也可以取缺省值)和名称,点击完成后EclipseMe将自动生成框架代码。可以添加必要的功能代码(阴影部分)到其中,以达到"Hello World"字符显示的目的。

package demo;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;
public class HelloWorldMIDlet extends MIDlet {
 private TextBox textbox;
 public HelloWorldMIDlet() {
  super();
  textbox = new TextBox("测试程序", "Hello World!", 20, 0);
 }
 protected void startApp() throws MIDletStateChangeException {
  Display.getDisplay(this).setCurrent(textbox);
 }
 protected void pauseApp() {
 }
 protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
 }
}

  在添加上述功能代码后会发现在前面有错误图标出现,这是由于没有导入相应的包所致。这有点类似于C++语言中缺少所引用的头文件。与C++需要手工添加对头文件的引用不同,在Eclipse中可以点击"源代码"菜单下的"组织导入"菜单项,EclipseMe将自动添加需要的包到工程:

import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.TextBox;


运行HelloWorld







  代码已经编写完毕。点击"运行"菜单下的"运行……"菜单项以弹出如上图所示配置界面。在左侧配置窗口中鼠标右键点击"Wireless Toolkit Emulator"并选择弹出菜单的"新建"菜单项,在右侧将显示如下所示的运行配置属性页,一般可选缺省设置。也可以在"Emulation"选项卡中对默认设备进行指定。通常用"DefaultClolorPhone"项即可,其模拟的是在彩屏手机上的运行效果。由于目前支持Java的手机一般配置都不是很低,绝大多数也都是彩屏配置,因此"DefaultClolorPhone"选项应该是比较大众的。当然,如何用户需要,也可以设置"DefaultGrayPhone"等其他项目以模拟在单色或其他配置的手机上的运行效果。

  最后,点击运行按钮执行我们刚才创建的第一个J2ME程序,将弹出如下所示的一个彩屏手机图案的窗口。这便是手机模拟器,可以在其上模拟手机的全部按键,功能与真机相同。观察其屏幕,显示的正是刚才编写的J2ME程序所显示的"Hello World"字样。虽然仅仅是几个字符的显示,但却标志着我们已经开始进入J2ME世界。在下一篇文章,将对J2ME程序的真机发布过程进行讲述,完成一个真正手机应用程序的制作和发布。
永远的激情,永远的动力,永远的自信!

TOP

引言

  在上一篇文章介绍了HelloWorld程序的开发过程,虽然这是一个经典的程序但并不具备任何实质性的功能而且只是在模拟器中仿真运行。经过这么长时间的学习,本文中要向读者在这段时间的学习有所交代,最起码应当让读者能够开发出一个具备简单功能的能够在真机运行的J2ME手机应用程序,也好以此向周围的同学、同事炫耀一番。相信赢得些许羡慕的目光应该不是什么难事。好了,闲话暂且不提,先简单介绍一下本文将要介绍的知识点。

  本文将通过一个简单的J2ME程序"整蛊专家"的开发向读者介绍信息框的显示、命令按钮的添加、通过文本框与用户的交互、对命令按钮的响应以及对所开发应用程序的打包发布等主要内容。最终展现给读者的将是一个能够在真机运行的J2ME手机程序。

  程序的设计

  首先,按照上一篇文章介绍的知识创建J2ME项目Test并添加MIDlet到其中。现在就在EclipseMe生成的框架代码基础上将下面阴影显示的功能代码添加到相应位置:

package demo;
import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.AlertType;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.TextBox;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;
public class Test extends MIDlet implements CommandListener {
 private TextBox textbox; // Textbox 显示一条消息
 private Display disp; // 引用MIDlet的Display 对象
 private Command cmdExit; // 设定按钮用于退出MIDlet
 private Command cmdOK; // 确定按钮
 private Alert alt; // 信息提示对象
 public Test() {
  super();
  disp = Display.getDisplay(this); // 获得当前MIDlet的Display对象
  cmdExit = new Command("退出", Command.SCREEN, 1); // 新建两个控制按钮
  cmdOK = new Command("阅读", Command.OK, 1);
  textbox = new TextBox("请输入待阅项目序号:", "", 40, 0); // 新建文本框
  textbox.addCommand(cmdExit); // 添加控制按钮
  textbox.addCommand(cmdOK);
  textbox.setCommandListener(this); // 开始侦听命令
 }
 protected void startApp() throws MIDletStateChangeException {
  alt = new Alert("整蛊专家 V1.0");// 开始运行时显示版权信息,新建信息框对象
  // 设置显示字符串
  alt.setString("==== 整蛊专家 V1.0 ====郎锐2004年作版权所有(C) 2004-2005");
  alt.setType(AlertType.INFO); // 设置为普通阅读信息框
  alt.setTimeout(Alert.FOREVER); // 信息窗口在按下DONE键后才能进入下一页面
  disp.setCurrent(alt, textbox); // 显示信息窗口
 }
 protected void pauseApp() {}
 protected void destroyApp(boolean arg0){}
 public void commandAction(Command arg0, Displayable arg1)
 {
  if (arg0 == cmdExit) { // 按下退出键时停止运行
   destroyApp(false);
   notifyDestroyed();
  }
  if (arg0 == cmdOK) { // 按下阅读键后阅读对应信息
   TextBox textbox = (TextBox)arg1; // 得到用户输入的内容
   String sInfo = textbox.getString();
   if (sInfo.equals("1") || sInfo.equals("2") || sInfo.equals("3") || sInfo.equals("4") || sInfo.equals("5")) { // 显示项目1的内容
    // 根据所选项目选择要显示的内容
    if (sInfo.equals("1")) alt.setString("一兄弟脾气甚……");
    if (sInfo.equals("2")) alt.setString("猪的四大愿望……");
    if (sInfo.equals("3")) alt.setString("春风里,百花下……");
    if (sInfo.equals("4")) alt.setString("为什么……");
    if (sInfo.equals("5")) alt.setString("昨夜做了……");
    alt.setTitle("您正在阅读短信" + sInfo); // 设置标题
   }else{
    alt.setString("很抱歉,暂时还没有您选择的项目,请重新输入!");
    alt.setTitle("错误警告"); // 设置标题
   }
   alt.setType(AlertType.INFO); // 设置为普通阅读信息框
   alt.setTimeout(Alert.FOREVER); // 信息窗口在按下DONE键后进入下一页面
   disp.setCurrent(alt, textbox); // 显示信息窗口
  }
 }
}  

  在讲述这段代码之前首先介绍一下MIDlet的生命周期:一个MIDlet在其生命周期中共有三种状态,分别是暂停、活动和停止。MIDlet被加载后首先是处于暂停状态,在J2ME调用startApp()方法后转入活动状态。通常情况下应用程序是不必考虑如何控制其运行状态的,其状态的切换由手机来决定。例如,在程序运行过程中如果有电话呼入则会自动转入暂停状态而无须在与用户交互后才能做出判断。最后,当用户按下手机的取消键时,MIDlet将进入停止状态。

  在Test类的构造函数中首先得到当前MIDlet的Display对象,以便进行界面显示。随后通过new操作符新建项目将要用到的命令按钮、文本框等高级用户界面类的对象。在创建命令按钮时,可以通过参数指定所要创建的命令按钮种类。在TextBox类方法addCommand()将其添加到文本框后需要继续调用setCommandListener()方法以开始命令的侦听,否则创建出来的命令按钮仅仅是个无法响应任何操作的摆设。由于需要处理按键,因此在这里必须实现CommandListener接口并处理commandAction方法,该方法的具体实现过程稍后在进行介绍。

  为了在程序开始之初启动程序封面,以显示版权信息、软件介绍等简介性质的文字或画面,需要在startApp()方法中添加相应的代码。这里是通过信息框来实现这一功能的。首先新建一Alert对象,并设置标题、内容信息和信息框类型。通常我们更习惯在按键之后再进入下一页面,为了实现这一效果可以在调用setTimeout()方法时指定FOREVER这一属性参数。设置完毕后通过Display的setCurrent()方法指定该信息框为当前显示界面。

  本程序具有用户交互功能,用户可以通过输入要查看短信的序号来阅读不同的短信内容。为实现该功能就要在commandAction()方法中添加代码进行处理。由于本程序添加有两种不同功能的按键,因此首先需要对第一个参数进行检查以区分当前执行的是退出命令还是确定命令。如果按下的是后者,再通过第二个参数得到用户通过键盘在文本框录入的字符并进行检测判断,对于习惯了C++编程的开发人员需要注意,在判断字符变量是否与其他字符相等时不能使用"=="操作符而要使用String的equals()方法进行判断。剩下的工作就是再以信息框将用户需要的短信显示出来即可,具体实现过程与前述方法类似。



  Eclipse在代码编写过程中会动态检查错误,在出现错误后,可以将鼠标移到在出错代码左侧的错误图标上双击鼠标,将弹出如上图所示的更改建议,用户可以在其上双击鼠标接受其建议,在右侧浮动窗口显示的代码将自动添加到适当的位置。

运行程序并打包

  代码编写无误后可以先在PC上的模拟器中运行调试,并对出现的问题进行修改,一切无误后再打包发布。在模拟器的运行过程在上一篇文章已有详细介绍,这里就不再重复。由于程序即将在真机运行,因此最好使用手机厂商提供的J2ME SDK。下图为使用SonyErisson J2ME SDK (WTK 1.0.4)和SonyErission_T630模拟器的运行过程截图:



  在程序列表中选中本程序Test,然后按下Lautch键将装载程序并进入软件首页(左2图),按下Done键进入用户交互界面(左3图)通过点击模拟器的数字按键录入要查看的短信序号并按下"阅读"键将显示相应短信内容(左4图)按下Done键后返回到前一页面,可以再次输入其他短信序号继续阅读其他短信的内容,直到按下"退出"键返回到最开始的界面(左1图)。



  显然,编写的程序并没有什么问题,可以向真机发布了。在发布时,首先要确保已经添加有对MIDlet的定义。可以在导航器视图中双击"Test.jad"项打开jad编辑器(见上图)。在编辑器下方窗口切换中选择Midlets进入Midlet定义窗体,确保有如上图所示的项目出现,否则添加之。如果需要添加图标的话,可以指定待使用的图标,但一定要预先将图标文件转换成png格式的文件。





  最后要进行的应用程序打包处理简单的几乎难以置信,只需右击项目并选择上下文菜单的"J2ME"菜单所弹出的"Create Package"菜单项即可(见上图)。EclipseMe将自动在项目存放目录下的deployed文件夹下生成两个文件,分别是Test.jad和Test.jar。只要通过手机上传软件经由数据线、红外口或是蓝牙将Test.jar上传至手机即可。当然,手机必须是支持Java的才行。如果不清楚是否支持,可查阅手机用户手册。

  小结

  到此为止,已经实现了一个真正能够在手机运行的J2ME程序。虽然最后完成的"整蛊专家"程序功能仍然有限,但是读者可以发现我们开发出来的软件与下载得到的各种Java手机程序并没有本质的差别。通过对其开发过程的剖析可以发现J2ME程序的开发并没有原先想象的那么神秘与高深。只要投入更多的精力和创意,不难写出功能更强大、界面更美观的J2ME程序。目前做到的是J2ME程序的突破,今后需要做的是不断的提高。在下一篇文章,也就是本系列文章的最后一篇文章,将在此基础上实现一个图形化的手机游戏程序。
永远的激情,永远的动力,永远的自信!

TOP

引言

  现在的手机作为一种娱乐性的电子通信设备,早已超出原先的通话、短信息等基本通信功能,越来越多的娱乐、休闲性软件如手机游戏、电子书、音乐编辑、拍照与图象处理等也都流行于当今各种品牌的手机。其中,游戏软件占有相当大的比重。既然我们已经掌握了手机软件的开发过程,为什么不自己开发一个个性化的手机游戏呢?本文将介绍一个简单的图象化手机游戏--"花皮猫大战流氓兔"的制作过程。花皮猫自然是笔者养的爱猫了,感兴趣的读者也完全可以让自己喜欢的阿猫阿狗担当游戏中的主角,充分展示DIY的魅力!

  游戏的设计

  手机游戏的开发首先需要规划好整体流程和具体的游戏规则(或游戏剧本),然后才能根据此剧本进行具体的编码实现。受文章篇幅限制,本游戏剧本设计不能太复杂。首先将游戏定位为人机对弈类游戏,程序运行开始首先显示本游戏的封面画面,停留几秒后自动转入角色选择画面,在玩家选择某一角色后开始游戏。游戏开始时随机决定哪一方先行。人机分别在3乘3大小的棋盘网格中交替落子(双方棋子图案是有区别的),而且只允许在没有落过子的空网格中下子。只要有一方所落棋子在横、竖、斜任何一方向上的总数达到三颗即获胜。如棋盘被填满时双方均未在上述方向达到三颗棋子则该局为平局。无论结果如何,在每局结束后均显示当局胜负结果与总比分。玩家可以选择退出或是重新开始新的一局。以上便是本游戏的主体框架和基本游戏规则,随后进行的编码工作便以此为依据。

  游戏框架的搭建


图1

  首先建立项目并新建一Midlet TicTacToe加入其中,继续添加ChoosePieceScreen、GameScreen和Game三个类到项目。作为一款游戏,如果仍拿文字来作软件封面显得也太不专业了。如果要在J2ME程序中使用图片,必须预先将其转换为png格式图片然后在项目上点击鼠标右键,从新建菜单下选择文件菜单项将弹出如上所示对话框。刚开始下半部分是隐藏的,需要通过点击高级按钮将其显示出来。选中链接至文件系统中的文件并通过浏览对话框指定要添加的图片路径。最后在文件名一栏输入图片的文件名并点击完成,将图片添加到项目。下面只须在startApp()中通过如下代码装载图片并通过信息框将其显示出来即可:

Image logo = null;
try {
 logo = Image.createImage("/logo.png");
}catch (IOException e) {}
Alert splashScreen = new Alert(null, "郎锐2004年作\n版权所有(c)\n2004--2005", logo, AlertType.INFO);
splashScreen.setTimeout(4000); // 延迟4秒


图2 图3 图4 图5

  在持续显示图2四秒后进入角色选择界面(图3):

choosePieceScreen = new ChoosePieceScreen(this);
Display.getDisplay(this).setCurrent(splashScreen, choosePieceScreen);

  此任务在ChoosePieceScreen类中实现,主要的功能有对角色图标的装载显示、对选定角色的确认等。在其构造函数中首先指定当前界面为列表选择方式,然后通过append()将装载的图象与相应的列表文字建立关联。最后,为了响应用户的输入选择还必须调用setCommandListener()来检测按键事件的发生,并在commandAction()方法中实现对选定角色的确认:

super("请选择:", List.IMPLICIT); // 设置列表选择
this.midlet = midlet;
append(CAT_TEXT, loadImage("/cat.png")); // 添加图象选项到列表
append(RABBIT_TEXT, loadImage("/rabbit.png"));
setCommandListener(this); // 侦听按键响应
……
public void commandAction(Command arg0, Displayable arg1) {
 if (arg0 == List.SELECT_COMMAND){
  // 检测是否为列表按键响应
  // 检测用户选中的选项
  boolean isPlayerCat = getString(getSelectedIndex()).equals(CAT_TEXT);     
  midlet.choosePieceScreenDone(isPlayerCat); // 进入游戏画面
 }
}

  这里是通过检测用户选择的列表项文字来判断玩家选择的是花皮猫还是流氓兔并通过变量isPlayerCat来标识,在choosePieceScreenDone()方法中新建一个GameScreen对象并将其作为当前显示界面来开始一局新的游戏。GameScreen类负责游戏界面的绘制,如对棋盘和双方棋子的绘制以及对光标移动的处理等工作。

  游戏界面编程

  对弈游戏最主要的界面就是棋盘与棋子的绘制。这首先要根据屏幕大小计算棋盘网格间距和棋子的大小:

screenWidth = getWidth();// 获取屏幕大小
screenHeight = getHeight();
if (screenWidth > screenHeight) {// 计算网格大小
 boardCellSize = (screenHeight - 2) / 3;
 boardLeft = (screenWidth - (boardCellSize * 3)) / 2;
 boardTop = 1;
}else{
 boardCellSize = (screenWidth - 2) / 3;
 boardLeft = 1;
 boardTop = (screenHeight - boardCellSize * 3) / 2;
}

  绘制棋盘时,首先用背景色清空整个画布然后再分别按行列绘制出黑色网格即可:

g.setColor(WHITE);
g.fillRect(0, 0, screenWidth, screenHeight);
g.setColor(BLACK);
for (int i = 0; i < 4;i++) {
 g.fillRect(boardLeft, boardCellSize*i+boardTop,(boardCellSize*3)+2,2);
 g.fillRect(boardCellSize * i + boardLeft, boardTop, 2, boardCellSize * 3);
}

  棋子的绘制可以通过在指定位置显示装载的图象来实现。例如,对于花皮猫棋子的绘制可按如下代码先装载预先准备好的图象(大小须与网格相匹配)然后再调用drawImage方法在指定位置绘制。对于流氓兔棋子的绘制只需更改待装载的图象即可:

private void drawCat(Graphics g, int x, int y) {
 Image image = null;
 try {// 装载图象
  image = Image.createImage("/cat.png");
 }catch (Exception e) {}
 g.drawImage(image, x + 1, y + 1, 0); // 在指定位置绘制图象
}

  至于对移动光标的处理,可以先在将要移动到的网格内侧绘制一个新的、四边与棋盘网格紧密相连的黑色矩形框,然后再在原网格位置用原网格背景进行重绘以擦除上次绘制的光标痕迹。在擦除旧光标痕迹时首先需要判断该位置是空白还是绘制有棋子图案,并根据判断结果绘制白色矩形或是重新装载当前显示的棋子图象。图4给出了几个回合后的游戏截图,只要游戏没有结束,上述绘制模块将会多次反复调用执行。如果程序的智能控制部分判断出游戏已经结束并给出胜负结果,则不再显示棋盘界面而是通过下面这段代码以特定的字体在白色画布上绘制出当前战绩(如图5所示)。

Font font = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_PLAIN, Font.SIZE_MEDIUM); // 设置字体
int strHeight = font.getHeight();
int statusMsgWidth = font.stringWidth(statusMsg);
int tallyMsgWidth = font.stringWidth(tallyMsg);
int strWidth = tallyMsgWidth;
if (statusMsgWidth > tallyMsgWidth)
strWidth = statusMsgWidth;
int x = (screenWidth - strWidth) / 2; // 计算字符绘制位置
x = x < 0 ? 0 : x;
int y = (screenHeight - 2 * strHeight) / 2;
y = y < 0 ? 0 : y;
g.setColor(WHITE); // 白色清空画布
g.fillRect(0, 0, screenWidth, screenHeight);
g.setColor(BLACK); // 黑色显示信息
g.drawString(statusMsg, x, y, (Graphics.TOP | Graphics.LEFT));
g.drawString(tallyMsg, x, (y + 1 + strHeight), (Graphics.TOP | Graphics.LEFT));

  在显示此界面时,如果用户按下退出或开始键,则在commandAction方法中将通过如下代码分别执行程序退出处理或是重新开始下一局新的游戏:

if (arg0 == exitCommand) // 退出
 midlet.quit();
else if (arg0 == newGameCommand) // 开始游戏
 initialize();

人工智能的实现

  如果说前面介绍的框架是骨骼,界面是皮肉的话,那么接下来将要介绍的人工智能部分则可以说是整个程序的灵魂了。它将进行对弈双方落子的合法性检测、计算机行棋的智能计算、游戏结束检测以及对胜负结果的判定等工作。以上这些都需要有合理的设计才能实现较高的游戏运行效率。考虑到游戏规则始终是围绕双方棋子的排列形状来进行的,因此可以把棋盘网格作为主要因素进行设计。按从左到右,从上到下的次序从0开始依次对棋盘的9个网格进行编号,可以得出如下几组获胜条件:0,1,2;3,4,5;6,7,8;0,3,6;1,4,7;2,5,8;0,4,8;2,4,6。只要有一方有三颗棋子的位置符合其中任何一组即可认定该方获胜(读者可以在纸上验证一下)。在程序实现过程中以WINS数组记录上述几种获胜条件,并在每一次行棋完毕后进行比对,以判断游戏是否有获胜方产生。限于篇幅,下面主要对计算机行棋思路的人工智能设计进行介绍。

  首先明确计算机的对弈目的:获胜,如果暂时无法获胜则阻止选手获胜,如果双方都暂时无法获胜则可以下一些"随手棋"。在计算出合适的下子位置后将其添加到己方的行棋记录(打谱)以备后用。由此可以写出如下代码:

int move = getWinningComputerMove();//如能立即获胜则在获胜位置下子
if (move == -1) {
 //如选手即将获胜则在选手将获胜的位置下子
 move = getRequiredBlockingComputerMove();
 if (move == -1) // 如双方均暂时无法获胜则下随手棋
  move = getRandomComputerMove();
}
computerState |= bit(move); // 当前计算机占用的所有位置

  其中,getWinningComputerMove方法通过对所有可能下子位置(即尚未落子的网格)的枚举,智能判断计算机下一步走到哪里才能获胜:

int move = -1;
for (int i = 0; i < 9;++i) {
 if (isFree(i) && isWin(computerState | bit(i))) {
  move = i; // 找到获胜位置时中断
  break;
 }
}

  如果循环完毕仍没有找到获胜位置则表示目前己方暂无法获胜,需要进一步调用getRequiredBlockingComputerMove方法来计算下一回合对方有无获胜的可能,其实现代码与getWinningComputerMove完全类似,只是以选手的行棋记录playerState替代计算机的行棋记录computerState而已。以上寥寥数行代码即构成了计算机对弈算法的人工智能核心部分,显然人工智能在实现上并没有想象的那么复杂与困难。

  小结

  通过本系列文章的介绍,陆续将J2ME手机应用程序的一般开发过程向读者作了一个较为系统和全面的介绍。尤其是本篇对图形化手机游戏的介绍相信一定对读者有不同程度的启发作用,而且本文所述程序框架完全是通用的,读者只需在此基础之上重新设计游戏剧本即可实现类似的手机游戏如"华容道"、"俄罗斯方块"等。本系列文章开发环境为:

  Windows 2000 Professional + SP4;
  Java2SDK 1.5.0;
  J2ME Wireless ToolKits 2.1;
  SonyErisson J2ME SDK(WTK 1.0.4);
  SonyErisson T628;
  Eclipse 3.0.1-win32;
  EclipseMe 0.5.5;
  NLpack-eclipse-SDK-3.0.x-win32
永远的激情,永远的动力,永远的自信!

TOP

:P 去年毕业设计就是做的手机游戏
天行健,君子以自强不息
地势坤,君子以厚德载物
   黑色海岸线欢迎您

TOP

还参加比赛呢 :L

TOP

不会做上面那个算法那么简单的吧。。。
呵呵,传代码~~~
永远的激情,永远的动力,永远的自信!

TOP

返回列表 回复 发帖