記錄存儲依賴於一個J2ME的專門的類:RecordStore,位於 Javax.microedition.rms.*
我們現在關注一下RecordStore的本質,我們可以可以把它看作一個數據表,但是我們不能直接訪問到制定列,必須先使用byte[] getRecord取得某行數據,然後對這個byte[]通過StreamReader來順序地讀到這一列。
它的方法有一大堆,但實際上我們用不著那麼多,這裡有個BaseRMS類,可以提供方便的借口,代碼來自Jason Lam的<J2ME & Gaming>。
import Javax.microedition.rms.*;
abstract public class BaseRMS {
private String rmsName;
private RecordStore recordStore;
BaseRMS(String rmsName){
this.rmsName = rmsName; //設置記錄名稱
}
public void open() throws Exception {
// 如果load RecordStore失敗則重新生成一個RecordStore
try {
recordStore = RecordStore.openRecordStore(this.rmsName,true);
if(recordStore.getNumRecords()>0){
loadData();
} else {
createDefaultData();
}
}catch(Exception e){
throw new Exception(this.rmsName + "::open::" + e);
}
}
public void close() throws Exception {
if(recordStore!=null){
try {
recordStore.closeRecordStore();
}catch(Exception e){
throw new Exception(this.rmsName + "::close::" + e);
}
}
}
public RecordStore getRecordStore(){
return this.recordStore; //返回整塊記錄
}
public String getRMSName(){
return this.rmsName;
}
abstract void loadData() throws Exception;
abstract void createDefaultData() throws Exception;
abstract void updateData() throws Exception;
}
下面的Score類由以上的BaseRMS派生
import Java.io.*;
public class Score extends BaseRMS {
private String[] names = new String[3]; // 僅保存前三條記錄,所以只要一個3元素的數組即可
private int[] values = new int[3];
public Score(String rmsName){
super(rmsName);
initValues(); // 這個是初始數據
}
private void initValues(){
names[0] = "Magic.D";
names[1] = "Tangel";
names[2] = "Nick";
values[0] = 100;
values[1] = 50;
values[2] = 10;
}
public void loadScores() throws Exception {
try{
this.open();
if(this.getRecordStore()!=null)
this.close();
}catch(Exception e){
throw new Exception("Error loading Scores" + e);
}
}
public int[] getValues(){
return this.values; // 得到分數的數組
}
public String[] getNames(){
return this.names; // 得到名字的數組
}
public void reset() throws Exception { // 重新初始化數據集
this.open();
initValues();
updateData();
if(this.getRecordStore()!=null)
this.close();
}
public void updateScores(int score,String Name) throws Exception {
try { //數據量小,簡單地使用冒泡排序來完成更新並重排記錄
for(int i=0;i<names.length;i++){
if(score>=values[i]){
this.open();
for(int j=names.length-1;j>i;j--){
values[j] = values[j-1];
names[j] = names[j-1];
}
this.values[i] = score;
this.names[i] = Name;
updateData();
if(this.getRecordStore()!=null)
this.close();
break;
}
}
}catch(Exception e){
throw new Exception(this.getRMSName() + "::updateScores::" + e);
}
}
public boolean isHighScore(int score) throws Exception {
boolean isHighScore = false; // 遍歷記錄,判斷新的分數是否是高分
try {
for(int i=0;i<names.length;i++){
if(score>=values[i])
isHighScore = true;
}
}catch(Exception e){
throw new Exception(this.getRMSName() + "::isHighScore::" + e);
}
return isHighScore;
}
protected void loadData() throws Exception {
try {
for(int i=0;i<names.length;i++){
byte[] record = this.getRecordStore().getRecord(i+1);
DataInputStream istream = new DataInputStream(new ByteArrayInputStream(record,0,record.length)); // 注意DataInputStream的使用
values[i] = istream.readInt();
names[i] = istream.readUTF();
}
}catch(Exception e){
throw new Exception(this.getRMSName() + "::loadData::" + e);
}
}
protected void createDefaultData() throws Exception {
try{
for(int i=0;i<names.length;i++){
ByteArrayOutputStream bstream = new ByteArrayOutputStream(12);
DataOutputStream ostream = new DataOutputStream(bstream);
ostream.writeInt(values[i]);
ostream.writeUTF(names[i]);
ostream.flush();
ostream.close();
byte[] record = bstream.toByteArray();
this.getRecordStore().addRecord(record,0,record.length);
}
}catch(Exception e){
throw new Exception(this.getRMSName() + "::createDefaultData::" + e);
}
}
protected void updateData() throws Exception {
try{
for(int i=0;i<names.length;i++){
ByteArrayOutputStream bstream = new ByteArrayOutputStream(12);
DataOutputStream ostream = new DataOutputStream(bstream);
ostream.writeInt(values[i]);
ostream.writeUTF(names[i]);
ostream.flush();
ostream.close();
byte[] record = bstream.toByteArray();
this.getRecordStore().setRecord(i+1,record,0,record.length);
}
}catch(Exception e){
throw new Exception(this.getRMSName() + "::updateData::" + e);
}
}
}
有了這個類,怎麼顯示高分,怎麼加入高分我想應該不用多言了,都是簡單的問題啦,同時我們也可以聯想到,游戲設置其實跟這個本質上是相同的,我們用BaseRMS派生出一個GameOption類,然後每次進入游戲前讀入設置,就OK 。到此我把這個小游戲的各個方面都說了一遍,自我感覺還是比較亂的,我計劃接下來再寫文章分別仔細討論一下J2ME的UI設計,圖形設計。