基于java的坦克大战游戏设计论文内容摘要:

的线程中。 敌方子弹仅需要扫描用户坦克,而用户坦克需要在每一步扫描所有的敌方坦克。 这需要对所有的对象有较好的控制。 另外,子弹在运行过程中也需要实时扫描是否 碰撞到了相关障碍物或屏幕边界。 如此过多的线程同时在本来效率就不高的 KVM 虚拟机上运行,也许会导致程序的缓慢。 5. 双方的坦克在前进时也需要考虑到是否碰撞到相关物体或对方坦克,以免重叠运行,造成许多物理上不可能的情况,缺乏真实感。 每一次刷新页面、每前进一步都需要将所有的周围环境都进行扫描。 6. 游戏的结束、开始、动态信息画面作为构成一个完美程序都是必不可少的重要部分。 良好的用户界面更是吸引用户的硬指标,相关的美术构图也需要有一定的考虑。 7. 游戏的地图不可能通过绘图来解决。 否则,不仅难于控制和处理 过多的元素,也会因过多的大型图片而不能限制程序的大小,失去手机上程序的原则和Java 的优势。 同时,地图关卡不宜保存在手机有限的内存中,而最好采取外部文件的读入读出方法。 8. 用户运行游戏时需要有分数记录的可能。 如何采用合理的记分标准,需要进行适当的设计。 记录分数的存储方式也需要有较好的解决方案。 手机中由于处理器和内存空间、存储空间都十分有限,其数据库系统与普通 PC大相径庭。 其数据库结构较为简单,被称之为 RMS 系统。 9. Java 是基于虚拟机的半解释型编译系统,其执行效率较 C++等完全编译后的程序会低 很多,程序如果不进行精简和优化,将可能导致运行的不流畅。 除开发过程中对结构上的控制、变量的使用、算法的优化等优化外,还可以使用混淆器 (Obfuscator)进行程序打包后的优化。 以上相关技术细节和整体流程将分别在以下小节阐述。 程序流程 MIDlet suite 是 MIDP 应用程序的最小单位, JAM 负责将手机内的 MIDlet suite 以图形化的方式呈现,让用户能够选取欲执行的 MIDlet suite,一旦选取了某个 MIDlet suite,操作系统就会激活 KVM 执行里面的 MIDlet。 MIDlet 及相关的支持类组成了 MIDP 应用程序的实际内容。 每个 MIDlet 都必须继承 这个抽象类。 在 MIDP 规格中定义了 MIDlet 的生命周期,以及可以存在的三种状态,包括Paused、 Active 以及 Destroyed,每一个 MIDlet 在任何时刻只可能处于其中的一个状态。 这三种状态的转换关系如图所示: 本程序采用面向对象的设计模式,对游戏中的所有物体赋予对象的概念和属性。 运行程序后允许用户选择执行选项菜单,在开始游戏后将先从外部文件载入地 图文件,对背景的所有物体进行绘图。 在主程序运行的线程中,画面刷新将以一定的频率采用双缓冲技术对屏幕重绘,实时反映整个游戏的进行状态。 用户控制的坦克运行在主线程中,随屏幕刷新的频率而步进。 敌方坦克将在游戏开始时逐渐新增线程,每增加一个敌方对象就新增加一条线程,一旦线程数满到最大值(本程序暂设置为 6),就不允许敌人再继续出现。 用户坦克自诞生之时起将拥有一发子弹,子弹虽然开在单独的线程中,但运行结束后(比如撞到相关物体或敌方坦克时)并不结束子弹对象,只是将其线程终止。 用户再次发射子弹时只是将终止的线程再次激活。 在 屏幕重绘的主程序中,将在每次的循环中判断若干事件。 如:用户坦克的生命是否已完全用尽,敌方坦克数是否已经为零,屏幕上的消减状态 (Destroyed) 停止状态 (Paused) 运行状态 (Active) StartApp() DestroyApp() 呼叫 MIDlet的构造函数 DestroyApp() PauseApp() 图 31 MIDlet 的流程 坦克数量是否少于仍剩下的坦克数量等。 以便程序进入相关的分支执行相关的反应代码,结束游戏或统计分数等。 主程序流程如图 32所示: 程序为需要完成独立功能的需显示的模块设置了单独的类。 TankMain 类是继承自 MIDlet 的控制主程序启动的首先被载入系统的部分。 载入程序后首先启动的是程序介绍的信息画面。 闪过后载入StartChoice 类,为用户提供可选择的选项。 在选择开始后,将运行BattleCanvas 类中的总流程控制。 它决定了游戏何时该结束,何时分配敌人数量, GameOver 字样的闪现规则,地图的绘制及整个游戏的调度。 图 33是程序中类之间的 UML 分析图。 敌方坦克与用户坦克的相关功能和具体行为分别定义在 EnemySprite 和 UserSprite 类中,它们都继承自 TankSprite图 33 与主程序相关的类的 UML 视图 Logo 画面 选项画面 主程序 屏幕绘图 本关记分统计 显示GameOver 显示历史记分表 About 开始 敌方需要出 坦克时,生成坦克 初始化参数 死亡时 符合结束条件时 图 32 本程序的主流程图 公共类,以简化程序的代码、理清结构。 在每关的结束或死亡后都将载入 ScoreScreen 类,统计当前的分数。 如果已死亡或完成所有的关数,程序将用户所得的分数记载到 RMS 数据库中,进行永久性保存。 载入过程中将 对所得分数与以往历史比较,放置到合适的位置中,形成排序。 绘图与 新增的 GameCanvas 包 提供低级绘制的 Canvas 类 为了能有程序开发人员控制接口的外观和行为,需要使用大量的初级用户接口类,尤其在游戏程序中,几乎完全依赖的就是 Canvas 抽象类进行绘图。 从程序开发的观点看, Canvas 类可与高级 Screen 类交互,程序可在需要时在 Canvas中掺入高级类的组件。 Canvas 提供了键盘事件、指点杆事件(如果设备支持),并定义了允许将键盘按键映射为游戏控制键 的函数。 键盘事件由键代码指定,但这样控制游戏会导致缺乏通用性,并不是每个设备的键盘布局都适合游戏的操作。 应当将键代码转换为游戏键的代码,以便硬件开发商能定义他们自己的游戏键布局。 本程序中,操纵用户坦克运行的按键都定义为游戏控制键,这样便能适应所有的机器。 Graphics 类 Graphics 类提供了简单的 2D 绘图功能。 它具有 24 位深度色彩的绘制能力,以三原色分别各占一个字节表示其颜色。 程序只能在 paint()函数中使用Graphics 绘制, GameCanvas 可调用 getGraphics()函数直接绘制在缓冲区上,可以在任何时间请求传输到前台。 其对象会被传给 Canvas 的 paint()函数,以便最终显示。 PNG 格式 PNG(Portable Network Graphics)格式是 MIDlet 唯一支持的图象格式, PNG具体格式由 PNG Specification,Version 定义的。 PNG格式提供透明背景的图象,这对绘制游戏画面和被操纵主角极有帮助。 坦克之间或与障碍物碰撞时就不会因为背景有特定的颜色,显示出的效果像贴上的图片而缺乏真实感,物体之间轻微重叠时最 上层图片也不会覆盖超过其有效象素外的部分。 PNG 格式图片中包含许多定义其图片特性的冗余部分 (Chunks)。 这些代码包含在每一个单独的 png 格式图象中,然而如果将多个 png 图象合并在一张幅面稍大一些的整图中,多个 chunks 就可以得到精简,图片的大小可以得到控制。 使用 Image 类中的 createImage 函数可从整图中分割出所需要的元素。 在 Game 包中的 TiledLayer 和 Sprite 类都整合了这样的功能。 本程序中的地图元素都集成在一张 图片中,实现了方便的管理和程序体积的精简。 Game 包中的新功能 MIDP 自 以后新增了 Game 包,为游戏的开发带来了极大的便利。 地图绘制、主角的动态显示、按键的检测、图层的控制等游戏专属的特性都得到了在移动设备上最大的发挥。 LayerManager(以下简称 LM)提供控制整体画面层的控制。 它包括了一系列自动获取了代号和位置的层,简化了各层加入游戏画面的过程,提供了自动排序和绘制的能力。 LM 存储了一个层的列表,新的层可以用 append 函数附加、删除和插入。 层的序号相当于坐标的 Z轴, 0层表示最接近用户视觉,层数 越高,离用户越远。 层号总是连续的,即使有中间的层被移除,其他层的序号会作相应的调整以保持整体的完整性。 LM 中的 View Window 控制着与 LM 相对坐标的可视区域。 改变 View Window 的位置可以制造出滚动屏幕的效果。 本程序中所有的地图、坦克都采用 LM控制,敌方坦克的生成由附加一个EnemySprite 对象得到。 唯有界面右侧的计分栏由 Graphics 类绘制。 Sprite 类是继承自 Layer 的用于存储多桢的基本可视元素。 不同的 frame 可交相显示,构成动态的效果。 图片可翻转、颠倒、由一个主角图片就可以 方便的得到所有方向的显示状态,相比原先只能使用 Canvas 绘图,需要将所有方向的主角图象都绘制在 png 图象中简化了许多。 Sprite 也可以从整合的图象中读图,读图时将把大图分解为若干等宽等高的小图。 每个小图按照其排列顺序有相应的序号,在程序中调用其序号,就可以绘制出相应的图片。 本程序中的双方坦克、子弹都由 Sprite 继承得到。 在有些情况下,控制主角的翻转,尤其是多幅图片配合显示的过程,如果将多图的共享定位点设置在通常的左上角,将很不容易控制,因为许多翻转都是以其他点为参考电的(比如,中心点)。 由此,引入参考 点的概念。 参考点由 defineReferencePixel 函数确定 未翻转图片状态时的坐标。 默认是 (0,0)点,如果需要,可将参考点设置在画面边界之外。 本程序中的坦克的参考点定义在图片正中,以便简便的实现转向等功能。 子弹的参考点设置在子弹底部的中心,因为子弹一出炮筒的时候紧挨着坦克的象素就是其底部中心。 TiledLayer 是有一组图象格元素 (grid of cells)组成的整块虚拟图象。 该类使不需要高分辨率的图象就能创建大幅图面成为可能。 这项技术通常应用在2D游戏平台的滚动背景的绘图。 一块整图可被分割成等 大小的图象格,每块格有其对应的序号,按照行列递增。 多块格可由大块同时替换组合而模拟动态的背景,这不需要逐块替换所有的静态图象格而显得非常方便。 本程序中的地图即为游戏背景。 每块障碍物都有其响应的代号,其中,用户需保护的总部因为体积稍大,使用了四块图象格显示。 地图背景分为 20*22 个图象格,每个格使用一个字节表示其中的障碍物,图象文件存储在外部文件中,以16进制的整数串表示,因此每个地图的大小为固定的 440 字节。 如果整块地图均由绘图产生,将导致体积迅速增加,且对坦克与障碍物的碰撞也难以检测。 J2ME中并没有 J2SE 中的 File 类,获取外部文件的手段很有限,仅仅在 Class 类中提供了一个 getResourceAsStream 函数,将外部文件获取为输入流,再由InputStream 的继承类读出。 有关绘图的一些技术 在没有 前,进行游戏绘图一般需要手动编程使用双缓冲。 需要在paint()方法内所想要画的图形画在一张预先准备好的背景,等所有绘图操作都完成后再将背景的数据拷贝到实际的屏幕上。 Image 类提供了一个建立背景的静态方法 createImage(int width, int height),再利用 getGraphics()方法取得属于这个背景的 Graphics 对象,所进行的绘图操作都会作用在背景上,等到全部的绘图操作完成后,再调用 drawImage()方法将背景的数据复制到实际显示的屏幕上。 这样的技术在绘制动画时特别有用。 绘制动画时经常需要不断地更新画面,而更新画面的操作就是先将屏幕以 fillRect()的方式清除,再将下一张图片画在屏幕上,然而反复的清除及重绘会造成屏幕的闪烁现象( flicker),因此使用双重缓冲的好处就是在背景进行这个清除及重绘的操作,再将完成的绘图拷贝到屏幕上,由于用户看不到清除的操作,因此就不会出现闪烁的现象了。 不过在某些 MIDP 的实现上已经加上了双重缓冲的支持,因此在处理前应先利用 Canvas 类的 isDoubleBuffer()方法来判断。 坦克的控制和敌方的智能运行 GameCanvas 中提供了与以往 不同的键盘采样功能。 Canvas 类中采取响应键盘事件的方法,每次执行周期时会读取 keyPressed 函数中需执行的代码。 这样的机制并不适合某些游戏场合。 在某些不支持 keyRepeat 功能的设备上,反复执行的 按键,比如发射子弹,将不能因为长时间按压而自动重复,这样就需要用户高频率的手动击键,这在操纵空间非常有限的移动设备上是非常困难的。 同时,事件的执行周期也并不一定适合游戏的场合,也许需要更高频率执行的按键却只能在指定的周期内规律的响应。 对此,针对游戏的开发,Game 包提供的键盘状态功能将显得十分有效。 GameCa。
阅读剩余 0%
本站所有文章资讯、展示的图片素材等内容均为注册用户上传(部分报媒/平媒内容转载自网络合作媒体),仅供学习参考。 用户通过本站上传、发布的任何内容的知识产权归属用户或原始著作权人所有。如有侵犯您的版权,请联系我们反馈本站将在三个工作日内改正。