毕业设计(论文)-基于JAVA的手机俄罗斯方块游戏程序设计.doc_第1页
毕业设计(论文)-基于JAVA的手机俄罗斯方块游戏程序设计.doc_第2页
毕业设计(论文)-基于JAVA的手机俄罗斯方块游戏程序设计.doc_第3页
毕业设计(论文)-基于JAVA的手机俄罗斯方块游戏程序设计.doc_第4页
毕业设计(论文)-基于JAVA的手机俄罗斯方块游戏程序设计.doc_第5页
已阅读5页,还剩14页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

JAVA手机游戏程序设计目 录一:引言1二:平台及J2ME体系结构介绍.1(一) JAVA2平台的划分和J2ME,J2SE及J2EE的关系1(二) J2ME平台介绍:2三:游戏功能设计.4(一) 游戏功能介绍4(二) 游戏功能分析4四:程序设计 5 (一)程序功能设计.5 (二) 程序中的类和类方法解析.8 1:KetrisGame模块 .8 2:KetrisCanvas模块.9 3: KetrisMap模块.10 4:KetrisBlock模块 .11五:程序仿真执行结果及编程和调试中的错误.11六: 总结. 13致谢.13参考文献.13附录一.14附录二.17附录三.17基于JAVA的手机游戏程序设计摘 要:本文通过编写一个可移植到手机上的俄罗斯方块游戏,来实现J2ME的实际应用。本文给出了详细的系统设计原理及其过程,开发出了相应的软件程序,在程序中反复运用了帖图,游戏操作,逻辑判断和线程的操作。本文还对软件的调试和运行中遇到的问题和解决方法进行了讨论。模拟运行和测试结果表明:该游戏设计合理,运行正确。一:引 言:无线通讯工业在过去的几年中飞速发展,已经成为世界上发展最快的技术领域之一。全世界移动电话的用户数量在2002年已经超过了10亿,据估计这个数字到2005年将会达到15亿,这远远超过了全世界个人电脑用户的数量。于此同时,Internet的快速崛起已经改变了现代人的生活方式。人们越来越依赖于来自Internet的信息,也将越来越不仅仅满足于通过个人电脑或办公室的工作站来访问Internet。通过便携式,无线的设备来访问Internet已经成为人们需求的方向,这就更加增大了人们对无线设备的需求。同时手机的功能也变的丰富多彩,从以前的移动电话机逐渐成为集通讯、短信、游戏、音频和视频为一体的多功能掌上电脑。想必您一定使用手机玩过游戏吧,是不是让您真实感受到移动游戏的惊奇体验。自己来编写手机游戏,并把其移植到手机中无疑成为了追求时尚的年轻人的新宠。SUN的J2ME平台恰恰为我们提供了这样的一个平台,只要掌握了基本的Java语言基础,就可以动手为自己的手机开发应用程序,使手机开发程序变的不再神秘。本文通过在J2ME平台下开发一个俄罗斯方块程序,并把它移植到手机上来学习无线设备的应用程序开发。同时对以前学过的课程(操作系统,Java语言等)进行巩固。二:平台及J2ME体系结构介绍:本文是在J2ME这个大的平台下进行开发,这就要求我们先要了解J2ME,让我们来看看JAVA2平台的划分。(一)JAVA2平台的划分和J2ME,J2SE及J2EE的关系34:目前Java2 平台已经正式划分为3 个部分它们分别是:J2SE-Java 2 平台标准版Java 2 platform standard Edition 其被使用范围最广用于我们通常使用的台式机desktop。J2EE-Java 2 平台企业版Java 2 Platform Enterprise Edition 被广泛应用于服务器上包括JSP Servlet EJB 以及目前炙手可热的Web Service 等技术。J2ME-Java 2 平台微型版Java 2 Platform Micro Edition 被使用在资源受限小型消费性电子设备上如电视机顶盒无线电话掌上电脑等。图一: Java 版本的划分和针对的设备移动设备PDA 市场的繁荣发展造成了五花八门的厂商与品种异常广泛的设备,例如两种设备也许具有相同的功能,但实现的方法可能会有相当大的区别。例如对PDA 和手持电话来说都具有显示的功能,但屏幕的实际尺寸却有很大的区别,支持的色深也不相同。重复的开发工作以及移植的不便性使得开发成本与开发难度不断提高,这就使得设备厂商要求拥有一个统一的开发平台。面对这个问题Sun 提出了J2ME 的解决方法。(二)J2ME平台介绍34: 带接入能力的消费类电子设备,如手机,传呼机,个人电子助理以及电视机顶盒之间有很多共同之处,但它们在形式,功能和特性上又有很大的差异。信息产品总是趋向于特定用途和有限的功能。要适应这些差异,对J2ME架构的要求不仅仅是小,还要有模块化能力和可定制能力。 图二:J2ME的整体架构 J2ME架构要设计成模块化的和可收缩的,以便它能支持客户和嵌入式设备市场的各种灵活的部署要求。为了达到这个目标,J2ME环境提供了一系列Java虚拟机技术,分别为市场上各种常见的多种处理器和内存布局作了优化。为了支持可定制能力和扩展能力,J2ME架构定义了三个基本的概念:Configuration,Profile和Optional Package。何谓Configuration 与Profile呢? 让我们先来看看图三。图三:Configuration和Profile设备的配置(configuration)为这些设备定义了一个基本的J2ME 运行环境,其中包括虚拟机和核心的java 类库。可以把配置理解为一个针对某一类设备的最小的Java 平台,其中包括满足该类设备的Java VM 虚拟机功能的最小子集和针对该类设备的Java 类库的最小集合。要注意的是configuration 主要针对的是系统级的特性,如基本的Java 语言的特性虚拟机的特性以及系统级的java 核心类库等。J2ME 配置Configuration 包括两种,分别是连接设备配置CDC 和连接受限设备配置CLDC。正如前面提到过的配置分别针对的是某一族系的设备J2ME 所支持的设备主要分为两种分别通过CDC 和CLDC 支持。个人移动信息设备指那些可以进行间隙性网络连接的设备,如移动电话,双向寻呼机,PDA等这类设备从性能上来讲属于低端设备由CLDC 支持。共享连接信息设备指那些网络连接固定不中断的设备,如电视机顶盒,互联网电视可视电话等这类设备从性能上来讲属于高端设备由CDC 支持。CDC,CLDC和J2SE的关系请看图四。 图四:CDC,CLDC和J2SE的关系CLDC 为那些资源受限不足以支持整个J2SE 虚拟机环境以及J2SE 核心类库的设备提供了运行Java 程序的基础。然而作为一位应用程序开发者如果您只能通过CLDC 提供的API 来进行编程是几乎不可能的。因为CLDC 中并没有提供给我们与用户存储设备网络直接交互的工具。CLDC是一个基础层,其上层可以架设一系列的描述(profiles)层来提供CLDC 所缺失的功能。每一种profile 被设计成适应某种类型的设备的形式,而移动信息设备描述Mobile Information Device Profile-MIDP 就是这些profile 中的一种。MIDP 是位于CLDC 上层的Profile,是目前J2ME 平台中发展相对最成熟最广为人知的Profile 。如同MIDP 的名字所描述的其针对的是移动信息设备Mobile Information Device。MID 这类设备通常指手机或是PDA, 它们在屏幕内存处理器等硬件特性上有诸多限制,所以说在MID 上开发应用程序必须要考虑一些技术上的特殊点。所以在开发此程序时我选择了集成有CLDC和MIDP开发包的工具WTK。WTK共分为1.0.4,2.0以及2.1三个版本,针对本程序的特点,我选择2.0版本。由于篇幅的原因,在此只作简单的介绍,详细可查阅J2ME无线设备程序设计和Java手机/PDA程序设计入门。三:游戏功能设计(一):游戏的主要功能: 游戏当然由玩家操纵方块来控制,这里设计用方向键来控制方块,向上为转动方块。 游戏有着预览的功能,就使告诉玩家下一个将出现什么类型的方块。 每个类型的方块都有各自不同的颜色。游戏能够在玩的过程中给出玩家的分数。 游戏有暂停,开始和结束等控制。(二):游戏的功能分析: 针对我手机的特点,在游戏和程序子菜单下将生成“俄罗斯方块”选项。单“选择”按钮(一功能键),将载入程序,否则将返回上级菜单。载入游戏后,将进入游戏的主菜单。主菜单中有两个选项,一是“开始游戏”,二是“帮助”。可通过手机上的导航键的上下按钮进行选择。当光标指向开始游戏,并单击“选择”按钮后,进入游戏界面。当光标指向帮助,并单击“选择”按钮后,进入帮助界面,帮助界面中是对此游戏的一些简单介绍,例如如何控制游戏等。选择“后退”可返回上级菜单。主菜单的左下角是退出选项,通过选择可回到游戏和程序菜单下。当选择开始游戏后便进入了开始游戏的界面。此时会发现手机的屏幕主要分为了两部分,左边的部分是游戏的主界面,用来显示游戏的进行情况。右边分成了二小块,最下面的为积分栏,上面是对下一个方块的预览。在游戏的右下角是暂停按钮,通过对应的功能键可使游戏进入暂停状态,并进入暂停菜单。暂停菜单下有两个选项,分别对应“继续”和“退出”,通过手机上的导航键可移动光标。当光标指向“继续”,并单击“选择”按钮后,继续回到游戏界面。当光标指向“退出”,并单击“选择”按钮后,将退出游戏,返回游戏的主菜单。此时由于游戏还未结束,所以直接退出游戏程序。在游戏进行的过程中也可通过关机键直接进入到手机开机后的初始界面,此时也不进行其他的任何操作。当游戏结束后,则弹出得分封装界面。当用户选择“确定”后得分载入手机。同样用户也可以通过选择“取消”跳过封装界面。在此游戏中主要用到了手机上的导航键和两个功能键。其中功能键主要用来对应功能的选择。而上下左右四个方向的按键分别对应与方块的变形,方块左移,方块右移和快速向下移动。 程序功能图为图五:图五:程序功能图四:程序设计: (一):程序功能设计如下:1 框架设计:在开发Java程序的时候,只要想到用户界面,就会很自然地想到AWT和SWING。但开发MIDlet时所用的用户界面组件并非这两者,而是一个全新的设计,专门针对移动通讯设备而最佳化的用户界面包-LCDUI(Limited Configuration Device UI)包。这是因为和桌上型号计算机比较起来,移动通讯设备不论在内存,操作界面,显示屏幕以及电力上都有很明显的限制。原因在于: AWT和SWING是针对桌上型计算机的硬件条件做了最优化的。但是移动通讯设备上并没有这样的条件,移动通讯设备通常只有很小的内存和速度不快的CPU。 AWT和SWING是针对使用鼠标作为输入方式的设备而设计的,而一般的通讯设备并没有鼠标。 AWT或SWING支持窗口管理的功能,比方说Layout Manager 的 设计。虽然Layout Manager可以让我们的用户界面组件容易移植,而且在窗口改变大小或是被其它窗口覆盖时,屏幕上可以有最佳的显示效果。可对于移动通讯设备来说,在屏幕上要出现重叠的窗口,或是改变窗口的大小都不太可能。 AWT或SWING所采用的消息处理机制在程序执行的时候产生许多的Event对象,这些对象通常是动态产生,而且数量很多,生命周期又短。临时对象的数量太多,会让虚拟机器的垃圾收集工作变的很沉重,尤其在内存和处理器能力有限的移动通讯设备上,会造成更沉重的负担。在LCDUI包中规定了以下几种输入设备,分别为:液晶屏幕,软件按钮,控制键,方向键以及字母数字键。能够在屏幕上显示的组件都来自Displayable这个抽象类,而Displayable又派生出了高级的Screen类和低级的 Canvas类1。其关系为图六:Javax.microedition.icdui.DisplayableJavax.microedition.icdui.CanvasJavax.microedition.icdui.Screen图六:Displayable类和派生的Screen,Canvas类2 游戏的菜单项: 游戏的菜单包括“游戏”和“帮助”2个主菜单项。在“游戏”里又有“帮助”,“暂停”选项,可通过对应的功能键选择,在“暂停”项里有“继续”,“重新开始”和“退出”三个选项。 3 编写游戏内容:在游戏里操纵的是一个个方块,所以应该编写一个类来封装这些方块。一个方块有几个属性,一个是方块的位置,包括x和y的坐标,一个是它的颜色。定义一个叫KetrisBlock的类来封装方块的这些属性。对于方块类,还会有其他的要求,还需定义一个方法,判断这个方块是不是在游戏所玩的区域里。玩的区域的定义:左上角的坐标为(0,0)(在Canvas编程中规定屏幕的左上角坐标为(0,0)。4. 编写产生新的方块组的算法: 在游戏中使得每次要产生的方块组不一样才行。预先定义7种不同的方块组。这个游戏的每个方块组都是由4个小方块组成的。每个方块组都是它所包括的4个小方块的不同组合。通过产生一个随机数,这个随机数决定要产生哪种类型的方块组。将新产生得方块组放在next变量中,再由next变量赋予pattern,通过一个switch(pattern)语句来生成方块。因为先产生的是预览的方块组。当游戏需要一个新的方块组时,应该从预览的那个方块组里取得,然后再重新产生一个预览的方块组。这样就需要定义一个方法switch(next),将预览的方块组转变为当前正在移动的那个方块。5:编写方块组移动的算法: 一个方块组应该是不断移动的。编写一个方法checkRot(),用来判断方块是否能旋转。算法checkMove()是用来判断从一个方块组移到另一个方块组,如果可以移动,则返回真;如果不可以移动,则返回假;6:编写将一行消去的算法:当方块组摆放的位置正好使得一行的方块都添满了时,应该将下一行都消去。算法为:先遍历每一行,对每一行都进行检查是不是已经填满了方块,如果已经填满了方块,则上面的方块都整体往下移动一格。在消去一行后调用方法repaintMap()。7:在游戏里实现一个线程:在这个游戏里,方块组可以自己不停的往下走,碰到下面的方块后就会在顶部产生一格新的方块组,它继续往下走,一直到整个方块组刚产生就没有路可走的时候,游戏就结束了。鉴于游戏的这个特点,打算用线程来控制这个游戏。8:控制游戏开始:在方法里先定义一个线程,然后让这个线程开始运行就可以了。当然还应该注意要重新给一些变量赋值,如游戏的分数。当点击“暂停”按钮后的开始,不是用来重新开始的,而是接着刚才的状态往下玩。那么应该在run()方法的一开始来判断游戏是否是暂停,如果是暂停的,就部将游戏的状态重新刷新一次。9:游戏暂停:这个功能可以通过将线程简单地挂起来实现。首先应该判断游戏的线程是否否为空,也就是用来判断游戏是否正在玩。如果是,则将这个线程挂起,并将GAME_SUSPEND标志赋值为GAME_SUSPEND。否则退出,不进行任何的操作。10:让游戏结束:先要判断游戏是否正在运行,如果是,则结束当前游戏的线程。否则,就不进行任何操作。11:封装得分情况:在程序的KetrisMap类中设置变量score来进行分数的统计。当有行消去时,调用方法check()来判断要消去的行和行数(最多可以同时消去4行)。然后在进行分数的重新统计。在游戏的结束时调用方法paintScore()来显示分数。 (二):程序中的类和类方法解析:1:程序整体结构如下: 列出本程序涉及的4个文件外部可见的类关系:生成KetrisMap类的对象Map,在当前画布上显示地图调用KetrisCanvas里的方法,例如清屏,游戏画布底层的渲染等 KetrisCanvas类(该类为游戏画布) KetrisMap类 KetrisGame类(主类,实现程序 的启动和关闭)KetrisBlock类调用KetrisCanvas类,生成类的对象ketris。生成KetrisBlock类的对象block,在当前画布上显示下坠物调用KetrisBlock的方法drawBrick。在当前画布上显示方块调用KetrisMap类构造,保存map 清除旧地图图七:程序可见类的关系2:程序解析如下:KetrisGame: 结构比较简单, 程序依然采用了单态结构, KetrisGame除了初始化主类DiamondCanvas, 将当前表示层display传递过去, 没有再担负其它工作.MIDlet有三种状态,分别是停止状态(Paused),激活状态(Active)和消灭状态(Destroyed)。MIDlet一开始一定是先进入停止状态,然后应用程序管理器再将它转换成激活状态,然后调用startApp()。状态图为:destroyApp()destroyApp()pauseApp()startApp()运行状态(Active)New XXX()消灭状态(Destroyed)停止状态(Paused)调用MIDlet的构造函数(无参数)图八:MIDlet的各状态及其转化 : KetrisCanvas: KetrisCanvas继承自Canvas, 是实现游戏重画, 封装逻辑运算的关键类.除了KetrisMIDlet,表示游戏地图的KetrisMap 和表示小砖块的KetrisBlock也都在KetrisCanvas中注册, 由其统一调度,产生的重绘效果.另一方面, KetrisCanvas 中还包含了对游戏开始, 暂停, 结束的各种控制. 同时还注册了命令监听器, 用于响应玩家的操作控制.各模块关系图为:KetrisBlockBRICK_COLORS:intyBrick:int#blockKetrisBlock()init()down()readPattern()readNextPattern()paint()drawBlock()isCrashAtBegin()drawBrick()drawNextBlock()checkDown()checkRot()checkMove()move()KetrisCanvasBRICK_WIDTHBACKGROUDGAMEAREA_XGAMEAREA_YKetrisCanvas()clear()commandAction()init()run()keyPressed()paint()KetrisMapSCOREFONT:FontKetrisMap()init()get()paint()check()deleteRow()paintScore() drawBlock()KetrisCanvasImportKetrisGameKetrisGame()KetrisGa()KetrisGame图九:KetrisCanvas与其他模块间的关系由上图可见, KetrisCanvas包含了清理屏幕Clear(), 初始化游戏画布, 游戏状态以及砖块边长大小的初始化方法init(), 在构造函数中, 以上两个首先被执行, 同时注册两个CommandAction事件, 用于响应用户的击键事件, 从而判断当前游戏状态. 构造函数的最后, 将整个程序作为一个新线程启动,在恒真的情况下, 每个50 毫秒就检测一次用户按键事件keyPressed(), 再重画当前画布paintCanvas(Graphics graphics).KeyPressed()用getKey()主动捕获按键状态, 是为了更好的响应用户按”下移”键的程序可玩度; 另一方面, 为了避免下降的砖块变化过于灵活, 对其它键状态的响应, 则继承了Canvas原有的keyPressed()方法, 单击一次, 执行一次.PaintCanvas(Graphics graphics)中, 程序根据不同的游戏状态重画画布, 一开始所有的重画都执行在传入参数graphics上面, 在完成所有操作后,在利用双缓冲重画方法flushGraphics()一次性画到屏幕上, 以避免色块bug。:KetrisMap:KetrisMap是游戏地图类, 包含了地图逻辑二维数组, 游戏分数统计等内部成员变量. 该类直接控制着地图逻辑变化和图层变化的维护和更新, 检查游戏图层能否消去, 当然, 还有游戏分数的控制. KetrisMap的构造函数完成初始化地图逻辑数组mapdata和当前行是否为空的任务.初始化方法init()将清空逻辑地图, 在设置逻辑上两侧墙和地面数据。get与set提供存取地图指定点逻辑值的方法。paint(Graphics g)画出两侧墙和地面砖块图像,check(Graphics g,int row)检查在指定行是否能够消行, 如果可以, 先改变当前行的地图数据, 再重画砖块。repaintMap(Graphics g)在有消去行为后调用,从容器底开始,冒泡重画容器地图。使用drawBlock(Graphics g, int y)方法,以行为单位,根据每格mapdata数据中的信息画出他们的图形。对于需要删除的行,只是使用deleteRow(Graphics g, int y)简单的把该行置黑。当然, 最后还需要提供在画布上重画得分的方法paintScore(Graphics g)。各模块关系图为:KetrisCanvasKetrisCanvas()init()run()commandAction()keyPressed()paint()clear()KetrisBlockKetrisBlock()init()readPattern()readNextPattern()paint()drawBlock()isCrashAtBegin()drawBrick()drawNextBlock()checkDown()checkRot()checkMove()move()KetrisMapKetrisMap()init()get()paint()check()deleteRow()paintScore()drawBlock()#mapMap()importimport图十:etrisMap与其他模块间的关系: KetrisBlock是响应各种图形重画的核心类。与KetrisCanvas和KetrisMap均可直接通信。在KetrisBlock中以成员变量的形式存储了7个预定义的方块逻辑数组,颜色选配方案以及相对坐标端点。KetrisBlock 定义画出单个小方砖,小方块, 以及对某个图形方块的位置,碰撞检测,移动检测,转动检测,获取坐标值,更新坐标值等操作。下面简略的分析一下KetrisBlock程序结构.首先KetrisBlock 定义了颜色数组BRICK_COLORS, 由于一种游戏方块对应一种颜色,BRICK_COLORS的索引也就唯一标识了某一个游戏方块。而二维数组blockpatternX系列则定义7种下坠物方块,包含每个方块可能的4种转换位置。KetrisBlock的构造函数中首先引用了KetrisMap的一个实例,接着随即生成了下一个游戏方块。在init()中,KetrisBlock初始化了当前下坠物和下一个下坠物,并根据当前下坠方块的初始化位置,判断游戏是否结束。方块是否能够移动,旋转都需要被KetrisBlock中类似于checkXXX()的方法判断,如果判断成功则通过move(int)移动,通过down()下移或者rotBlock()变换状态。当方块已经不能继续下移的时候,fixBlock()可以更新当前逻辑地图数据。paint(Graphics)则是通过首先清理原先背景,再调用drawBlock(Graphics g)来更新图层。总之,KetrisBlock提供粒子级别的操作方法,将底层的数组更新和画布重绘与上层的游戏逻辑隔离开。各模块关系图为:#blockKetrisBlockKetrisBlock()init()readPattern()readNextPattern()paint()drawBlock()isCrashAtBegin()drawBrick()drawNextBlock()checkDown()checkRot()checkMove()fixBlock()KetrisCanvasKetrisCanvas()init()run()commandAction()keyPressed()paint()clear()KetrisMapKetrisMap()init()get()paint()check()deleteRow()paintScore()drawBlock()Map()图十一:etrisBlock于其他模块间的关系五:程序仿真执行结果及编程和调试中的错误: 运行结果如下:图十二:运行结果图由于项目本身简单,而且大部分代码已经是相对成熟的,我们跳过单体测试;程序的完成是在不断的调试和改正中完成的,所以程序的调试是开发程序中不可缺少的很重要的一环。作为一个真正的产品要经过单体测试、结合测试和系统测试。由于此实验是个整体,所以在调试时我选择的是块细分的方法来调试。先调试一小块程序,然后再把小块组合成大块调试。步骤为:先调试界面部分,接着是方块类的调试(在界面的基础上加上方块类),其次是方块的变换,移动和按键的响应,最后是整体的调试。在程序的设计和调试中常会遇到的错误列表如下:1:MIDletStateChangeException异常:如果MIDlet在状态转换回调函数执行时发生错误2。2:java.lang.SecurityException:在MIDlet中直接调用System.exit()或Runtime.exit()来结束程序的执行2。3: java.lang.ThreadDeath:当Thread类的stop()方法以无参数形式被调用时,此错误被抛出2。部署MIDlet不像使用CLDC和MIDP API编写Java代码那么简单。MIDlet要想被传输到无线设备上,就必须将所需要的资源(包括JAD文件,JAR文件等)打包在一起,按照用户所在的区域做好配置,然后放置在一个支持无线(OTA)协议规范的服务器上让移动设备下载。现在的手机采用的操作系统(多为Symbian)已在系统中嵌入了这个协议。所以只要有一个这样的手机,都可采用数据线下载,蓝牙或者上网等多种下载方式。WTK中集成有MIDlet程序的环境,所以很容易实现应用程序的打包1。详细可参考J2ME无线设备程序设计。当程序打包完毕后,最关键的步骤就是把程序移植到手机上。我采用的是通过数据线下载方式。但由于程序的编写采用的是MIDP2.0,而手机只支持MIDP1.0,所以最后并没有下载成功,手机显示cannot creat KetrisGame MIDlet。六:总结在当今这个信息时代下,技术发展更新是飞速的,而在这其中,以无线通讯技术的发展最为迅猛。作为手机中最重要的软件功能,手机中的增值服务(例如手机游戏,特色功能)自然成为各大手机厂商关注的焦点。软件的合理设计可使硬件发挥更大的效益。反观我国的手机业,不仅在硬件反面受制于人,在软件方面也和发达的国家和企业有很大的距离。我想手机上的软件开发应该是任何手机研发者的主攻方向之一。经过毕业论文的设计,使我对手机的软件工作原理有了更深刻的了解,对自己以前的学习是一个巩固,提高了我的自学和动手能力,也锻炼了我分析问题解决问题的能力。虽然最后完成了程序在电脑上的模拟实现,但并没有在手机上得以实现。完整的分析原因,这为我以后彻底修改指明了方向。参考文献1王森编著/Java手机/PDA程序设计入门.北京:电子工业出版社,2004.32 施铮等编著/J2ME技术参考手册.北京:电子工业出版社,2004.13 (美)里格斯(Riggs,R.)等著;肖炜,郭晓刚译/J2ME无线设备程序设计:第2版北京:电子工业出版社,2004.6书名原文:Programming Wireless Devices With the Java2 Platform,Micro Edition4 温尚书编著/J2ME无线通讯实用案例教程北京:清华大学出版社,2003.10附录一、程序中类库清单:(一)KetrisGame类:此类继承了MIDlet类,为此程序的主类,也是程序的入口。在这个类中生成了类KetrisCanvas类的一个对象Ketris,在其它的类中多次用到。方法如下:KetrisGame(该类为游戏的主类)KetrisGame()startApp() pauseApp()destroyApp()KetrisGame()构造函数。首先调用MIDlet中没有参数的构造函数来初始化,如果没有没有参数的构造函数,MIDlet将无法正常的初始化,也就无法正常的启动。startApp()为程序的运行态。startApp()可能不只一次被调用而已,而是每次从停止状态重新回到运行状态的时候都会被应用程序管理器调用。pauseApp()为程序的暂停态。直接调用pauseApp()只会执行pauseApp()之中的程序代码而已,无法改变MIDlet的状态,destroyApp()为程序消灭态。除非是系统强制关闭MIDlet,否则最好MIDlet先调用destroyApp(),然后再调用notifyDestroyed(),请应用管理器帮我们将MIDlet转换到消灭状态。(二)KetrisCanvas类:此类为游戏画布类,其采用的是J2ME的底层的类库Canvas。此类 的作用就是要把画布直观的显示在手机屏幕上,其中画布包括游戏 的地图,方块的移动,反转,消行,以及分数显示等。方法如下: KetrisCanvasBRICK_WIDTH:intBACKGROUD:intGAMEAREA_X:int GAMEAREA_Y:intKetrisCanvas()init()commandAction()keyPressed() clear()KetrisCanvas()构造函数。其目的是初始化游戏的画布,在游戏中显示demo画面所需的设置,添加startCmd和exitCmd按钮,并添加按钮响应和增加游戏的线程。init()初始化函数,显示demo画面所需的设置。包括游戏画面的高度和宽度等。commandAction()按钮响应函数。当选择游戏中对应功能按钮后,游戏做出暂停,继续等响应,从而控制游戏。keyPressed()方向键响应函数。当选择上,下,左,右等方向键后,控制方块的变换和位置的移动。clear()刷新画面函数。当游戏结束或者强制退出后,游戏将以在画面上画方形并向方块中填充颜色的方式来刷新画面。(三) KetrisBlock类:该类为封装下坠物对象及其操作。游戏有预览下一个方块的功能, 方块在特殊的位置不能反转等,这些都需要游戏做出正确的响应, 在类中有正确的方法来实现。方法如下:KetrisBlockKetrisBlock()init()readPattern()readNextPattern()paint()drawBlock()isCrashAtBegin()drawBrick()drawNextBlock()checkDown()checkRot()checkMove()fixBlock()blockpatternX在游戏中有七中不同的方块,游戏中通过一个3维数祖表示不同的 方块。第一维用rot表示(旋转值),第二维用x(也就是行),第三维用y表示(也就是列)。X是通过一个随机数rand来随机产生的。KetrisBlock()类的构造函数。构造,保存map,初始化blockimage,rand,next等变量值。init():方块类的初始化函数。得到当前下坠物及在预览框中得到下一个下坠物。readPattern()设置当前下坠物变量的内容。readNextPattern()设置下一个下坠物变量的内容。只需要包含4种旋转变化中的第一种即可,所以rot维值=0paint()绘制下坠物,包括清除下坠物的旧图像,调用绘制下坠物新图像的函数。如果3维都没有变化,则无需重画。isCrashAtBegin()判断下坠物是不是和map中已有的砖块重叠,为了处理gameover的时候,只需画出部分下坠物的情况。如果返回trure,则有重叠,否则为无重叠。drawNextBlock()在游戏容器的右边绘出下一个下坠物。checkDown()判断下坠物是否能下移。如果返回true,则自动下移。否则为人工按键下移。checkMove()判断下坠物是否可以移动。move()判断方块的左右移动。fixBlock()根据下坠物的当前位置设置地图数据。(四)KetrisMap类:此类为游戏地图类,地图高16个小砖块,宽16小砖块,但是游戏容器 高16,宽12(包括左右2堵墙)。方法如下: KetrisMap KetrisMap() init() get() paint() check() deleteRow() paintScore() drawBlock()KetrisMap()类的构造函数。地图用一个2维数组来表示,2维数组mapBlockExist来表示地图的某行上是否已经存在数据。init()清除计分,把地图中的全部元素清0,并设置2堵墙和容器底。get(int ,int )获取地图某行某列的数据,前一个参数表示行号,后一个表示列号。当函数返回非0时表示有砖块。set()设置地图数据。paint()此方法其实只负责非运动砖块。check()判断是否有行需要消去。最多可以连消4行。deleteRow()删除行。当方法check()判断需要消行后,删除行,方法是只是简单的把该行置黑。repaintMap()有消去行为后调用,重画游戏地图。paintScore()在游戏画面的右部显示游戏得分。附录二、WTK使用方法:使用WTK开发应用程序,首先要建立工程。建立工程KetrisGame后,会在WTK/apps/KetrisGame中生成四个文件夹,分别为bin,lib,res,src,且都为空。其中bin目录将放置目录文件和清单文件,还有程序编译后进行合成程序而产生的JAR文件;res目录放的是程序代码之外的资源文件,如图象文件,音效文件,文本文件等;而src目录则放置所有的源代码。当程序编译后,在项目目录下产生了三个新的目录,tmpclasses放置了编译后产生的class文件,classes目录则存放了经过预先审核的class文件。编译功能只会帮我们将源文件边缘并进行预先审核,并不会自动帮我们产生JAR文件。如果要部署MIDP应用程序,则必须先包装JAR文件,也就是打包。打包好的程序放在res文件夹内。JAR文件实际上是包裹住MIDlet Suite 的文件,属于ZIP压缩格式。和JAR同在一个文件夹下的是JAD文件,也就是描述文件。用来描述MIDlet Suite基本信息的文本文件,包括MIDlet Suite 所包含的MIDlet相关信息,或是MIDlet Suite 之整体信息。这是一个外部文件,不存在JAR文件内部,是个独立的文件。J2ME MIDP 手机程序标准开发流程:模拟器测试或实机测试源代码(.java)Javac.exe打包文件和描述文件(.jar,.jad)Class文件(.class)Jar.exeJar.exePreverify.exe描述文件和清单文件(.jad,Manifest.mf)经过预先审核的class文件(.class)附录三、参考文献翻译面向对象的概念解析:The vocabulary of OOP You need to understand some of the terminology of OOP to go further. The most important term is the class. A class is the template or blueprint from which Objects are actually 实际made. This leads to the standard way of thinking about classes; as cookie cutters. Objects are the cookies themselves. When you construct an object from a class, you are said to have created an instance of the class. As you have seen, all code that you write in Java is inside a class. The standard Java library supplies several thousand classes for such diverse purposes as user interface design, dates and calendars, and network programming. Nonetheless, you still have to create your own classes in Java, to describe the objects of the problem domains of your applications, and to adapt the classes that are supplied by the standard library to your own purposes. Encapsulation (sometimes called data hiding) is a key concept in working with objects. Formally, encapsulation is nothing more than combining data and behavior in one package and hiding the implementation of the data from the user of the object. The data in an object are called its instance fields. and the functions and procedures that operate on the data are called its methods. A specific object that is an insta

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论