用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,int
moves;}
private byte[] scoreRec; // 當前關成績.
private
static final int SCORE_LEN = 8;
private RecordStore
store; //
記錄存儲,沒有打開時為空.
/*
* 構造函數.
*/
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 (RecordStoreException
ex) {
}
if
(store == null)
return
false;
return
true;
}
可以看出,我們的每個記錄長度是8個字節,都是整型量,第一個是關,第二個是成績,最後的結構類似於:
關 步數
0 33
1 98
2 109
3 77
...
最後,在這個類中最重要的兩個函數readScore()和setScore(), 分別負責讀取和設置某一關的成績。在這兩個函數當中,我們要注重在rms
中遍歷某個元素的方法,你需要自己設個標記TAG,來標記你的記錄,因為rms不象數組一樣,可以按照下標來索引,rms的幾個函數包括
getRecord()
getRecordSize()
enumerateRecords()
addRecord()
setRecord()
等等都要知道是做什麼用的。
/**
* 讀取某級別的成績.
*/
public int readScore(int
level) {
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)
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;
}
}
/**
* 設置某級別的成績.
*/
boolean
setScore(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();
return
false;
}
return true;
}
C. 最後要看看這個Score類怎樣使用,我們需要在主Midlet裡面初始化它,然後在ConrolLogic.java中 設置成績。
首先,聲明這個類成員, 並且進行初始化:HuaRongDaoMidlet.java
public class HuaRongDaoMidlet
extends MIDlet implements CommandListener{
... ...
private
Score score;
/** The Form object for the
Options command */
private
Form optionsForm;
... ...
public
void startApp() {
score = new Score();
... ...
在程序結束時關閉它,
... ...
public
void commandAction(Command c, Displayable d) {
if ( c == CMD_EXIT && d == splash ){
//退出
score.close();