Swing贪吃蛇游戏(四):增加游戏得分排行榜功能

在上几篇博文中,介绍了

Swing贪吃蛇游戏(一):基本功能实现 >>>

[url]http://mouselearnjava.iteye.com/blog/1913290[/url]

Swing贪吃蛇游戏(二):增加随机产生障碍物功能 >>>

[url]http://mouselearnjava.iteye.com/blog/1913886[/url]

Swing贪吃蛇游戏(三):增加游戏进度存储和加载功能 >>>

[url]http://mouselearnjava.iteye.com/blog/1914225[/url]

本文在这些既有功能之上,添加游戏得分排行榜功能。[b]得分排行榜上列出Top 10的记录信息,包括玩家名称,得分和名次。[/b]

为了完成这个功能,我们需要做的主要改动有如下几点:

首先:创建与记录相关的类。

其次:完成游戏结束后对记录文件更新的操作。

最后:完成点击Record相关的MenuItem,读取记录信息,并用ScrollPane展示出来。

[b]1. 创建与记录相关的类[/b]

package my.games.snake.model;

import java.io.Serializable;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;


/**
* @author Eric

* @desc 贪吃蛇游戏的排行榜
*/
public class SnakeGameRecords implements Serializable {

private static final long serialVersionUID = 4513299590910220441L;

private static final int TOP_TEN = 10;

private Record[] records = null;

private int numberInRecord = 0; // 排行榜中已经拥有的记录个数

public SnakeGameRecords() {
records = new Record[TOP_TEN];
}

@SuppressWarnings("unchecked")
public void sortRecords() {
Collections.sort(Arrays.asList(getAvailableRecords()), new RecordComparator());
}

private Record[] getAvailableRecords(){
Record[] availableRecords = new Record[numberInRecord];
for(int i=0;i availableRecords[i] = new Record(records[i].getPlayer(),records[i].getScore());
}
return availableRecords;
}

/**
*
* @return
*/
public Record getLastAvailableRecord() {
return isEmpty() ? null : records[numberInRecord - 1];
}

/**
*
* @param record
*/
public void addRecordToTopTen(Record record) {
if (isEmpty()) {
records[0] = record;
numberInRecord++;
return;
}

if (isFull()) {
if (records[TOP_TEN - 1].getScore() < record.getScore()) {
records[TOP_TEN - 1] = record;
sortRecords();
return;
}
}

records[numberInRecord] = record;
numberInRecord++;
sortRecords();
}

/**
*
* @return
*/
public boolean isEmpty() {
return 0 == numberInRecord;
}

/**
*
* @return
*/
public boolean isFull() {
return TOP_TEN == numberInRecord;
}

/**
* @return the numberInRecord
*/
public int getNumberInRecord() {
return numberInRecord;
}

/**
* @param numberInRecord
* the numberInRecord to set
*/
public void setNumberInRecord(int numberInRecord) {
this.numberInRecord = numberInRecord;
}

/**
* @return the records
*/
public Record[] getRecords() {
return records;
}

/**
* @param records
* the records to set
*/
public void setRecords(Record[] records) {
this.records = records;
}

private class RecordComparator implements Comparator {

public int compare(Object o1, Object o2) {
Record r1 = (Record) o1;
Record r2 = (Record) o2;

return (0 == compareScore(r1, r2)) ? compareName(r1, r2)
: compareScore(r1, r2);
}

private int compareScore(Record r1, Record r2) {
return r1.getScore() - r2.getScore();
}

private int compareName(Record r1, Record r2) {
return r1.getPlayer().compareTo(r2.getPlayer());
}

}

}


package my.games.snake.model.record;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;

import my.games.snake.model.SnakeGameRecords;

/**
*
* @author Eric
* @vesion 1.0
* @desc Read Record
*/
public class ReadRecord {

public SnakeGameRecords readRecordsFromFile(File recordFile) {
SnakeGameRecords records = new SnakeGameRecords();
FileInputStream fileInput = null;
ObjectInputStream objectInput = null;

if (!recordFile.exists()) {
return records;
}

try {
fileInput = new FileInputStream(recordFile);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

try {
objectInput = new ObjectInputStream(fileInput);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Object o = null;
try {
o = objectInput.readObject();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

try {
objectInput.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
fileInput.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
records = (SnakeGameRecords) o;
records.sortRecords();
return records;
}

}


package my.games.snake.model.record;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

import my.games.snake.model.SnakeGameRecords;

/**
* @author Eric
* @vesion 1.0
* @desc Write records
*/
public class WriteRecord {

public void writeRecordToFile(SnakeGameRecords records, File recordFile) {
FileOutputStream fileOutput = null;
try {
fileOutput = new FileOutputStream(recordFile);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ObjectOutputStream objectOutput = null;
try {
objectOutput = new ObjectOutputStream(fileOutput);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
objectOutput.writeObject(records);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
objectOutput.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
fileOutput.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}


[b]2. 完成游戏结束后对记录文件更新的操作。[/b]

[b]3. 完成点击Record相关的MenuItem,读取记录信息,并用ScrollPane展示出来。[/b]

public class SnakeGameFrame extends JFrame {
private JMenuItem recordMI = new JMenuItem("Record");

public SnakeGameFrame() {
setMenu.add(recordMI);
recordMI.addActionListener(new RecordAction());
}

private class RecordAction implements ActionListener {

@SuppressWarnings("deprecation")
public void actionPerformed(ActionEvent event) {
File file = new File("file.dat");
SnakeGameRecords records = new ReadRecord()
.readRecordsFromFile(file);
records.sortRecords();
JScrollPane panel = new RecordScrollPane().getReadScrollPane(records,
file);

JDialog recordDialog = new JDialog(SnakeGameFrame.this, "贪吃蛇游戏");
recordDialog.setBounds(300, 300, 300, 219);

Container container = recordDialog.getContentPane();
container.add(panel);
recordDialog.show();
}
}
}



package my.games.snake.ui;

import java.io.File;

import javax.swing.JScrollPane;
import javax.swing.JTable;

import my.games.snake.model.Record;
import my.games.snake.model.SnakeGameRecords;

public class RecordScrollPane{

private static final long serialVersionUID = -3552642981292000951L;

public JScrollPane getReadScrollPane(SnakeGameRecords records,
File recordFile) {
Object[][] data = new Object[records.getNumberInRecord()][3];
for (int i = 0; i < records.getNumberInRecord(); i++) {
Record record = records.getRecords()[i];
data[i][0] = String.valueOf(i + 1);
data[i][1] = record.getPlayer();
data[i][2] = String.valueOf(record.getScore());
}
Object[] columnNames = new Object[3];
columnNames[0] = "ID";
columnNames[1] = "Name";
columnNames[2] = "Score";
JTable table = new JTable(data, columnNames);
table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
JScrollPane pane = new JScrollPane(table);
return pane;
}
}


//游戏结束时,如果分数大于0,那么将分数写入到排行榜中去
public class SnakeGamePanel extends JPanel {
private void writeScore() {
if (score == 0) {
return;
}
File file = new File("file.dat");
SnakeGameRecords records = new ReadRecord().readRecordsFromFile(file);
if (records == null
|| records.isEmpty()
|| !records.isFull()
|| (records.getLastAvailableRecord().getScore() < score && records
.isFull())) {
String playerName = JOptionPane
.showInputDialog("Please input your name");
if (playerName == null || playerName.length() == 0
|| playerName.trim().equals("")) {
playerName = "无名英雄";
}
Record record = new Record(playerName, score);
records.addRecordToTopTen(record);
new WriteRecord().writeRecordToFile(records, file);
}

}
}



一个演示的示例如下:

游戏结束时,输入Frank的玩家名字。

[img]http://dl2.iteye.com/upload/attachment/0087/5102/0034b235-7358-35de-b362-e1a37e5225c0.jpg[/img]

查看得分排行榜:

[img]http://dl2.iteye.com/upload/attachment/0087/5106/2dd54c9d-f22e-3021-a440-228cfe2fb3cf.jpg[/img]

[img]http://dl2.iteye.com/upload/attachment/0087/5104/16cc9469-7e59-3485-b0ad-dee712e7eaaa.jpg[/img]


至此,一个拥有进度存储和加载功能,得分排行榜以及随机产生障碍物的Swing贪吃蛇游戏就完成了。

代码还没有优化过,详细代码请参考附件MySnakeGame.7z

你可能感兴趣的:(Swing游戏,Java)