J2ME手机游戏设计案例源代码-MenuCanvas
- 格式:doc
- 大小:45.50 KB
- 文档页数:6
Java自制手机联网游戏[ 录入者:admin | 时间:2006-04-18 09:51:35 | 作者:未知 | 来源:未知 | 点击数:238 ][上一篇] [下一篇]本文介绍了一个可以在手机上运行的联网游戏程序。
通过这个程序,无论在何地,只要手机能够上网就可以和Internet上的朋友联网游戏。
下面对程序的一些细节做一简要介绍,希望能给从事Java开发的技术人员一些启示。
J2ME简介J2ME(Java 2 Micro Edition)是Java 2的一个组成部分,它与J2SE、J2EE并称。
根据Sun的定义:J2ME 是一种高度优化的Java运行环境,主要针对消费类电子设备的,例如蜂窝电话和可视电话、数字机顶盒、汽车导航系统等等。
J2ME技术在1999年的JavaOne Developer Conference大会上正式推出,它将Java 语言的与平台无关的特性移植到小型电子设备上,允许移动无线设备之间共享应用程序。
J2ME的构架J2ME的构架如图1、图2所示。
图1 J2ME的构架1图2 J2ME的构架2程序运行的环境客户端即为手机(需支持J2ME的手机,例如motorola 388)用户,编程环境是Windows 2000 server + MotoJ2SDK+JDK1.3.1+MS SQL server2000,服务器端为Windows 2000 server+JDK1.3.1。
J2ME编程流程以MotoJ2SDK的开发过程为例,其流程如下所示:图3 J2ME编程流程程序简介服务器端代码的编写客户端和服务器端采用Socket连接。
服务器端需要时刻监听客户的请求(如图4),一旦有客户需求,它就需要马上响应(如图5),并做出相应的处理,然后将结果返回给客户,客户显示服务器处理结果(如图10)。
图4 服务器监听8000端口更多精彩请关注更多精彩请关注更多精彩请关注图5 服务器接受到请求并响应请求服务器端程序代码如下:try{gameServer gServer = new gameServer();//创建一个主类实例gServer.newServerSocket(gServer.port);//监听gServer.port端口while(true)//时刻等待客户端连接。
GameCanvas是MIDP2.0的⼀个最主要元素,提⾼了J2ME游戏开发的⽅便性,相对于MIDP1.0,降低了J2ME游戏开发的难度跟成本,本⽂专门详述了GameCanvas游戏画布的有关内容,对GameCanvas有个⼤概的剖析。
⼀、GameCanvas中的主要⽅法、⽅法原型跟⽅法的作⽤如下总结: 1、⽅法GameCanvas,⽅法原型protected GameCanvas(boolean suppressKeyEvents),作⽤:构造⽅法,参数suppressKeyEvents 表⽰是否需要处理游戏键之外的其他按键事件。
例如数字键,如果此参数为 false ,那么按键事件处理⽅法keyPressed ,keyRepeated , keyReleased 在程序运⾏过程中不会被调⽤,这样可以提⾼速度和性能。
2、⽅法getGraphics,⽅法原型protected Graphics getGraphics(),⽅法作⽤:得到画布中脱机屏幕上⽤于作图的Graphics 对象。
3、⽅法flushGraphics,⽅法原型public void flushGraphics(),⽅法作⽤:要求刷新屏幕,这时脱机屏幕上的图像会被绘制到真实屏幕上。
4、⽅法flushGraphics,⽅法原型public void flushGraphics(int x, int y, int width, int height),⽅法作⽤:要求刷新屏幕上指定区域,这时脱机屏幕上指定区域的图像会被绘制到真实屏幕上。
5、⽅法getKeyStates,⽅法原型public int getKeyStates(),⽅法作⽤:得到按键状态。
⼆、GameCanvas是为了⽅便游戏开发的Canvas类,从类的实现上,可以看出GameCanvas类是Canvas类的subclass,它继承了MIDP1.0中在使⽤的javax.microedition.lcdui.Canvas类,因此Canvas备置的⽅法可以直接使⽤GameCanvas. 三、GameCanvas的特征,就是⽀持取得offscreen缓冲和按键的状态。
开发易于移植的J2ME游戏(一)[ 录入者:admin | 时间:2006-05-19 17:39:30 | 作者: | 来源: | 点击数:232 ][上一篇] [下一篇]开发易于移植的J2ME游戏(一)by 蜡笔小刀(happyfire)2005.5.25说明:此文为给J2ME开发网()电子期刊的专稿,转载请先联系本人(mobiledev@)J2ME游戏开发中,移植是个问题。
各种手机的屏幕大小,按键,支持的API和性能各不相同,要想一次开发,到处运行并非易事。
本文从几个方面简要讨论一下开发易于移植的J2ME游戏的方法,每一节分别对应一个具体问题。
一不大不小的Size问题1 屏幕尺寸不等?把它看做变量!第一个问题,就是屏幕的尺寸问题。
不同牌子不同型号的手机,屏幕尺寸大小不一。
在渲染时必须考虑到尺寸的变化,即将尺寸看成两个变量 ScreenWidth和ScreenHeight,将这两个变量代入到渲染时坐标的计算式中。
这样屏幕尺寸变了,但想要的效果不会变。
举个简单的例子,现在想居中绘制一个Logo图,只要设置渲染的坐标为:x=(ScreenWidth-ImageWidth)/2; y=(ScreenHeight-ImageHeight)/2即可。
再举个RPG游戏中绘制地图的例子,假如Tile 大小为16*16,屏幕大小为128*128,则一屏正好显示8*8个Tile,但是如果直接用8*8次循环绘制这些Tile,那么程序就写死了,如果屏幕大小变了(换了一个机型或改成使用全屏)或者Tile大小变了,这些地方就要改动。
正确的方法还是将尺寸看做变量,可将Tile的宽和高定义为常量,这样需要绘制的Tile数目为 ScreenWidth/TileWidth * ScreenHeight/TileHeight。
现在你可以在各种大小的屏幕上正确显示你的地图了。
这样的例子很多,也不光是屏幕尺寸需要看作变量,凡是有可能改变的数值,将他们定义成变量或常量,那么可移植性就会提高很多。
1.1MIDlet低级界面开发技术及应用实例(第1部分)1.1.1MIDlet低级界面开发技术1、低级图形用户界面所谓低级图形用户界面,指的是那种我们可以自己在上面画图的控件。
所以比较复杂,当然也更加灵活。
游戏开发中涉及最多的是低级用户界面。
2、Canvas类低级图形用户界面是由javax.microedition.lcdui.Canvas类实现的,由于Canvas类的paint 方法被声明为抽象方法,所以Canvas类也是一个抽象类。
应用程序如果要使用,则必须扩展Canvas类。
在创建Canvas类的子类时,要求程序提供paint方法的实现,在paint方法中实现自定义的绘画行为。
public class SomeOneCanvas extends Canvas{…void paint(Graphics g){}…}由于Canvas也是Displayable类的子类,所以使用Display类中的setCurrent()方法就可以在屏幕上显示该Canvas,从而实现屏幕切换。
3、低级图形用户界面的应用示例(1)MIDP主程序代码示例package com.px1987.midpcanvas;import javax.microedition.lcdui.Display;import javax.microedition.midlet.MIDlet;import javax.microedition.midlet.MIDletStateChangeException;public class CanvasMidlet extends MIDlet {public CanvasMidlet() {}protected void destroyApp(boolean arg0) throws MIDletStateChangeException {}protected void pauseApp() {}protected void startApp() throws MIDletStateChangeException {SomeOneCanvas oneCanvas = new SomeOneCanvas ( );Display oneDisplay = Display.getDisplay(this);oneDisplay.setCurrent(oneCanvas);}}(2)SomeOneCanvas类代码示例Canvas类是低级用户界面的画布,所有的图形图像绘制和用户交互(包括按键、指针和Command)都由这个类来负责。
import java.io.IOException;import javax.microedition.lcdui.Display;import javax.microedition.lcdui.Graphics;import javax.microedition.lcdui.Image;import javax.microedition.lcdui.game.GameCanvas;import yer;import yerManager;import javax.microedition.lcdui.game.Sprite;import javax.microedition.lcdui.game.TiledLayer;import javax.microedition.midlet.MIDlet;import javax.microedition.midlet.MIDletStateChangeException;import com.sun.perseus.j2d.Transform;public class GameMIDlet extends MIDlet {private Display display;private MyGameCanvas gameCanvas;public GameMIDlet() {display = Display.getDisplay(this);gameCanvas = new MyGameCanvas();}protected void destroyApp(boolean arg0) throws MIDletStateChangeException { // TODO Auto-generated method stub}protected void pauseApp() {// TODO Auto-generated method stub}protected void startApp() throws MIDletStateChangeException {display.setCurrent(gameCanvas);new Thread(gameCanvas).start();}public class MyGameCanvas extends GameCanvas implements Runnable{ Graphics g = getGraphics();private Image img;private TiledLayer layer;private TiledLayer layerUn;private Image imgSp;private Sprite sprite;int curX,curY;boolean isMove;//记录精灵移动方向。
基于J2ME的手机游戏主菜单的设计与实现摘要刚进游戏时看到的菜单叫主菜单,手机游戏主菜单界面是集游戏中主要功能大成的界面,设计的好坏直接影响用户群的大小。
本文在分析菜单界面功能和键位使用方法的基础上,结合实际开发中的经验,阐述了手机游戏菜单的设计原则和设计流程,并给出了基于j2me的编程实现。
关键词主菜单;j2me;手机游戏中图分类号tp311 文献标识码a 文章编号1674-6708(2010)30-0230-02游戏一般有两个菜单,手机游戏也不例外:主菜单(main menu)和暂停菜单(pause menu)。
在刚进游戏时看到的菜单叫主菜单, 在游戏过程中弹出的菜单叫暂停菜单。
游戏需要有专门的代码来绘制菜单和实现菜单的功能。
其中主菜单主要提供给玩家“新游戏”、“继续”、“音乐开关”、“帮助”、“关于”、“退出游戏”等功能,主菜单界面是集游戏中主要功能大成的界面,设计的好坏直接影响用户群的大小。
由于手机内存、屏幕、键盘等的限制,手机游戏对功能的要求更高,主菜单的设计尤为重要。
1 菜单界面功能分析游戏界面作为人机交互的桥梁,其作用无可取代。
游戏玩家对游戏的直观印象,一个来自操作,另一个就是画面。
游戏界面本身就是画面的一部分,其地位举足轻重[1],通常的手机游戏主要涉及以下几个界面:1)启动界面,从程序启动到进入游戏主界面时的画面,一般制作一个简单的开始动画;2)主菜单界面:累似于文章写作中的提纲,可以点击菜单进入到相应的界面中;3)新游戏界面:通常指游戏运行中的主界面,也是新游戏的开始部分;4)继续界面,可以保存游戏进度,也可以用来作为难度选择界面来做;5)帮助界面。
主要介绍游戏规则和按键控制等;6)关于界面,这个界面即申明了版权,又可以适当作些广告;7)退出界面,可以直接退出游戏,或单独作一个界面,询问玩家是否退出游戏。
每一个游戏的菜单都是非常重要的一部分,无论是界面的美观,功能,或者版式。
1 绪论1.1 手机软件现状在信息社会中,手机及其他无线设备越来越多的走进普通百姓的工作和生活,随着信息网络化的不断进展,手机及其他无线设备上网络势在必行。
但是传统手机存在以下弊端:1. 传统手机出厂时均由硬件厂商固化程序,程序不能增加、删除,有了错误也不能更新、修改,若要增加新功能必须另换一部手机。
2. 传统手机访问互联网是通过WAP(Wireless Application Protocal),所有网络资源必须接通网络才能在线访问,非常耗时、费用亦很高。
而Java技术在无线应用方面的优势非常明显:1. 应用程序可按需下载,而不是购买由硬件商提供的套件,可升级空间大。
2. Java技术提供了一个类库,它使的应用开发商可以创建更为直觉、丰富的用户界面(GUI);3. Java技术使网络带宽的应用更为有效,因为应用程序可以下载到器件上,并在本地运行,仅仅是在连接到服务器时才会占用网络带宽。
基于以上分析,Java手机将是未来手机的发展方向,是业界的热点。
1.2 J2ME介绍虽然 Java 已经被用到许多企业级软体上,可是其实骨子里面还是非常适合用在嵌入式系统之中。
Java平台演进到Java2后,Java平台分别针对不同领域的需求被分成四个版本,亦即J2EE、J2SE、J2ME以及JavaCard。
其中J2ME定位在消费性电子产品的应用上。
这个版本针对资源有限的电子消费产品的需求精简核心类库,并提供了模块化的架构让不同类型产品能够随时增加支持的能力。
这个版本的应用层面相当广泛,会是未来Java平台发展的重点项目。
J2ME在1999年的JavaOne开发人员大会上初次亮相,它的目标是面向智能无线设备和小型计算机设备的开发人员。
J2ME的一个关键优点是,J2ME与所有支持Java的设备都是兼容的。
支持Java的设备就是任何运行Java虚拟机器的计算机。
Motorola、Nokia等生产厂商都生产支持Java的设备。
百度文库- 让每个人平等地提升自我!淮海工学院计算机工程学院实验报告书课程名:《手持设备软件开发》题目:实验3:J2ME手机游戏程序设计班级:软件学号: 1姓名:评语:成绩:指导教师:批阅时间:年月日一、实验目的与要求掌握J2ME手机游戏设计的一般方法,掌握游戏画布,分块图层,精灵和图层管理类的使用方法。
掌握控制游戏画面更新及固定帧率的方法。
二、实验内容对实例MIDP项目Game中的SimpleSprite游戏应用程序做如下的修改:1.使用动态分块修改游戏的背景使得在游戏运行过程中小花与小草连续的变换。
2.增加命令,可以控制sprite0移动的速度,同时保证画面的稳定更新。
3.sprite1在游戏开始时出现的位置随机生成,但要保证不与sprite0发生碰撞。
三、实验步骤SimpleSpriteCanvas.javapackage SimpleSprite;import javax.microedition.lcdui.*;import javax.microedition.lcdui.game.*;import java.util.*;public class SimpleSpriteCanvas extends GameCanvas{private boolean isPlay; // 值为true时游戏线程反复执行private long delay; // 线程执行时的延时,控制游戏每帧的时间private int width, height; // 保存屏幕的宽度和高度private TiledLayer background; // 定义背景为分块图层private Sprite sprite0, sprite1; //sprite0 大的, sprite1 小的private Image backImage, spriteImage; // 生成背景、精灵所用图像private final int toLeft[]={0, 1, 1, 2, 2, 3, 3, 4}; //精灵0向左运动的帧序列private final int toRight[]={5, 6, 6, 7, 7, 8, 8, 9}; //精灵0向右运动的帧序列private int xStep = 0, yStep = 0;private boolean pxCollides = false; //碰撞检测方式,默认矩形检查private boolean rightToLeft = true;private int aniIndex1, aniIndex2;private int state=1;private int moveLength=2; //初始步长private int xPosition=30,yPosition=80;// 构造方法public SimpleSpriteCanvas() {super(true);width = getWidth();height = getHeight();delay = 50;background = createBackground();sprite0 = createSprite("/SimpleSprite/sprite0.png", 56, 29);sprite1 = createSprite("/SimpleSprite/sprite1.png", 34, 27);sprite0.setPosition(180,70);createPosition();//产生随机位置sprite1.setPosition(xPosition,yPosition);collidesFind();sprite0.setFrameSequence(toLeft);sprite1.defineCollisionRectangle(0, 0, 64, 64);}// 启动线程体public void start() {isPlay = true;Thread1 thread1= new Thread1();Thread2 thread2= new Thread2();thread1.start();thread2.start();}// 停止线程执行public void stop() { isPlay = false; }// 线程体,游戏主体class Thread1 extends Thread{public void run(){Graphics g = getGraphics(); // 获取脱机屏幕缓冲区中图形对象long beginTime = 0, endTime = 0;while (isPlay == true) {beginTime = System.currentTimeMillis();queryKey(); // 查询按键状态sprite0Move();drawScreen(g); // 绘制屏幕endTime = System.currentTimeMillis();if (endTime - beginTime < delay) {try {Thread.sleep(delay - (endTime - beginTime));} catch (InterruptedException ie) { }}}}}// 主动查询按键状态,进行处理private void queryKey() {int keyStates = getKeyStates(); // 查询游戏按键状态,游戏按键被按下时if ((keyStates & LEFT_PRESSED) != 0) // 如果未超过左侧范围,向左移动xStep = -1*moveLength;if ((keyStates & RIGHT_PRESSED) !=0) // 如果未超过TiledLayer右侧范围,向右移动xStep = moveLength;if ((keyStates & UP_PRESSED) != 0) // 如果未超过TiledLayer上侧范围,向上移动yStep = -1*moveLength;if ((keyStates & DOWN_PRESSED) !=0) // 如果未超过TiledLayer下侧范围,向下移动yStep = moveLength;}// 在屏幕上显示游戏画面private void drawScreen(Graphics g) {g.setColor(0x99ccff);g.fillRect(0, 0, getWidth(), getHeight());background.paint(g);sprite0.nextFrame();sprite1.nextFrame();sprite0.paint(g);sprite1.paint(g);flushGraphics();}// 小花与小草转换class Thread2 extends Thread{public void run(){while (isPlay == true){if (state==1){background.setAnimatedTile(aniIndex1, 6);background.setAnimatedTile(aniIndex2, 5);state=0;}else{background.setAnimatedTile(aniIndex1, 5);background.setAnimatedTile(aniIndex2, 6);state=1;}try {Thread.sleep(500);} catch (InterruptedException ie) { S ystem.out.println("sleep wrong");} }}}// 建立分块图层private TiledLayer createBackground() {try {backImage = Image.createImage("/SimpleSprite/bgtiles.png");} catch (Exception e) {}TiledLayer tiledLayer = new TiledLayer(8,9,backImage,32,32);aniIndex1 = tiledLayer.createAnimatedTile(5);aniIndex2 = tiledLayer.createAnimatedTile(6);// 数组中存放单元格中需要填充的分块号int[] map = {0, 0, 7, 0, 0, 0, 8, 0,7, 0, 0, 0, 7, 0, 0, 7,0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, -2, 0, 0, 0, -1,0, 0, 1, 2, 3, -1, 1, 2,0, -2, 1, 2, 2, 2, 2, 2,1, 2, 2, 4, 4, 4, 4, 4,};// 将分块填充进相应的单元格for (int i=0; i < map.length; i++) {int column = i % 8;int row = (i - column) / 8;tiledLayer.setCell(column,row,map[i]);}return tiledLayer;}// 建立精灵private Sprite createSprite(String picName, int spriteWidth, int spriteHeight) { try {spriteImage = Image.createImage(picName);} catch (Exception e) {}Sprite sprite = new Sprite(spriteImage, spriteWidth, spriteHeight);return sprite;}private void sprite0Move() {sprite0.move(xStep, yStep); //移动// 如果方向改变则改变动画序列if (xStep > 0 && rightToLeft == true) {rightToLeft = false;sprite0.setFrameSequence(toRight);}else if (xStep < 0 && rightToLeft != true) {rightToLeft = true;sprite0.setFrameSequence(toLeft);}//检测碰撞if( sprite0.collidesWith(background,pxCollides) ||sprite0.collidesWith(sprite1,pxCollides) ) {//如果移动后和其他背景或另一个物体发生碰撞则返回到原来位置sprite0.move(-xStep*2, -yStep*2);}// 重新初始化步长xStep = yStep = 0;}public void change() {// 改变碰撞检测方式,true表示采用象素级检查,false表示采用矩形检查if (pxCollides == true)pxCollides = false;elsepxCollides = true;}public void fast(){if(moveLength<10)moveLength++;}public void slow(){if(moveLength>1)moveLength-- ;}public void createPosition(){Random rdm = new Random();xPosition = (rdm.nextInt() >>> 1)%224 ; //取0-224的随机正数yPosition = (rdm.nextInt() >>> 1)%256 ;}public void collidesFind(){while( sprite1.collidesWith(background,pxCollides) ||sprite1.collidesWith(sprite0,pxCollides) ) {createPosition();sprite1.setPosition(xPosition,yPosition);}}public void displayChange(){if (sprite1.isVisible())sprite1.setVisible(false);elsesprite1.setVisible(true);}}SimpleSpriteMidlet.javapackage SimpleSprite;import javax.microedition.midlet.*;import javax.microedition.lcdui.*;// MIDlet主程序public class SimpleSpriteMidlet extends MIDlet implements CommandListener { private Display display;private SimpleSpriteCanvas gameCanvas;private Command exitCommand, actCommand,fastCommand,slowCommand,displayCommand;// 在MIDlet启动时进行初始化工作public void startApp() {display = Display.getDisplay(this); // 获得显示屏幕对象gameCanvas = new SimpleSpriteCanvas(); // 建立GameCanvas对象// 建立Command对象exitCommand = new Command("退出", Command.EXIT, 1);actCommand = new Command("改变", Command.SCREEN, 1);fastCommand = new Command("加速", Command.SCREEN, 1);slowCommand = new Command("减速", Command.SCREEN, 1);displayCommand = new Command("小龙显隐", Command.SCREEN, 1);gameCanvas.addCommand(exitCommand);gameCanvas.addCommand(actCommand);gameCanvas.addCommand(fastCommand);gameCanvas.addCommand(slowCommand);gameCanvas.addCommand(displayCommand);gameCanvas.setCommandListener(this);gameCanvas.start(); // 启动GameCanvas中的线程体display.setCurrent(gameCanvas);}// Command事件处理程序public void commandAction(Command c, Displayable s) {if (c == exitCommand) {exit();}else if (c == actCommand) {gameCanvas.change();}else if (c == fastCommand) {gameCanvas.fast();}else if (c == slowCommand) {gameCanvas.slow();}else if (c == displayCommand) {gameCanvas.displayChange();}}public void pauseApp() { }public void destroyApp(boolean unconditional) { }// 停止线程,结束MIDlet程序public void exit() {gameCanvas.stop();destroyApp(false);notifyDestroyed();}}四、实验结果五、结果分析与实验体会这一次试验实现要求不是很难,但是不管用什么办法实现总是有不足的地方。
人工智能及识别技术ARTIFICIAL INTELLIGENCE AND IDENTIFICATION TECHNIQUES1引言目前,基本上所有的GSM手机均已内置了对J2ME的支持,即使是市场价格在几百元的低端手机,如Samsung的J708,也内置了MIDP2.0,开发人员可以直接在上面开发J2ME 应用程序。
本文采用MVC设计模式,制作一款手机游戏。
在手机游戏开发过程中引入MVC设计模式,提高手机游戏的适应性和可移植性。
使用MVC设计模式完成手机游戏“华山论剑”的总体设计和代码实现。
2J2ME(Java2MicroEdition)开发平台Java是一个通用的开发环境,在不同的操作系统以及硬件平台上构架了一个抽象层,提供各种安全机制、合理的内存管理机制、无效对象回收机制、代码的网络传输能力,使得同一份代码能够通过有线网络或者无线下载,安全地到达不同硬件上的Java的虚拟机平台。
J2ME(Java2Micro Edition)是Java2的一个组成部分,它与J2SE、J2EE并称。
为了应对移动数据的发展,推进无线电子商务等业务的发展,J2ME(Java2Micro Edition)即用于嵌入式系统的Java,被引入无线领域。
作为Java2平台的一部分,J2ME与J2SE、J2EE一道,为无线应用的客户端和服务器端建立了完整的开发、部署环境。
由于专门针对多样化的嵌入设备和消费电子设备,J2ME 的结构与传统的编程语言和规范有很大的不同,它是由配置(Configuration)、概要(Profile)和可选包(Optional Package)三要素构成。
3MVC游戏是一种特殊的图形用户界面,要求界面结构能够在不改变软件的功能和模型情况下,支持用户对界面构成的调整。
MVC由Trygve Reenskaug提出,首先被应用在SmallTalk-80环境中,是许多交互和界面系统的构成基础,Microsoft的MFC基础类也遵循了MVC的思想。
***********MenuMIDimport javax.microedition.lcdui.Display;import javax.microedition.midlet.MIDlet;/** To change this template, choose Tools | Templates* and open the template in the editor.*//** MenuMID为MIDlet主程序*/public class MenuMID extends MIDlet{private Display display;private MenuCanvas canvas; //声明画布对象canvas private MainCanvas mcanvas;public MenuMID(){display = Display.getDisplay(this); //获取Displaycanvas=null;mcanvas=null;LoadMenu(); //载入菜单}protected void startApp(){}protected void pauseApp() {}protected void destroyApp(boolean arg0) {}/* 退出程序*/public void exit() {System.gc(); //清理垃圾destroyApp(false);notifyDestroyed();}/* LoadMenu()函数用于创建菜单画布,并设置为当前显示对象*/public void LoadMenu(){canvas=null;canvas=new MenuCanvas(this); //创建菜单对象canvasdisplay.setCurrent(canvas); //设置canvas为当前显示对象}/* LoadMainCanvas()函数用于创建游戏主画布,并设置为当前显示对象*/ public void LoadMainCanvas(){canvas=null;if(mcanvas==null) //如果没有创建游戏主画布,则先创建mcanvas=new MainCanvas(this);display.setCurrent(mcanvas);}}**************MainCanvasimport javax.microedition.lcdui.Canvas;import javax.microedition.lcdui.Graphics;/** To change this template, choose Tools | Templates* and open the template in the editor.*//** MainCanvas实现程序主画面*/public class MainCanvas extends Canvas {private MenuMID mid; //声明MIDlet对象,以方便调用MIDlet/* 构造函数中,将MenuMID作为参数传入*/public MainCanvas(MenuMID midlet){super();this.setFullScreenMode(true); //设置为全屏模式mid=midlet; //将传入的MenuMID赋给mid}/* 绘图*/protected void paint(Graphics g) {//填充背景g.setColor(0x00ffffff);g.fillRect(0, 0, getWidth(), getHeight());//绘制画面内容g.setColor(0x00ff0000);//设置画笔颜色g.drawString("游戏开始", getWidth()/2, 50, Graphics.HCENTER|Graphics.BASELINE);}/* 响应按键事件,并进行处理*/protected void keyReleased(int keyCode) {int keyAction=getGameAction(keyCode); //通过按键获取游戏动作// 检查游戏动作,并作相应处理switch(keyAction){case Canvas.GAME_A:mid.LoadMenu(); //调用MIDlet以转到菜单画面break;case Canvas.GAME_B:mid.exit(); //调用MIDlet以退出程序break;}repaint(); //重绘}}***********MenuCanvasimport javax.microedition.lcdui.Canvas;import javax.microedition.lcdui.Font;import javax.microedition.lcdui.Graphics;/** MenuCanvas实现游戏菜单画面*/public class MenuCanvas extends Canvas{public MenuMID mid; //声明MIDlet对象,以方便调用MIDletstatic int CurrMenuID; //声明当前菜单索引static final String StrMenu[]={"开始","排行榜","设置","关于","退出"}; //菜单项数组static int MenuLocY; //绘制菜单时第一项的顶端Y坐标//定义中等字体private Font mediumFont=Font.getFont(Font.FACE_SYSTEM,Font.STYLE_PLAIN, Font.SIZE_MEDIUM);//定义加粗中等字体private Font mediumBoldFont=Font.getFont(Font.FACE_SYSTEM,Font.STYLE_BOLD, Font.SIZE_MEDIUM);//定义加粗大字体private Font largeFont=Font.getFont(Font.FACE_SYSTEM,Font.STYLE_BOLD, Font.SIZE_LARGE);/* 在构造函数中进行变量初始化*/public MenuCanvas(MenuMID midlet){super();setFullScreenMode(true); //设置为全屏模式this.mid=midlet; //将传入的MenuMID赋给midCurrMenuID=0; //设置开始时的默认菜单项为第1项MenuLocY=100; //设置菜单项起始Y坐标为100repaint(); //重绘}/* 绘制画面内容*/protected void paint(Graphics g) {//填充背景g.setColor(0x00ffffff);g.fillRect(0, 0, getWidth(), getHeight());//绘制标题g.setColor(0x00ff0000); //设置标题颜色g.setFont(largeFont); //设置字体g.drawString("太空之战", getWidth()/2, 50, Graphics.HCENTER|Graphics.BASELINE);//调用drawMenu()函数绘制菜单drawMenu(g,CurrMenuID);}/* 响应按键事件*/protected void keyReleased(int keyCode) {int keyAction=getGameAction(keyCode); //通过按键获取游戏动作// 检查游戏动作,并作相应处理switch(keyAction){case Canvas.UP: //选择上一项菜单CurrMenuID=Math.max(CurrMenuID-1,0);break;case Canvas.DOWN: //选择下一项菜单CurrMenuID=Math.min(CurrMenuID+1,StrMenu.length-1);break;case Canvas.FIRE: //执行所选中的菜单switch(CurrMenuID){ //判断当前选中的菜单项并执行case 0:mid.LoadMainCanvas(); //用MIDlet以加载主画面break;case 4:mid.exit(); //用MIDlet以退出程序break;}break;}repaint(); //重绘}/* drawMenu函数用于绘制菜单*/private void drawMenu(Graphics g, int menuID) {//循环绘制菜单项for(int i=0;i<5;i++){//检查是否为当前选中的菜单项if(i==menuID){//如果是当前选中的菜单项,则绘制为高亮显示g.setColor(0x00b0b0b0);g.fillRect(0,MenuLocY+(i-1)*mediumBoldFont.getHeight() , getWidth(),mediumBoldFont.getHeight());//绘制菜单项背景//绘制高亮菜单项g.setColor(0x00f0f000);g.setFont(mediumBoldFont);g.drawString(StrMenu[i], getWidth()/2, MenuLocY+i*mediumBoldFont.getHeight(), Graphics.HCENTER|Graphics.BOTTOM);}else{//绘制非高亮菜单项g.setColor(0x000080ff);g.setFont(mediumFont);g.drawString(StrMenu[i], getWidth()/2, MenuLocY+i*mediumBoldFont.getHeight() , Graphics.HCENTER|Graphics.BOTTOM);}}}}。