首先需要将用户的姓名和分数保存,这就需要一个格式,在这里定义为"用户分数#用户姓名"这样的格式。用户姓名是在记录分数的界面用户输入的,而用户的分数则是从GameScreen类中直接获取的。那如何获取GameScreen的实例呢?可以有多种方法,可以在构造RecordScreen的时候就将实例放到构造函数的参数中,也可以在Midlet的主类SnakeGame中获取GameScreen的实例。我偏向于第二种做法,因为这样看起来结构比较清晰,因为所有的屏幕都是属于这个Midlet的,将所有的屏幕(Screen)都做为主类的成员,再为每个设置get方法就可以在任何时候很方便的获取任意一个屏幕的实例。还有个问题是如何随时获取主Midlet类的实例呢?在JBuilder里面生成的代码中有个静态的变量instance,所以在任何地方都可以用SnakeGame.instance来获取这个类的实例。不过我的习惯是将instance设置成private类型,再写一个getInstance()的静态方法返回instance。这样,如果我想获取GameScreen的实例,就可以在任何地方直接用SnakeGame.getIntance().getGameScreen()获取了。
数据可以获取了,现在就是保存了,保存很简单了,打开一个RecordStore,然后用addRecord方法添加记录就是了,这里的记录表现形式只能是byte数组类型的。代码如下:
int score = gameScreen.getScore();//获取的分数
String name = playerName.getString();//获取姓名
String record = score + "#" + name;//组成字符串
try {
RecordStore rs = RecordStore.openRecordStore("SnakeGame", true);//打开,如果没有就新建
rs.addRecord(record.getBytes(), 0, record.length());//保存
rs.closeRecordStore();//关闭
}
catch (RecordStoreException ex) {
ex.printStackTrace();
}
这样简单就把数据保存进去了。
保存完了应该读取了,而且这个是要按排名先后来排序的,一般来说,遍历整个记录集可以使用RecordEnumeration,我们可以用RecordStore的enumerateRecords来进行遍历,enumerateRecords有三个参数,在这里只需要关心第二个参数就可以了,第二个参数是需要提供一个排序的类,这个类要实现RecordComparator接口,RecordComparator接口里面有compare(byte[] a byte[] b)函数,我们只要按照我们的意图实现这个方法就可以了。我们需要的是比较#前面的数字的大小,因此也比较简单,具体类的代码如下:
class MyExpenseComparator
implements RecordComparator {
public int compare(byte[] a, byte[] b) {
String strA = new String(a);
String strB = new String(b);
int indexA = strA.indexOf("#");
String scoreA = strA.substring(0, indexA);
int indexB = strB.indexOf("#");
String scoreB = strB.substring(0, indexB);
if (Integer.parseInt(scoreA) > Integer.parseInt(scoreB)) {
return this.PRECEDES;
}
if (Integer.parseInt(scoreA) < Integer.parseInt(scoreB)) {
return this.FOLLOWS;
}
return this.EQUIVALENT;
}
}
有了这个排序的类,其他的就好办了,遍历记录然后一条一条显示就可以了,考虑到如果记录多了会很长,因此遍历的时候只取出前10名的记录,后面的全部都删除掉。遍历以及显示记录的代码如下:
private void listRecord() {
String[] names;
try {
RecordStore rs = RecordStore.openRecordStore("SnakeGame", false);
int count = 0;
RecordEnumeration e = rs.enumerateRecords(null, new MyExpenseComparator(), false);
while (e.hasNextElement()) {
int rid = e.nextRecordId();
String str = new String(rs.getRecord(rid));
int index = str.indexOf("#");
String score = str.substring(0, index);
String name = str.substring(index + 1);
if (count++ >= 10)
rs.deleteRecord(rid);
else
append("No" + count + "." + "姓名:" + name + " 得分:" + score + "\r\n");
}
rs.closeRecordStore();
}
catch (Exception e) {
e.printStackTrace();
}
}
显示和记录都完成了,呵呵,再集成到我们的游戏里面去吧,整个RecordScreen的代码如下:
package snakegame;
import javax.microedition.lcdui.*;
import javax.microedition.rms.RecordStore;
import javax.microedition.rms.*;
import java.util.Hashtable;
public class RecordScreen
extends Form implements CommandListener {
private Command cancel;
private Command save;
private TextField playerName = new TextField("您的大名", "Noname", 10, TextField.ANY);
private GameScreen gameScreen;
public RecordScreen() {
super("记录成绩");
this.gameScreen = SnakeGame.getInstance().getGameScreen();
cancel = new Command("取消", Command.EXIT, 1);
save = new Command("保存成绩", Command.OK, 2);
this.append(playerName);
addCommand(cancel);
addCommand(save);
setCommandListener(this);
listRecord();
}
private void saveRecord() {
int score = gameScreen.getScore();
String name = playerName.getString();
String record = score + "#" + name;
try {
RecordStore rs = RecordStore.openRecordStore("SnakeGame", true);
int id = rs.addRecord(record.getBytes(), 0, record.length());
rs.closeRecordStore();
}
catch (RecordStoreException ex) {
ex.printStackTrace();
}
listRecord();
}
private void listRecord() {
String[] names;
try {
RecordStore rs = RecordStore.openRecordStore("SnakeGame", false);
int count = 0;
RecordEnumeration e = rs.enumerateRecords(null, new MyExpenseComparator(), false);
while (e.hasNextElement()) {
int rid = e.nextRecordId();
String str = new String(rs.getRecord(rid));
int index = str.indexOf("#");
String score = str.substring(0, index);
String name = str.substring(index + 1);
if (count++ >= 10)
rs.deleteRecord(rid);
else
append("No" + count + "." + "姓名:" + name + " 得分:" + score + "\r\n");
}
rs.closeRecordStore();
}
catch (Exception e) {
e.printStackTrace();
}
}
public void commandAction(Command command, Displayable displayable) {
if (command == save) {
saveRecord();
SnakeGame.getInstance().gameScreen();
}
if (command == cancel) {
SnakeGame.getInstance().gameScreen();
}
}
}
class MyExpenseComparator
implements RecordComparator {
public int compare(byte[] a, byte[] b) {
String strA = new String(a);
String strB = new String(b);
int indexA = strA.indexOf("#");
String scoreA = strA.substring(0, indexA);
int indexB = strB.indexOf("#");
String scoreB = strB.substring(0, indexB);
if (Integer.parseInt(scoreA) > Integer.parseInt(scoreB)) {
return this.PRECEDES;
}
if (Integer.parseInt(scoreA) < Integer.parseInt(scoreB)) {
return this.FOLLOWS;
}
return this.EQUIVALENT;
}
}
OK,这个功能就实现了!
不过在测试中发现,如果输入的姓名有中文,可能显示的就会有点问题,上面的图片第二条记录,本来填写的是“无名”,结果显示的时候只显示出了“无”字。这个问题有人知道的话请告诉我解决的办法,多谢了!!