小例子学J2ME手机游戏开发----(-)初具手机游戏框架的HelloWorld
原创 58prince http://blog.csdn.net/prince58 转载请注明出处,谢谢。
一、安装
JDK1.6
WTK2.5.2
Eclipse3.4
ecpliseMe : http://eclipseme.org/updates
JDK和WTK的安装没什么特别的,一路NEXT下去就行了。Eclipse下载完后解压出来即可以使用,打开Eclipse->help->software updates…即可弹出如上图所示的对话框,新建一个eclipseMe的site(填http://eclipseme.org/updates),选择install就可以在线安装eclipseMe.安装上还有问题的可以查看一下网站的帮助,本教程主要讲解J2ME游戏方面的,其他方面就略过了。
二、Canvas和Graphics
MIDP的图形用户界面分为两类,分别是高级图形用户界面和低级用户界面。高级图形用户界面使用起来更方便,却有失灵活性,无法自定义样式,难以达到预期的效果,所以一般手机游戏都是使用低级用户界面来处理界面上的东西,以达到更丰富更个性的界面效果。
Canvas和Graphics是我们必须熟练使用的两个类,分别代表了画布和画笔。Canvas 继承自javax.microedition.lcdui.Displayable,实现屏幕上画东西的功能,当然Canvas还提供了一些按键和触摸的监听事件。我们只需要重载Paint方法,就可以在Canvas上进行绘制了。
Graphics类通过不同的图形操作方法实现在Canvas 上画东西,常用的就是这么几项:
绘制图形基元(如矩形、直线等)
绘制文本
绘制图像
当然,低级界面中也有一些问题,所以有些时候我们需要低级界面和高级界面结合起来用,比如用高级控件来给用户输入信息(网游中常常要用到,如聊天功能)。但是不能把高级界面和低级界面放在同一个Displayable中,而越多的Displayable意味着越多的内存,所以尽可能让所有的事情都在低级界面中完成。
三、从HelloWorld开始
和惯例一样从HelloWorld开始,这个程序很简单,用低级界面实现在屏幕上显示"Hello World!"的字符串。按J2ME的规范,程序将从继承自javax.microedition.midlet.MIDlet类的子类开始运,现在先来看MIDlet类的代码如下:
import javax.microedition.midlet. MIDlet;
public class cMidlet extends MIDlet {
static cMidlet s_midletInstance;// 声明一个cMidlet的静态变量,方便在canvas内中对其进行引用。
static cGame s_cGameInstance = null;// 声明一个可视类的对象,cGame是继承自javax.microedition.lcdui.Canvas类的子类,负责程序的显示和逻辑,在后面会做详细的介绍。
public cMidlet()
{
s_midletInstance = this;// 在构造方法中将类的实例对象付给静态变量s_midletInstance。
}
// startApp()是对应父类中定义的抽象方法的实现,程序运行时此方法将被调用。
protected void startApp() {
if (s_cGameInstance == null)
{
s_cGameInstance = new cGame();
}
}
//对应父类中定义的抽象方法的实现。MIDlet进入暂停时此方法将被调用。
protected void pauseApp() {
}
//对应父类中定义的抽象方法的实现。程序结束时此方法将被调用。
protected void destroyApp(boolean arg0) {
notifyDestroyed();
}
}
Canvas类的代码如下:
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Graphics;
public class cGame extends Canvas {
static cGame s_game;
public cGame(){
Display.getDisplay(cMidlet.s_midletInstance).setCurrent(this);//将当前的displayable对象cGame设置为当前可视类对象。很多时候这一步也可以在MIDlet类中的startApp内完成。
setFullScreenMode(true);//设置全屏模式
}
protected void paint(Graphics g) {
g.setColor(0x009900);
g.fillRect(0, 0, 240, 320);
g.setColor(0x000000);
g.drawString("Hello World!", 10, 20, Graphics.LEFT|Graphics.TOP);//相关参数和功能大家自行参看WTK的帮助文档
}
}
运行效果:
四、实现Runnable接口
也许你会觉得上边这个例字相当的简单,貌似也没什么用处,不过我们稍微修改一下便能成为一个手机游戏框架的雏形。对于游戏来说,是由“帧”驱动的,即每隔一段时间将重绘一次画面,而目前的示例代码只在程序一开始系统调用一次paint,此后将不再调用,所以,我们要实现Runnable接口,控制游戏的帧刷新。
根据人的视觉能力,一般来说,一秒钟内运行25帧左右,人能看到的动画是连惯的。而实际中由于实到手机硬件的限制,有时游戏能以15帧每秒左右的速度运行,也能达到不错的运行效果。
Runnable接口的声明如下:
package java.lang;
public abstract interface Runnable {
// Methods
void run();
}
我们在cGame类添上implements Runnable,让它实现Runnable接口。同时需要实现run方法,paint()是很耗费资源的,不能时时刻刻都在paint,所以为了使游戏平稳的运行,需要对帧对行控制,下面代码中的while (System.currentTimeMillis() - s_lastFrameTimer<50)这个地方就是控制帧速的,1000毫秒/20帧 = 50毫秒,大约控制在20帧每秒的速度,每次画完paint()都做一些间隔再画。
public class cGame extends Canvas implements Runnable{
static cGame s_game;
static int s_paintCount;
static long s_lastFrameTimer;
public cGame(){
Display.getDisplay(cMidlet.s_midletInstance).setCurrent(this);
setFullScreenMode(true);
new Thread(this).start();
}
public void run() {
while (cMidlet.s_midletInstance!=null)
{
repaint();
while (System.currentTimeMillis() - s_lastFrameTimer<50)
{
Thread.yield();
}
s_lastFrameTimer = System.currentTimeMillis();
}
}
protected void paint(Graphics g) {
g.setColor(0x009900);
g.fillRect(0, 0, 240, 320);
g.setColor(0x000000);
g.drawString("Hello World!", 10, 20, Graphics.LEFT|Graphics.TOP);
g.drawString("paint count: "+ (s_paintCount++), 10, 40, Graphics.LEFT|Graphics.TOP);
}
}
运行效果如下图,和上一个例子相近,只是paint count 会不停的累加。
到此我们已经这完成了一个简单的J2ME手机游戏的框架,下边的教程会在此基础上进一步的完善。
完整代码下载:
http://www.xun6.com/file/17bb59997/HelloWorld.rar.html
调试以上代码很简单,自己新建一个J2ME的项目,把下载包里src目录下的代码COPY到你的J2ME项目的src目录即可。