首先需要将用户的姓名和分数保存,这就需要一个格式,在这里定义为"用户分数#用户姓名"这样的格式。用户姓名是在记录分数的界面用户输入的,而用户的分数则是从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,这个功能就实现了!
不过在测试中发现,如果输入的姓名有中文,可能显示的就会有点问题,上面的图片第二条记录,本来填写的是“无名”,结果显示的时候只显示出了“无”字。这个问题有人知道的话请告诉我解决的办法,多谢了!!