`
MouseLearnJava
  • 浏览: 463821 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

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

阅读更多
在上几篇博文中,介绍了

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

http://mouselearnjava.iteye.com/blog/1913290

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

http://mouselearnjava.iteye.com/blog/1913886

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

http://mouselearnjava.iteye.com/blog/1914225

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

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

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

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

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

1. 创建与记录相关的类

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<numberInRecord;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();
		}
	}
}


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

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

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的玩家名字。



查看得分排行榜:






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

代码还没有优化过,详细代码请参考附件MySnakeGame.7z
  • 大小: 8.1 KB
  • 大小: 11.1 KB
  • 大小: 20.8 KB
0
0
分享到:
评论
1 楼 zyazyz008 2013-07-30  
楼主强大

相关推荐

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

    在本项目中,"Swing贪吃蛇游戏(三):增加游戏进度存储和加载功能",我们将探讨如何为一个基于Java Swing开发的贪吃蛇游戏添加保存和加载进度的功能。这涉及到游戏状态的序列化和反序列化,以及用户交互的增强。以下...

    Swing版贪吃蛇游戏

    Swing版贪吃蛇游戏是一款基于Java Swing图形用户界面库开发的经典小游戏,它不仅保留了传统贪吃蛇的基本玩法,还增加了许多现代化的功能,如进度保存与加载、得分排行榜和随机生成的障碍物等,提升了游戏的趣味性和...

    JavaSwing贪吃蛇小游戏

    在Swing贪吃蛇游戏中,主要涉及以下核心知识点: 1. **Swing组件**:游戏界面通常由多个Swing组件构成,如JFrame作为主窗口,JPanel作为游戏面板,以及可能的JLabel用于显示分数或游戏状态。这些组件通过继承自...

    java swing 贪吃蛇游戏.zip

    这个“java swing 贪吃蛇游戏.zip”压缩包包含了一个使用Java Swing开发的贪吃蛇游戏的完整源代码,非常适合初学者进行学习、实践,或者作为毕业设计或课程设计的项目。 贪吃蛇游戏是一个经典的计算机游戏,玩家...

    (源码+视频) swing贪吃蛇游戏开发教程+源码.rar

    【Swing贪吃蛇游戏开发教程】是一套针对Java初学者的编程教学资源,它涵盖了使用Java Swing库创建一个经典游戏——贪吃蛇的过程。Swing是Java AWT(抽象窗口工具包)的一个扩展,提供了丰富的图形用户界面(GUI)...

    Java swing 贪吃蛇游戏.zip

    在Java Swing中创建贪吃蛇游戏,我们可以学习到以下关键知识点: 1. **Swing组件**:贪吃蛇游戏的核心是游戏面板,这通常会由`JPanel`类来实现。在`GamePanel.java`中,我们可能会看到如何自定义`JPanel`,添加绘图...

    java_swing完整版贪吃蛇

    在本项目“java_swing完整版贪吃蛇”中,开发者利用Java Swing的技术,实现了一个经典的贪吃蛇游戏。 贪吃蛇游戏是一个非常基础且受欢迎的游戏,玩家控制一个不断移动的蛇,通过吃食物来增长蛇的身体长度。当蛇头...

    贪吃蛇游戏java版源码

    这个Java版本的贪吃蛇游戏源码是为那些希望深入理解游戏开发和Java GUI编程,特别是AWT(Abstract Window Toolkit)和Swing库的开发者准备的。以下是基于这个项目的一些关键知识点的详细说明: 1. **Java编程基础**...

    儿时回忆,贪吃蛇,Java swing编写,完美运行。myeclipes导入即可

    在Java Swing中实现贪吃蛇游戏,主要涉及以下几个关键知识点: 1. **图形用户界面(GUI)**:使用JFrame作为主窗口,放置JPanel作为游戏面板。Swing提供了各种组件,如JButton、JLabel等,但在这里主要是自定义组件以...

    Java项目:贪吃蛇游戏(java+swing)

    Java项目“贪吃蛇游戏(Java+Swing)”是一个基于Java编程语言和Swing图形用户界面库开发的经典游戏。Swing是Java Standard Edition (Java SE)的一部分,它提供了丰富的组件和工具,使得开发者能够创建出功能强大且...

    java Swing thread 贪吃蛇

    在贪吃蛇游戏中,至少需要两个线程:一个用于游戏逻辑(包括蛇的移动、食物的生成、碰撞检测),另一个用于更新和绘制游戏画面。这样可以确保游戏流畅运行,不会因为渲染和逻辑处理在同一线程而导致卡顿。 1. **...

    java swing的贪吃蛇代码,自己写的,没有用到线程 只用到Swing的timer类控制游戏运行

    总结来说,这个项目展示了如何利用Java Swing的`Timer`类在单线程环境下构建一个功能完整的贪吃蛇游戏,同时体现了Swing组件绘制、事件处理和资源管理的能力。这样的实现方式简化了编程复杂性,但可能限制了游戏的...

    有计时功能的贪吃蛇 Java小游戏

    在编写贪吃蛇游戏时,主要会用到Java的Swing或JavaFX库来构建图形用户界面(GUI),以及线程控制来实现游戏循环。 1. **Swing或JavaFX库**:这两者都是Java提供的用于创建GUI的工具包。Swing是Java AWT的扩展,提供...

    贪吃蛇游戏源码贪吃蛇游戏源码

    1. **图形用户界面(GUI)**:贪吃蛇游戏通常会使用Java的Swing或JavaFX库来构建用户界面。这些库提供了丰富的组件和API,可以方便地创建窗口、按钮、面板等元素,实现游戏画面的展示。 2. **多线程**:贪吃蛇游戏...

    贪吃蛇游戏功能源代码

    贪吃蛇游戏是一款经典的计算机游戏,它通过控制蛇在有限的区域内移动,吃食物来增长。这个源代码是使用Java编程语言实现的,特别适合初学者作为了解Java游戏开发的入门项目。以下将详细讲解这款贪吃蛇游戏的源代码所...

    贪吃蛇游戏

    贪吃蛇游戏是一款经典的电子游戏,它源自早期的计算机时代,至今仍深受玩家喜爱。这款游戏的基本概念是控制一条不断增长的蛇,通过移动吃掉屏幕上的食物来得分,同时避免蛇头碰到自己的身体或边界。游戏难度随着蛇的...

    java swing 贪吃蛇

    贪吃蛇游戏的基本规则是:一条蛇在不断移动的网格中吃食物,每吃掉一个食物,蛇的长度就增加一节。当蛇碰到边界或自己的身体时,游戏结束。这个简单的游戏机制需要程序员掌握以下Java Swing的关键概念: 1. **组件...

    基于java+swing贪吃蛇实践报告.docx

    ### 基于Java+Swing贪吃蛇实践报告知识点解析 #### 一、项目概述 本项目旨在通过Java编程语言结合Swing图形用户界面工具包来开发一款经典的贪吃蛇游戏。通过该项目的设计与实现,不仅可以加深对Java语言基础语法的...

    贪吃蛇游戏各种源码集合

    Python实现的贪吃蛇游戏通常利用pygame库,它提供了图形用户界面和游戏开发所需的许多功能。通过Python源码,你可以学习如何处理键盘输入、绘制图形以及实现简单的游戏循环。 2. **Java**:Java是一种面向对象的...

    一个小小的贪吃蛇游戏,基于Java Swing .zip

    标题中的“一个小小的贪吃蛇游戏,基于Java Swing .zip”揭示了这是一个使用Java编程语言,特别是Java Swing库开发的简单贪吃蛇游戏。Java Swing是Java AWT(抽象窗口工具包)的一个扩展,提供了丰富的图形用户界面...

Global site tag (gtag.js) - Google Analytics