毕业设计(论文)-基于J2ME技术的手机游戏开发.doc_第1页
毕业设计(论文)-基于J2ME技术的手机游戏开发.doc_第2页
毕业设计(论文)-基于J2ME技术的手机游戏开发.doc_第3页
毕业设计(论文)-基于J2ME技术的手机游戏开发.doc_第4页
毕业设计(论文)-基于J2ME技术的手机游戏开发.doc_第5页
已阅读5页,还剩27页未读 继续免费阅读

下载本文档

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

文档简介

1 基于基于 J2ME 技术的手机游戏开发技术的手机游戏开发 摘要摘要 随着无线通信业在近几年内取得巨大发展,手机增值服务市场前景广阔。 手机游戏融合信息技术和娱乐元素于一体,成为其中最重要的一部分。 本论文着眼基于的手机游戏开发,利用 J2ME 技术将经典的街机游戏青 蛙远行移植到手机上;探讨基于 J2ME 的手机游戏开发方法,及 J2ME 游戏 程序设计特点、游戏多手机移植和针对内存受限制特点的优化技术。 关键字关键字 J2ME;游戏开发;青蛙冒险;J2ME Polish 1 引言引言 1.1手机游戏背景介绍手机游戏背景介绍 移动游戏并不是新鲜的事物,早在 20 世纪 80 年代掌上游戏机就已经风靡一时,其中 最成功的是任天堂的游戏小子(Nintendo Game Boy)。然而,随着无线通信业的巨大发展, 以及微处理器性能的大幅提升和 Internet 的快速崛起,已经从根本上改变了通信网络、设 备与服务的整体蓝图1。手机增值服务成为巨大的商业市场,各种增值服务,如短信、彩 信、KJava 和彩铃等已经得到了市场的认可,而手机游戏正是众多热门服务中最重要的一 部分,无线专家预测 2006 年有高达 8.5 亿手机游戏玩家。手机游戏的广阔市场和巨大发展 潜力必将是移动游戏的下一个黄金时期。 手机游戏与大型在线游戏如奇幻游戏 Dungeons /判断 LEFT_KEY 与 UP_KEY 同时间按下 If(keyState byte tempo = 30; / set tempo to 120 bpm byte d = 8; / eighth-note byte C4 = ToneControl.C4; byte D4 = (byte)(C4 + 2); / a whole step byte E4 = (byte)(C4 + 4); / a major third byte G4 = (byte)(C4 + 7); / a fifth byte rest = ToneControl.SILENCE; / rest byte seq2 = ToneControl.VERSION, 1, / version 1 ToneControl.TEMPO, tempo, / set tempo ToneControl.BLOCK_START, 0, / start A 段歌曲 E4,d, D4,d, C4,d, E4,d, / 定义 A 段歌曲合唱内容 E4,d, E4,d, E4,d, rest,d, ToneControl.BLOCK_END, 0, / end A 段歌曲 ToneControl.PLAY_BLOCK, 0, / 播放 A 段 D4,d, D4,d, D4,d, rest,d,/ 播放 B 段 E4,d, G4,d, G4,d, rest,d, ToneControl.PLAY_BLOCK, 0, / 重新播放 A 段 D4,d, D4,d, E4,d, D4,d, C4,d / 播放 C 段 ; String contantType =javax.microedition.media.Manager.getSupportedContentTypes(null); for(int i =0;icontantType.length;i+) 11 if(contantTypei=audio/x-tone-seq) try tonePlayer=Manager.createPlayer(Manager.TONE_DEVICE_LOCATOR); tonePlayer.realize(); ToneControl toneControl =(ToneControl)tonePlayer.getControl(ToneControl); toneControl.setSequence(seq2); tonePlayer.setLoopCount(-1); tonePlayer.start(); catch(Exception ex) 2.4 网络网络 手机的网络能力是得天独厚的,充分利用手机丰富多样的网络通信能力将成为移动游 戏的杀手锏:J2ME 使用通用连接框架(Generic Connection Framework,GCF)为资源有限 的设备提供了一个可扩展的、通用的 I/O 框架,支持多种网络协议,如 HTTP 协议、 HTTPS 协议、串口通信、Socket 通信、UDP 协议。J2ME 扩展包技术更是使得扩展 GCF 后能够使用 Java 编写手机蓝牙、红外、USB 等通信程序。GCF 本身是一个基于 Java 语言 接口技术的框架。 图 8 GCF 框架 12 3 游戏实现游戏实现 游戏设有多个关卡,每个关卡中青蛙都有不同的任务:在第一关中,跳跃的青蛙从底 部开始,要在规定的 90 秒中通过 3 条马路到达顶部的目的地,每条马路上都有一个道具要 捡取,马路上是行使的各种汽车,青蛙不能碰撞到汽车,不然就丢掉一次机会,要重新回 到起点开始,第一关一共有三次重试机会。 图 9 游戏第一关 3.1 创建项目与应用程序管理器创建项目与应用程序管理器 在下载和安装已经发布的 Java 手机程序时都是以单个 MIDlet Suite(MIDP 程序套件) 作为单位的,每个 MIDlet Suite 包含一个或者多个 MlDlet 程序,作为对 MIDlet 进行签名 时也是以 MIDlet Suite 为单位的,数据共享、用户配置数据、持久存储等都能在同一个 MIDlet Suite 中共享,发布程序时以每个 MIDlet Suite 进行打包成 JAR 文件(一般同时间创 建一个相应的 jad 文件来描述该 JAR 文件,在网络环境中需要提供 JAR 文件发送到互联网 上供用户下载) 。 在 J2ME 游戏创建 MIDlet Suite:创建一个名称为 Frogger 的移动应用程序项目,便于 在 IDE 中管理项目资源,项目目录结构如下4: Frogger/ build.xml 项目各种操作配置文件,如运行、测试、重点配置对象, 描述各种各种扩展元素 source/src/ 游戏源码存放位置 目的地 汽车障碍 道具 起点,青蛙 13 resources/ 存放游戏资源文件位置,如:图片、字体等 nbproject/ NetBeans 项目描述文件 dist/ 最终分发打包程序存放位置 build/ 再创建一个名称为 Frogger.java 类做为游戏主类继承 javax.microedition.midlet.MIDlet: 所有的 MID 应用程序主类都必需继承自 MIDlet 类。MIDlet 实际上是一个应用程序管理器 (AMS)的接口,实际程序中通过实现 MIDlet 类的 startApp()、pauseApp()和 destroyApp()方 法来管理整个程序的生命周期: 图 10 MIDlet 程序的状态转换 下面是游戏的主类: / 引入相关的类包 import javax.microedition.midlet.MIDlet; import javax.microedition.lcdui.* public class Frogger extends MIDlet implements CommandListener private Display display; / 其它代码略:这里主要声明 Frogger 类用到成员变量,和整个游戏的全程对象 private final List mainMenu; public Frogger() super(); / 程序管理器构造 this.mainMenu = new List(Frogger, List.IMPLICIT ); / 开始运行游戏 protected void startApp() this.display = Display.getDisplay( this ); 14 this.display.setCurrent( this.mainMenu ); protected void pauseApp( ) protected void destroyApp(boolean unconditional) public void commandAction( Command cmd, Displayable screen ) 这里只是一个最基本的 MIDlet 子类,它的任务主要是启动游戏并创建一个菜单显示到屏幕 上。 3.2 CSS 菜单设计菜单设计 启动游戏时,首先展示一个启动画面和主菜单。这是用户对游戏的第一印象,必须要 力求精美。在这个游戏中我用 CSS(层叠样式表)来定制 UI 组件的:使用网页制作工具为不 同的手机制作不同外观的菜单,下图展示了为不同手机设计的菜单: 图 11 不同机型菜单风格截图: 左,默认风格,右,Sony- Ericsson/K700 首先在 build.xml 文件中配置 j2mepolish 标签:定义元素的 usePolishGui 属 性为 ture,使编译时支持 CSS。再在程序中添加预处理项,如: /Frogger 类中游戏主要导航菜单、设置 CSS 预处理: /#style mainScreen this.mainMenu = new List( Frogger, List.IMPLICIT ); /#style mainMenuItem this.mainMenu.append( Locale.get( menu.StartGame), null); /#style mainMenuItem this.mainMenu.append( Locale.get( menu.Settings), null); /#style mainMenuItem this.mainMenu.append( Locale.get( menu.About), null); 15 /#style mainMenuItem this.mainMenu.append( Locale.get( menu.Quit), null); 这样就可以在资源文件中随意的定义 CSS 外观,resources/polish.css 是为本游戏定 义的默认属性,其中的列表 CSS 属性将得到上面右幅图的菜单项效果: /例如 mainMenuItem 的 CSS 风格定义 .mainMenuItem margin: 2; padding: 5; background: none; /*获得菜单项背景透明效果*/ font-color: fontColor; font-style: bold; font-size: small; layout: center; checkbox-plain: none; checkbox-selected: url(checked.png); 3.3 游戏屏幕处理游戏屏幕处理 FroggerScreen 类是游戏的核心,它控制循环操作,包括青蛙的移动,图像的绘制以及 读取和响应用户的输入。通常连续的刷新屏幕会使得屏幕图像效果不稳定,出现如闪烁等 情况,而及时的按键响应对本游戏更为重要,这里需要使用游戏设计中两个重要的概念5: 双缓冲屏幕操作 实时按键响应(包括组合按键操作) J2ME 为优化设计为这两种操作提供了本地 API:J2ME Game API。FroggerScreen 继承 了 GameCanvas 类。绘制操作自动将下一屏幕绘制到脱机屏幕上,然后使用 flushGraphics() 直接把图像从脱机屏幕上拷贝到当前屏幕上。getKeyStates()同时间侦测从上一次操作后的 多个游戏按键的状态,使得按键不被“遗忘” ,这样保证了操作处理的实时性,甚至可以模 拟游戏操作性极强的组合按键使用。如果需要抑制主某些时间段的按键操作,只需要使用 简单的背对背调用就可以了。设计 Frogger 类: public class FroggerScreen extends GameCanvas implements Runnable public FroggerScreen( Frogger midlet ) super( true ); /开始游戏 16 public void start() Thread thread = new Thread( this ); thread.start(); public void run() int keyState = getKeyStates(); if (keyState != 0) / 处理按键状态 / 刷新屏幕: flushGraphics(); 3.4 游戏引擎设计游戏引擎设计 任何游戏的核心都不过是用来完成各种游戏任务的一个循环,在这个游戏里就是移动 的车辆,玩家,检测玩家输入,检测碰撞情况:将所有的东西渲染到 LCD 屏幕上,但是需 要足够快的速度,使的玩家有一种真实感。 为了实现这个,我们需要使用游戏循环的东西:任何需要处理的任务都是游戏循环的 一部分,通常把每秒种循环次数称为 CPS(cycles per second)及帧率,也有的称为 FPS(frames per second) 。 为了实现游戏循环,需要一个独立于应用程序的执行进程 ,这样才能对它进行控制 (如暂停程序)。在 Java 中通常有两种方法可以实现:定时器与线程。 定时器 MIDP2.0 的 GameCanvas 为我们提供了 getKeyStates()主动按键查询功能,可以主动处 理按键动作,通过 TimerTask 与 Timer 类的配合来模拟多线程,可以很方便的开启多个线 程,并且代码的结构比较清晰,但是创建类的数量比较多,系统开销稍微大一些。下面详 细进行一下介绍:Timer 类是一个定时器,可以每隔一段固定的时间做一件事情,而且可 以很方便的停止这些动作。依次为:构造对象:Timer timer = new Timer();对象创建以后, 可以使用其中的 schedule 或者是 scheduleAtFixedRate 方法起启动一个任务(Task)动作。需 要停止时,可以调用 Timer 对象的 cancel 方法实现,该方法可以停止该 Timer 启动的所有 任务(Task)。 TimerTask 类是一个线程类,所有线程的动作代码都写在该类内部。 TimerTask 是一个抽象类,在实际使用过程中,一般是继承 TimerTask 类,然后实现实际的 操作,停止 TimerTask 可以使用 TimerTask 对象里面的 cancel 方法。 线程 17 通过 Thread 类或 Runnable 接口 实现类的多线程操作控制循环,游戏使用了 Runnable 接口:Thread.sleep()方法使得线程方法更容易在游戏中控制稳定的帧率。将帧速率控制程 序段加入到 Frogger 类中: /设置游戏每秒钟最大循环次数为 30 private final static int MAX_FRAMES_PER_SECOND = 30; /计算每秒钟循环的时间为 1000/30 =33ms private final static int TIME_PER_FRAME = 1000 / MAX_FRAMES_PER_SECOND; /在主循环中控制游戏的帧速率 public void run() long lastCycleTime = System.currentTimeMillis(); long cycleStartTime; while (!this.world.gameOver) /标记循环开始时间 cycleStartTime = System.currentTimeMillis(); / move players and actors: int keyState = getKeyStates(); if (keyState != 0) /处理按键 lastCycleTime = System.currentTimeMillis(); / 绘制脱机屏幕: this.world.render(this.graphics, 0, 0 ); / 刷新屏幕: flushGraphics(); / 计算需要 sleep()的时间: long timeForFrame = System.currentTimeMillis() - cycleStartTime; if (timeForFrame TIME_PER_FRAME ) try Thread.sleep( TIME_PER_FRAME - timeForFrame ); catch (InterruptedException e) 18 3.5 制作二进制数组地图、关卡初始化文件制作二进制数组地图、关卡初始化文件 由于青蛙远行是一款关卡类游戏,每进入一关都存在大量的可重用的初始化代码, 考虑将这些数据放入二进制文件。这样每进入一关只需要读取相应的初始化文件进行关卡 初始化即可,如地图的创建、玩家坐标等等6。 这样的设计为游戏节约了大量的代码段中间,即所有的关卡只需要一份代码,而且关 卡的编辑和调试也相当简单:不需要修改任何代码,只要修改被读如的文件即可。 图 12 用二进制编辑器编辑 level1 的关卡数据 本游戏使用 J2ME Polish binaryeditor 进行编辑,将关卡地图和其它只读数据都采用这 种灵活的方式存储: world.data 定义每关公有的初始化数据,如重试次数、青蛙跳跃距离 等 level关卡序号.data 定义每关特有的初始化数据,如背景地图数组、开始坐标等 19 图 13 为关卡一编辑的二维背景地图数据 下面是游戏中关卡初始化的一段代码: private void loadNextLevel() / 清空当前关卡数据 int size = getSize(); for (int i = 0; i j2mepolish 标记时,程序将针对特殊的 API 和各手机特点进行了优化,为 不同的设备、语言环境生成相应的 JAR 包。 4.4.2 兼容兼容 MIDP1.0/MIDP2.0 相对 MIDP1.0 使用 MIDP2.0 的游戏 API 编写游戏更容易,但是 MIDP1.0 手机并不支 持 javax.microedition.lcdui.game.* API。合理的编码风格可以在 J2ME Polish 游戏引擎中使 用 Game API。J2ME Polish 通过交换 import 声明在代码里自动地编写包装类,所以需要合 理的类声明: 不该如此使用游戏引擎 public class MyGameCanvas extends javax.microedition.lcdui.game.GameCanvas implements Runnable public MyGameCanvas(boolean supress) super(supress); public void run() / main game-loop 当移植上面的代码到 MIDP1.0 设备上时,该代码将无效。下面演示了一个有效的例子, 它使用了恰当的 import 声明。 通过 import 语句恰当地使用了游戏引擎 import javax.microedition.lcdui.game.GameCanvas; public class MyGameCanvas extends GameCanvas implements Runnable public MyGameCanvas(boolean supress) super(supress); public void run() 25 / main game-loop 4.4.3 优化游戏引擎优化游戏引擎 通过在 build.xml 文件中的部分定义一些预处理变量,可以调整游戏引擎。 下面是可以达到的优化效果: 使游戏达到全屏模式 通过使用反向缓冲和平铺图片可以优化 TiledLayer 的性能 增加可能平铺图片的数量 通过执行不完善或者慢的游戏 API 来激活 MIDP2.0 设备的游戏引擎 全屏模式下运行游戏 通常可能想在全屏模式下运行游戏。可以通过在项目的 build.xml 里使用元素的 fullscreen 属性来实现。可取得值为 true,false 或者 menu。 元素的 fullscreen 属性使得所有的程序都可以在全屏模式下。如果想在游戏中 使用不同的设置,那就通过修改 polish.GameCanvas.useFullScreen 预处理变量,为 GameCanvas 定义特性的设置。可取得值仍然是 true,false,menu。下面是在 GameCanvas 全 屏模式下,如何使用 menu: 26 当在 GameCanvas 中添加命令是,你需要确保是在 menu 模式下。menu 模式需要你使 用 J2ME Polish GUI,因此不能使用 paint(Graphics)方法。因为这个方法已经在 J2ME Polish GUI 内部使用了。 在这种情况下,可以使用 flushGraphics()方法作为替代。如果这

温馨提示

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

评论

0/150

提交评论