用NetBeans开发平台开发J2ME游戏实例讲解(第四部分)
(3) 使用rms来记录成绩排行榜
J2ME 记录治理系统(RMS)提供了一种机制,通过这种机制,MIDlet 能够持久存储数据,并在以后检索数据。我们在程序中就需要这样的一个排行榜,
这个排行榜在程序关闭以后仍然能够记录数据,rms正好满足了这个要求,有关rms的信息,请参考:
http://www-128.ibm.com/developerworks/cn/Java/j-wi-rms/index.Html
http://game.kongzhong.com/content/j2mecontent_730.html
我们在程序中要实现排行榜的功能,需要做的事情有这样几件:
A. 在选项菜单当中加入排行榜,这好办, 在HuaRongDaoMielet.java中加入产生排行榜的代码;
B. 新建一个类,取名Score, 关于新建类的方法,上面的论述中有讲述,我们需要的接口函数很简单,getScore(), setScore()就可以了,注重这
里,rms是字节数组组成的记录体系,因此我们假如要存储整型量,就要有整形到byte[]以及byte[]到整型量的转换,如下:
/**
* 数组到整数.
*/
private int getInt(byte[]buf, int offset) {
return (buf[offset+0] & 0xff) 24
(buf[offset+1] & 0xff) 16
(buf[offset+2] & 0xff) 8
(buf[offset+3] & 0xff);
}
/**
* 整数到数组.
*/
private void putInt(byte[] buf, int offset, int value) {
buf[offset+0]= (byte)((value 24) & 0xff);
buf[offset+1]= (byte)((value 16) & 0xff);
buf[offset+2]= (byte)((value 8) &0xff);
buf[offset+3]= (byte)((value 0) &0xff);
}
其中offset是byte[]的偏移量,一个整型量用4个字节来表示。
另外我们需要对rms存储系统进行初始化,在构造函数当中引入open()函数,如下所示:
// 每关成绩 = {int level,intmoves;}
private byte[] scoreRec; // 当前关成绩.
privatestatic final int SCORE_LEN = 8;
private RecordStorestore; //记录存储,没有打开时为空.
/*
* 构造函数.
*/
Score() {
store= null;
scoreRec = new byte[SCORE_LEN];
putInt(scoreRec,0, 0);
putInt(scoreRec,4, 0);
open();
}
/**
* 打开存储记录
*/
boolean open() {
try{
store= RecordStore.openRecordStore("HuaRongDaoScore", true);
} catch (RecordStoreExceptionex) {
}
if(store == null)
returnfalse;
returntrue;
}
可以看出,我们的每个记录长度是8个字节,都是整型量,第一个是关,第二个是成绩,最后的结构类似于:
关 步数
0 33
1 98
2 109
3 77
...
最后,在这个类中最重要的两个函数readScore()和setScore(), 分别负责读取和设置某一关的成绩。在这两个函数当中,我们要注重在rms
中遍历某个元素的方法,你需要自己设个标记TAG,来标记你的记录,因为rms不象数组一样,可以按照下标来索引,rms的几个函数包括
getRecord()
getRecordSize()
enumerateRecords()
addRecord()
setRecord()
等等都要知道是做什么用的。
/**
* 读取某级别的成绩.
*/
public int readScore(intlevel) {
try {
// 查找成绩
RecordEnumerationenm = store.enumerateRecords(null, null, false);
while(enm.hasNextElement()) {
int ndx= enm.nextRecordId();
if (store.getRecordSize(ndx) == SCORE_LEN) {
int l = store.getRecord(ndx, scoreRec, 0);
if (l == SCORE_LEN && getInt(scoreRec, 0) == level)
return getInt(scoreRec, 4);
}
}
// 没有这一关的成绩,新建
putInt(scoreRec, 0, level);
putInt(scoreRec, 4, 0);
store.addRecord(scoreRec, 0, SCORE_LEN);
return 0;
}catch (RecordStoreException ex) {
ex.printStackTrace();
return-1;
}
}
/**
* 设置某级别的成绩.
*/
booleansetScore(int level, int moves) {
try{
// 查找成绩
RecordEnumeration enm = store.enumerateRecords(null, null, false);
while (enm.hasNextElement()) {
int ndx = enm.nextRecordId();
if (store.getRecordSize(ndx) ==SCORE_LEN) {
int l = store.getRecord(ndx, scoreRec, 0);
if (l == SCORE_LEN && getInt(scoreRec, 0) == level)
//只存储较小的值
if ( getInt(scoreRec,4)== 0 getInt(scoreRec, 4) moves){
putInt(scoreRec, 4, moves);
store.setRecord(ndx, scoreRec,0, SCORE_LEN);
}
}
}
// 没有这一关的成绩,新建
putInt(scoreRec, 0, level);
putInt(scoreRec, 4, moves);
store.addRecord(scoreRec, 0, SCORE_LEN);
}catch (RecordStoreException ex) {
ex.printStackTrace();
returnfalse;
}
return true;
}
C. 最后要看看这个Score类怎样使用,我们需要在主Midlet里面初始化它,然后在ConrolLogic.java中 设置成绩。
首先,声明这个类成员, 并且进行初始化:HuaRongDaoMidlet.java
public class HuaRongDaoMidletextends MIDlet implements CommandListener{
... ...
privateScore score;
/** The Form object for theOptions command */
privateForm optionsForm;
... ...
publicvoid startApp() {
score = new Score();
... ...
在程序结束时关闭它,
... ...
publicvoid commandAction(Command c, Displayable d) {
if ( c == CMD_EXIT && d == splash ){
//退出
score.close();