构建一个J2ME游戏:从GameCanvas类开始
2006-01-01 12:24
295 查看
构建一个J2ME游戏:从GameCanvas类开始GameCanvas类继承自Canvas,提供了一个屏幕后端的缓冲区,所有的绘制操作都先在这个缓冲区里进行。当所有绘制操作完成后,我们调用flushGraphics()方法将缓冲区内容输出到屏幕。这种双缓冲机制可以使图像的移动更加平滑,避免图像的闪烁。缓冲区大小等于屏幕的大小,而且每一个GameCanvas实例有且仅有一个缓冲区。
GameCanvas类提供一种存储按键状态的机制,我们可以通过它方便的了解用户与游戏的交互。这种机制可以跟踪用户按特殊键的次数,调用getKeyStates()方法返回所有游戏键按键状态的二进制表示,1代表上次调用方法后按过该键,0表示上次调用后还没有按过该键。我们可以跟踪的游戏状态有(这里的键都是在Canvas类里定义的):DOWN_PRESSED, UP_PRESSED, RIGHT_PRESSED, LEFT_PRESSED, FIRE_PRESSED, GAME_A_PRESSED, GAME_B_PRESSED, GAME_C_PRESSED和GAME_D_PRESSED。
首先扩展GameCanvas类,定制一个游戏画布,代码见清单1。清单2是运行例子的MIDlet。
package com.j2me.part3;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.game.GameCanvas;
import java.io.IOException;
public class MyGameCanvas
extends GameCanvas
implements Runnable
{
public MyGameCanvas()
{
super(true);
}
public void start()
{
try
{
//导入couple图片,坐标定位在屏幕中央
coupleImg = Image.createImage("/couple.gif");
coupleX = CENTER_X;
coupleY = CENTER_Y;
}
catch(IOException ioex)
{
System.err.println(ioex);
}
Thread runner = new Thread(this);
runner.start();
}
public void run()
{
//获取画布的graphics对象
Graphics g = getGraphics();
while(true) //无穷循环
{
//基于上一个代码清单列出的结构
//首先检查游戏状态
verifyGameState();
//检查用户输入
checkUserInput();
//更新屏幕
updateGameScreen(getGraphics());
//休息一下,控制刷新频率
try
{
Thread.currentThread().sleep(30);
}
catch(Exception e)
{}
}
}
private void verifyGameState()
{
//现在先不做任何操作
}
private void checkUserInput()
{
//获取按键信息
int keyState = getKeyStates();
//计算x轴位置
calculateCoupleX(keyState);
}
private void updateGameScreen(Graphics g)
{
//清空屏幕背景
g.setColor(0xffffff);
g.fillRect(0, 0, getWidth(), getHeight());
//将couple图片绘制到当前坐标位置
g.drawImage(
coupleImg, coupleX, coupleY, Graphics.HCENTER |
Graphics.BOTTOM);
flushGraphics();
}
private void calculateCoupleX(int keyState)
{
//判断移动方向
if((keyState & LEFT_PRESSED) != 0)
{
coupleX -= dx;
}
else if((keyState & RIGHT_PRESSED) != 0)
{
coupleX += dx;
}
}
private Image coupleImg;
private int coupleX;
private int coupleY;
private int dx = 1; //移动量
//屏幕中心
public final int CENTER_X = getWidth() / 2;
public final int CENTER_Y = getHeight() / 2;
}清单 1. MyGameCanvas:游戏画布的第一个版本
清单 2 是使用这个游戏画布的MIDlet:
package com.j2me.part3;
import javax.microedition.lcdui.Display;
import javax.microedition.midlet.MIDlet;
public class GameMIDlet extends MIDlet
{
MyGameCanvas gCanvas;
public GameMIDlet()
{
gCanvas = new MyGameCanvas();
}
public void startApp()
{
Display d = Display.getDisplay(this);
gCanvas.start();
d.setCurrent(gCanvas);
}
public void pauseApp()
{}
public void destroyApp(boolean unconditional)
{}
}清单 2. 运行游戏示例的MIDlet类
使用Wireless工具建立一个工程,导入这两个类,然后生成并运行工程。确保你的工程目录res中有这个图片文件
,并保证名称为couple.gif, 图1是运行结果。
图1. 构建一个游戏:使用GameCanvas类
使用设备的方向键可以左右移动屏幕中的小图像,这是通过从checkUserInput()里取得按键状态,然后调用calculateCoupleX(),通过将按键状态与GameCanvas里预定义的按键值进行与操作(&),得到用户当前按的键,然后将实例变量更新,最终反映到设备屏幕上。
图像是在updateGameScreen()方法里被绘制到屏幕上的。这个方法使用传入的Graphics对象进行绘制,每一个GameCanvas只有一个Graphics对象。方法首先擦除上次绘制的图像,然后基于当前的coupleX值(还有一直不变的coupleY值)绘制couple.gif图像,最后将缓冲区的数据输出到屏幕。
run()方法里的循环体遵循我们刚开始提出的游戏结构。循环每30毫秒检查一次用户输入并刷新屏幕。你可以试着将这个值改变一下,这会改变刷新的频率。
最后,注意MyGameCanvas的构造器里调用了父类GameCanvas的构造方法,传入的参数为true,这表示从Canvas类继承的按键事件机制被抑制了,因为我们的代码不需要这些通知机制。我们的游戏状态用GameCanvas里自带的按键信息(由getKeyStates()方法取得)来处理已经足够了。通过抑制“keyPressed”、“keyReleased”和“keyRepeated”等通知机制,可以提高游戏的性能。
GameCanvas类提供一种存储按键状态的机制,我们可以通过它方便的了解用户与游戏的交互。这种机制可以跟踪用户按特殊键的次数,调用getKeyStates()方法返回所有游戏键按键状态的二进制表示,1代表上次调用方法后按过该键,0表示上次调用后还没有按过该键。我们可以跟踪的游戏状态有(这里的键都是在Canvas类里定义的):DOWN_PRESSED, UP_PRESSED, RIGHT_PRESSED, LEFT_PRESSED, FIRE_PRESSED, GAME_A_PRESSED, GAME_B_PRESSED, GAME_C_PRESSED和GAME_D_PRESSED。
首先扩展GameCanvas类,定制一个游戏画布,代码见清单1。清单2是运行例子的MIDlet。
package com.j2me.part3;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.game.GameCanvas;
import java.io.IOException;
public class MyGameCanvas
extends GameCanvas
implements Runnable
{
public MyGameCanvas()
{
super(true);
}
public void start()
{
try
{
//导入couple图片,坐标定位在屏幕中央
coupleImg = Image.createImage("/couple.gif");
coupleX = CENTER_X;
coupleY = CENTER_Y;
}
catch(IOException ioex)
{
System.err.println(ioex);
}
Thread runner = new Thread(this);
runner.start();
}
public void run()
{
//获取画布的graphics对象
Graphics g = getGraphics();
while(true) //无穷循环
{
//基于上一个代码清单列出的结构
//首先检查游戏状态
verifyGameState();
//检查用户输入
checkUserInput();
//更新屏幕
updateGameScreen(getGraphics());
//休息一下,控制刷新频率
try
{
Thread.currentThread().sleep(30);
}
catch(Exception e)
{}
}
}
private void verifyGameState()
{
//现在先不做任何操作
}
private void checkUserInput()
{
//获取按键信息
int keyState = getKeyStates();
//计算x轴位置
calculateCoupleX(keyState);
}
private void updateGameScreen(Graphics g)
{
//清空屏幕背景
g.setColor(0xffffff);
g.fillRect(0, 0, getWidth(), getHeight());
//将couple图片绘制到当前坐标位置
g.drawImage(
coupleImg, coupleX, coupleY, Graphics.HCENTER |
Graphics.BOTTOM);
flushGraphics();
}
private void calculateCoupleX(int keyState)
{
//判断移动方向
if((keyState & LEFT_PRESSED) != 0)
{
coupleX -= dx;
}
else if((keyState & RIGHT_PRESSED) != 0)
{
coupleX += dx;
}
}
private Image coupleImg;
private int coupleX;
private int coupleY;
private int dx = 1; //移动量
//屏幕中心
public final int CENTER_X = getWidth() / 2;
public final int CENTER_Y = getHeight() / 2;
}清单 1. MyGameCanvas:游戏画布的第一个版本
清单 2 是使用这个游戏画布的MIDlet:
package com.j2me.part3;
import javax.microedition.lcdui.Display;
import javax.microedition.midlet.MIDlet;
public class GameMIDlet extends MIDlet
{
MyGameCanvas gCanvas;
public GameMIDlet()
{
gCanvas = new MyGameCanvas();
}
public void startApp()
{
Display d = Display.getDisplay(this);
gCanvas.start();
d.setCurrent(gCanvas);
}
public void pauseApp()
{}
public void destroyApp(boolean unconditional)
{}
}清单 2. 运行游戏示例的MIDlet类
使用Wireless工具建立一个工程,导入这两个类,然后生成并运行工程。确保你的工程目录res中有这个图片文件
,并保证名称为couple.gif, 图1是运行结果。
图1. 构建一个游戏:使用GameCanvas类
使用设备的方向键可以左右移动屏幕中的小图像,这是通过从checkUserInput()里取得按键状态,然后调用calculateCoupleX(),通过将按键状态与GameCanvas里预定义的按键值进行与操作(&),得到用户当前按的键,然后将实例变量更新,最终反映到设备屏幕上。
图像是在updateGameScreen()方法里被绘制到屏幕上的。这个方法使用传入的Graphics对象进行绘制,每一个GameCanvas只有一个Graphics对象。方法首先擦除上次绘制的图像,然后基于当前的coupleX值(还有一直不变的coupleY值)绘制couple.gif图像,最后将缓冲区的数据输出到屏幕。
run()方法里的循环体遵循我们刚开始提出的游戏结构。循环每30毫秒检查一次用户输入并刷新屏幕。你可以试着将这个值改变一下,这会改变刷新的频率。
最后,注意MyGameCanvas的构造器里调用了父类GameCanvas的构造方法,传入的参数为true,这表示从Canvas类继承的按键事件机制被抑制了,因为我们的代码不需要这些通知机制。我们的游戏状态用GameCanvas里自带的按键信息(由getKeyStates()方法取得)来处理已经足够了。通过抑制“keyPressed”、“keyReleased”和“keyRepeated”等通知机制,可以提高游戏的性能。
相关文章推荐
- 从硬件的底层开始,构建一个FlappyBird游戏
- Android学习笔记(10)-开始做一个数独游戏[中]
- Android学习笔记(11)-开始做一个数独游戏[下]
- quick cocos2d-x 实战:做一个手机横版格斗游戏2:游戏开始界面设计
- 使用Box2d和cocos2d-x从头开始制作一个弹弓类游戏系列教材的第二部分
- Android学习笔记(9)-开始做一个数独游戏[上]
- 从头开始构建一个web即时通讯系统 - 基础 - web即时通讯系统的四种实现
- 分享一个帮助你快速构建HTML5游戏的javascript类库 - CreateJS
- 刚刚开始学习j2me,目标是开发一个小游戏
- 从头开始构建一个HTML电子邮件模板
- 一切从游戏开始-完整的一个python to hack 实例
- Android学习笔记(10)-开始做一个数独游戏[中]
- 每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此。HF作为牛客的资深元老,自然也准备了一些小游戏。其中,有个游戏是这样的:首先,让小朋友们围成一个大圈。然后,他随机指定一个数m,让编号为0的小朋友开始报数。每次喊到m-1的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物,并且不再回到圈中,从他的下一个小朋友开始,继续0...m-1报数....这样下去....直到剩下
- 分享一个帮助你快速构建HTML5游戏的javascript类库 - CreateJS
- 自己早期做的一个基于j2me的飞行射击类游戏
- 从头开始构建一个嵌入式 Linux 发行版
- Android学习笔记(11)-开始做一个数独游戏[下]
- 1.有一个游戏,50关,前20关是每关得分是他们关卡数,21-40关是每关20分,41-49 每关30分,50关一次性加1000分。求,输入关卡数,求得分。 2.写一个程序,要求,输入一个数,求从这个数前面15个数开始计算的和
- 发布一个J2ME RPG 游戏地图编辑eclipse plugin(Tiles MapEditor)
- 游戏设计的艺术:一本透镜的书——第六章 游戏以一个创意开始