在上两篇博文中,介绍了
Swing贪吃蛇游戏(一):基本功能实现 >>>> [url]http://mouselearnjava.iteye.com/blog/1913290[/url]
Swing贪吃蛇游戏(二):增加随机产生障碍物功能 >>> [url]http://mouselearnjava.iteye.com/blog/1913886[/url]
本文在这些既有功能之上,添加游戏进度的保存和加载功能。
游戏进度的保存和加载功能是通过[b]序列化[/b]和[b]反序列化[/b]来完成的。
[color=blue][b]保存[/b][/color]--> [b]通过序列化的方式将当前游戏运行状态中用到的一些重要对象序列化到文件中加以保存,从而达到记录当前游戏状态的效果。[/b]
[b][color=blue]加载[/color][/b]--> [b]通过反序列化的方式将序列化后的对象读取出来,从而达到恢复之前游戏保存时的状态的效果。用户可以在此基础上继续进行游戏。[/b]
那么,为了能够完成这个功能,我们需要做一些什么样的改动呢?
[b]首先:添加用于保存和加载功能的MenuItem, 并为它们添加ActionListenser[/b]
[b]其次:编写用于保存记录和加载记录的逻辑[/b]
至此,游戏进度存储和加载的功能就完成了。下面将给出游戏进度存储和加载功能的一个实例。
[b]游戏进度存储[/b]-->>
某一时刻的游戏进度:
[img]http://dl2.iteye.com/upload/attachment/0087/5034/3cc42545-6a3a-323d-adf3-be06277bd8f8.jpg[/img]
点击Save MenuItem,并保存游戏进度。
[img]http://dl2.iteye.com/upload/attachment/0087/5040/62d7ea98-4ba4-377a-9f99-0219c34aee22.jpg[/img]
[img]http://dl2.iteye.com/upload/attachment/0087/5036/2dfad83b-d97b-3c2a-b054-b06a3e669154.jpg[/img]
[img]http://dl2.iteye.com/upload/attachment/0087/5038/179fc46d-072c-39bc-a35c-d35ebb42b51c.jpg[/img]
[b]游戏进度读取[/b]-->>
打开之前保存的游戏进度文件Snake.dat
[img]http://dl2.iteye.com/upload/attachment/0087/5026/161be8ac-e7c1-3b7e-8393-e9d7b95501be.jpg[/img]
[img]http://dl2.iteye.com/upload/attachment/0087/5028/0d58f871-a2eb-38df-9916-ddb030b013cc.jpg[/img]
[img]http://dl2.iteye.com/upload/attachment/0087/5030/9669ba87-2f73-3b65-a449-42a5fdb657a5.jpg[/img]
游戏继续,贪吃蛇向下运动一会的截图如下:
[img]http://dl2.iteye.com/upload/attachment/0087/5032/8d66145a-3d87-32f4-b9ce-fa7020e16c4e.jpg[/img]
详细代码请参考附件MySnakeGame.7z
Swing贪吃蛇游戏(一):基本功能实现 >>>> [url]http://mouselearnjava.iteye.com/blog/1913290[/url]
Swing贪吃蛇游戏(二):增加随机产生障碍物功能 >>> [url]http://mouselearnjava.iteye.com/blog/1913886[/url]
本文在这些既有功能之上,添加游戏进度的保存和加载功能。
游戏进度的保存和加载功能是通过[b]序列化[/b]和[b]反序列化[/b]来完成的。
[color=blue][b]保存[/b][/color]--> [b]通过序列化的方式将当前游戏运行状态中用到的一些重要对象序列化到文件中加以保存,从而达到记录当前游戏状态的效果。[/b]
[b][color=blue]加载[/color][/b]--> [b]通过反序列化的方式将序列化后的对象读取出来,从而达到恢复之前游戏保存时的状态的效果。用户可以在此基础上继续进行游戏。[/b]
那么,为了能够完成这个功能,我们需要做一些什么样的改动呢?
[b]首先:添加用于保存和加载功能的MenuItem, 并为它们添加ActionListenser[/b]
public class SnakeGameFrame extends JFrame {
private JMenuItem loadMI = new JMenuItem("Open");
public JMenuItem saveMI = new JMenuItem("Save");
public SnakeGameFrame() {
//省略其它
setMenu.add(loadMI);
setMenu.add(saveMI);
loadMI.addActionListener(new LoadAction());
saveMI.addActionListener(new SaveAction());
}
private class LoadAction implements ActionListener {
public void actionPerformed(ActionEvent event) {
FileDialog dialog = new FileDialog(SnakeGameFrame.this, "Open",
FileDialog.LOAD);
dialog.setVisible(true);
String dir = dialog.getDirectory();
String fileName = dialog.getFile();
String filePath = dir + fileName;
if (fileName != null && fileName.trim().length() != 0) {
File file = new File(filePath);
panel.loadGameDataFromFile(file);
startMI.setEnabled(false);
pauseMI.setEnabled(true);
} else {
JOptionPane.showConfirmDialog(SnakeGameFrame.this,
"文件名为空\n装载游戏进度失败", "贪吃蛇游戏", JOptionPane.DEFAULT_OPTION);
}
}
}
private class SaveAction implements ActionListener {
public void actionPerformed(ActionEvent event) {
if (panel.getGameState() == GameState.INITIALIZE) {
JOptionPane
.showConfirmDialog(SnakeGameFrame.this,
"游戏没有运行\n不能保存游戏进度", "贪吃蛇游戏",
JOptionPane.DEFAULT_OPTION);
return;
}
FileDialog dialog = new FileDialog(SnakeGameFrame.this, "Save",
FileDialog.SAVE);
dialog.setVisible(true);
String dir = dialog.getDirectory();
String fileName = dialog.getFile();
String filePath = dir + fileName;
if (fileName != null && fileName.trim().length() != 0) {
File file = new File(filePath);
panel.saveGameDataToFile(file);
} else {
JOptionPane.showConfirmDialog(SnakeGameFrame.this,
"文件名为空\n保存游戏进度失败", "贪吃蛇游戏", JOptionPane.DEFAULT_OPTION);
}
}
}
}
[b]其次:编写用于保存记录和加载记录的逻辑[/b]
public class SnakeGamePanel extends JPanel {
//省略其它属性和方法
public void saveGameDataToFile(File file) {
try {
FileOutputStream fileStream = new FileOutputStream(file);
ObjectOutputStream objectStream = new ObjectOutputStream(fileStream);
objectStream.writeObject(flag);
objectStream.writeObject(color);
objectStream.writeObject(snake);
objectStream.writeObject(food);
objectStream.writeObject(new Integer(score));
objectStream.writeObject(barrier);
objectStream.writeObject(new Boolean(needToGenerateFood));
objectStream.writeObject(new Boolean(needToGenerateBarrie));
objectStream.close();
fileStream.close();
JOptionPane.showConfirmDialog(frame, "保存游戏进度成功", "贪吃蛇游戏",
JOptionPane.DEFAULT_OPTION);
} catch (Exception e) {
JOptionPane.showConfirmDialog(frame, e.toString() + "\n保存游戏进度失败",
"贪吃蛇游戏", JOptionPane.DEFAULT_OPTION);
}
}
public void loadGameDataFromFile(File file) {
try {
int[][] svaedFlag;
Snake savedSnake;
Grid savedFood;
Integer savedScore;
Color[][] savedColor;
Barriers savedBarriers;
Boolean savedNeedToGenerateFood;
Boolean savedNeedToGenerateBarrie;
FileInputStream fileStream = new FileInputStream(file);
ObjectInputStream objectStream = new ObjectInputStream(fileStream);
svaedFlag = (int[][]) objectStream.readObject();
savedColor = (Color[][]) objectStream.readObject();
savedSnake = (Snake) objectStream.readObject();
savedFood = (Grid) objectStream.readObject();
savedScore = (Integer) objectStream.readObject();
savedBarriers =(Barriers) objectStream.readObject();
savedNeedToGenerateFood = (Boolean)objectStream.readObject();
savedNeedToGenerateBarrie = (Boolean)objectStream.readObject();
objectStream.close();
fileStream.close();
if (svaedFlag != null && savedColor != null && savedSnake != null && savedFood != null
&& savedScore != null && savedBarriers != null && savedNeedToGenerateFood != null
&& savedNeedToGenerateBarrie != null) {
flag = svaedFlag;
color = savedColor;
score = savedScore.intValue();
gameState = GameState.RUN;
snake = savedSnake;
food = savedFood;
barrier = savedBarriers;
needToGenerateFood = savedNeedToGenerateFood.booleanValue();
needToGenerateBarrie = savedNeedToGenerateBarrie.booleanValue();
frame.saveMI.setEnabled(true);
if (!timer.isRunning()) {
timer.start();
}
repaint();
JOptionPane.showConfirmDialog(frame, "装载游戏进度成功", "贪吃蛇游戏",
JOptionPane.DEFAULT_OPTION);
}
} catch (Exception e) {
JOptionPane.showConfirmDialog(frame, e.toString() + "\n装载游戏进度失败",
"贪吃蛇游戏", JOptionPane.DEFAULT_OPTION);
}
}
}
至此,游戏进度存储和加载的功能就完成了。下面将给出游戏进度存储和加载功能的一个实例。
[b]游戏进度存储[/b]-->>
某一时刻的游戏进度:
[img]http://dl2.iteye.com/upload/attachment/0087/5034/3cc42545-6a3a-323d-adf3-be06277bd8f8.jpg[/img]
点击Save MenuItem,并保存游戏进度。
[img]http://dl2.iteye.com/upload/attachment/0087/5040/62d7ea98-4ba4-377a-9f99-0219c34aee22.jpg[/img]
[img]http://dl2.iteye.com/upload/attachment/0087/5036/2dfad83b-d97b-3c2a-b054-b06a3e669154.jpg[/img]
[img]http://dl2.iteye.com/upload/attachment/0087/5038/179fc46d-072c-39bc-a35c-d35ebb42b51c.jpg[/img]
[b]游戏进度读取[/b]-->>
打开之前保存的游戏进度文件Snake.dat
[img]http://dl2.iteye.com/upload/attachment/0087/5026/161be8ac-e7c1-3b7e-8393-e9d7b95501be.jpg[/img]
[img]http://dl2.iteye.com/upload/attachment/0087/5028/0d58f871-a2eb-38df-9916-ddb030b013cc.jpg[/img]
[img]http://dl2.iteye.com/upload/attachment/0087/5030/9669ba87-2f73-3b65-a449-42a5fdb657a5.jpg[/img]
游戏继续,贪吃蛇向下运动一会的截图如下:
[img]http://dl2.iteye.com/upload/attachment/0087/5032/8d66145a-3d87-32f4-b9ce-fa7020e16c4e.jpg[/img]
详细代码请参考附件MySnakeGame.7z