成绩评定表
课程设计任务书
目录
1.设计目的
2.设计需求及流程
3.详细设计
4.运行与调试
5.源代码
6. 设计总结
1. 设计目的
本次课程设计的主要目的是为了通过具体的程序来加深对Java语言的掌握,提高自己的编程水平。选择的题目来自《Java课程设计(第二版)》中的扫雷游戏,这是一个综合性的题目,可以对Java中的各项功能有更好的理解和使用,同时也为以后的工作打下一定的基础
2. 总体设计
2.1设计需求
在设计扫雷游戏时,需要编写7个源文件:MineGame.java,MineArea.java,Block.java,BlockView.java,LayMines.java,ShowRecord.java,Record.java 除了这七个源文件外,还需要Java系统提供一些重要的类,如File,JButton和JLabel等类。
2.2系统功能设计流程图:
2.3类的组合关系
3详细设计
3.1 MineGame.java(主类):
(1)成员变量
bar和fileMenu 提供菜单操作,单击菜单操作中的选项为“初级”,“中级”,“高级”或“扫雷英雄榜”;mineArea 是扫雷区域,提供有关雷的主要功能;英雄榜” 负责存放三个级别的扫雷最好成绩;showHeroRecord负责显示英雄榜中的数据
(2)方法
MineGame()是构造窗口,负责完成窗口的初始化。
ActionPerformed(ActionEvent)方法是MineGame类实现的ActionListener接口中的方法,该方法负责执行菜单发出的有关命令。用户选择菜单中的菜单项可触发ActionEvent事件,导致actionPerformed(ActionEvent)方法执行相应的操作。
Main(String[])方法是程序运行的入口方法。
3.2 MineArea.java:
(1)成员变量
block和Block类型的数组,用来确定雷区有多少需进行扫雷的方块;
blockView是BlockView类型的数组,负责block数组中Block对象提供视图;
lay是LayMines类型的对象,负责设置block数组中的哪些方块不是雷;
record负责提供保存成绩的界面,是一个对话框,默认为不可见,用户只有扫雷成功后,才可以看见该对话框;
reStart是一个按钮对象,用户单击它重新开始游戏;
time是计时器对象,负责计算用户用时。
(2)方法
initMineArea(int,int,int,int)方法可根据参数提供的数据设置雷区的宽度,高度,类的数目以及雷区的级别
actionPerformed(actionEvent)是MineArea类实现的ActionListener接口中的方法。当用户单击blockView中的某个方块时actionPerformed(actionEvent)执行有关算法。
Show()方法是一个递归方法。actionPerformed(actionEvent)方法执行将调用show方法进行扫雷
mousePressed(mouseEvent)方法是MineArea类实现的MouseListener接口中的方法,当用户按下鼠标右键时,mousePressed(mouseEvent)方法负责让方块上显示一个探雷标记。
inquireWin()方法用来判断用户扫雷是否成功,如果成功该方法负责让record对话框可见
3.3Block.java:
(1)成员变量
name方块上的名字
aroundMineNumber是方块周围雷的数目
mineIcon是方块上雷的图标
isMine用来表示方块是否是雷
isMark用来表示方块是否被标记
isOpen用来表示方块是否被挖开
(2)方法
setAroundMineNumber(int)方法用来设置aroundMineNumber的值;
getAroundMineNumber()方法用来获取aroundMineNumber的值。
3.4 BlockView.java
(1)成员变量 blockNameOrIcon用来显示Block对象的name,number和mineIcon属性;blockCover用来遮挡blockNameOrIcon;card卡片式布局。
(2)方法 giveView(Block block)方法给参数指定的Block对象提供视图; seeBlockNameOrIcon()方法让用户看见视图中的标签,无法看见按钮; seeBlockCover()方法让用户看见视图中的按钮,无法看见标签。
3.5LayMines.java:
(1)成员变量 mineIcon用来存放一个格式为gif的图像。
(2)方法 layMinesForBlock(Block[][],int)方法对参数指定的Block数组进行设置,其中int参数指定雷的数目。
3.6Record.java:
(1)成员变量 textName提供用户扫雷优胜者出入姓名;用户单击“确定”按钮,可以保存成绩。
(2)方法
actionPerformed(ActionEvent)方法是Record类实现的ActionListener接口中的方法,当用户单击“确定”按钮后,该方法被执行,所执行的操作就是获取用户输入的名字和用时,然后调用writeRecord(String,String)方法将信息写入英雄榜中;writeRecord(String,String)负责将有关信息写入“英雄榜”文件。
3.7 ShowRecord:
(1)成员变量 file存放文件的引用,用户单击“显示成绩”按钮,可以查看各个级别的最好成绩;用户单击“重新计分”按钮,可以将“英雄榜”中的成绩恢复为初始值 。
(2)方法 actionPerformed(ActionEvent)方法是ShowRecord类实现的ActionListener接口中的方法,当用户单击“显示成绩”按钮后,该方法被执行,所执行的操作就是调用readAndShow()方法;readAndShow()方法负责读取存放在文件中的各个级别的扫雷最好成绩以及扫雷者姓名,并显示这些相关信息。
4运行与调试
运行界面1
运行界面2
运行界面3
5源代码
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
import java.util.*;
import java.io.*;
public class MineGame extends JFrame implements ActionListener{
JMenuBar bar;
JMenu fileMenu;
JMenuItem 初级,中级,高级,扫雷英雄榜;
MineArea mineArea=null;
File 英雄榜=new File("英雄榜.txt");
Hashtable hashtable=null;
ShowRecord showHeroRecord=null;
MineGame(){
mineArea=new MineArea(16,16,40,1);
add(mineArea,BorderLayout.CENTER);
bar=new JMenuBar();
fileMenu=new JMenu("游戏");
初级=new JMenuItem("初级");
中级=new JMenuItem("中级");
高级=new JMenuItem("高级");
扫雷英雄榜=new JMenuItem("扫雷英雄榜");
fileMenu.add(初级);
fileMenu.add(中级);
fileMenu.add(高级);
fileMenu.add(扫雷英雄榜);
bar.add(fileMenu);
setJMenuBar(bar);
初级.addActionListener(this);
中级.addActionListener(this);
高级.addActionListener(this);
扫雷英雄榜.addActionListener(this);
hashtable=new Hashtable();
hashtable.put("初级","初级#"+999+"#匿名");
hashtable.put("中级","中级#"+999+"#匿名");
hashtable.put("高级","高级#"+999+"#匿名");
if(!英雄榜.exists()) {
try{ FileOutputStream out=new FileOutputStream(英雄榜);
ObjectOutputStream objectOut=new ObjectOutputStream(out);
objectOut.writeObject(hashtable);
objectOut.close();
out.close();
}
catch(IOException e){}
}
showHeroRecord=new ShowRecord(this,hashtable);
setBounds(100,100,280,380);
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
validate();
}
public void actionPerformed(ActionEvent e){
if(e.getSource()==初级){
mineArea.initMineArea(8,8,10,1);
setBounds(100,100,200,280);
}
if(e.getSource()==中级){
mineArea.initMineArea(16,16,40,2);
setBounds(100,100,280,380);
}
if(e.getSource()==高级){
mineArea.initMineArea(22,22,99,3);
setBounds(100,100,350,390);
}
if(e.getSource()==扫雷英雄榜){
if(showHeroRecord!=null)
showHeroRecord.setVisible(true);
}
validate();
}
public static void main(String args[]){
new MineGame();
}
}
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class MineArea extends JPanel implements ActionListener,MouseListener{
JButton reStart;
Block [][] block;
BlockView [][] blockView;
LayMines lay;
int row,colum,mineCount,markMount;//雷区的行数、列数以及地雷个数和用户给出的标记数
ImageIcon mark;
int grade;
JPanel pCenter,pNorth;
JTextField showTime,showMarkedMineCount; //显示用时以及标记数
Timer time; //计时器
int spendTime=0;
Record record;
public MineArea(int row,int colum,int mineCount,int grade) {
reStart=new JButton("重新开始");
mark=new ImageIcon("mark.gif"); //探雷标记
time=new Timer(1000,this);
showTime=new JTextField(5);
showMarkedMineCount=new JTextField(5);
showTime.setHorizontalAlignment(JTextField.CENTER);
showMarkedMineCount.setHorizontalAlignment(JTextField.CENTER);
showMarkedMineCount.setFont(new Font("Arial",Font.BOLD,16));
showTime.setFont(new Font("Arial",Font.BOLD,16));
pCenter=new JPanel();
pNorth=new JPanel();
lay=new LayMines();
initMineArea(row,colum,mineCount,grade); //初始化雷区,见下面的LayMines()
reStart.addActionListener(this);
pNorth.add(showMarkedMineCount);
pNorth.add(reStart);
pNorth.add(showTime);
setLayout(new BorderLayout());
add(pNorth,BorderLayout.NORTH);
add(pCenter,BorderLayout.CENTER);
}
public void initMineArea(int row,int colum,int mineCount,int grade){
pCenter.removeAll();
spendTime=0;
markMount=mineCount;
this.row=row;
this.colum=colum;
this.mineCount=mineCount;
this.grade=grade;
block=new Block[row][colum];
for(int i=0;i<row;i++){
for(int j=0;j<colum;j++)
block[i][j]=new Block();
}
lay.layMinesForBlock(block,mineCount);
blockView=new BlockView[row][colum];
pCenter.setLayout(new GridLayout(row,colum));
for(int i=0;i<row;i++) {
for(int j=0;j<colum;j++) {
blockView[i][j]=new BlockView();
blockView[i][j].giveView(block[i][j]); //给block[i][j]提供视图
pCenter.add(blockView[i][j]);
blockView[i][j].getBlockCover().addActionListener(this);
blockView[i][j].getBlockCover().addMouseListener(this);
blockView[i][j].seeBlockCover();
blockView[i][j].getBlockCover().setEnabled(true);
blockView[i][j].getBlockCover().setIcon(null);
}
}
showMarkedMineCount.setText(""+markMount);
validate();
}
public void setRow(int row){
this.row=row;
}
public void setColum(int colum){
this.colum=colum;
}
public void setMineCount(int mineCount){
this.mineCount=mineCount;
}
public void setGrade(int grade) {
this.grade=grade;
}
public void actionPerformed(ActionEvent e) {
if(e.getSource()!=reStart&&e.getSource()!=time) {
time.start();
int m=-1,n=-1;
for(int i=0;i<row;i++) {
for(int j=0;j<colum;j++) {
if(e.getSource()==blockView[i][j].getBlockCover()){
m=i;
n=j;
break;
}
}
}
if(block[m][n].isMine()) {
for(int i=0;i<row;i++) {
for(int j=0;j<colum;j++) {
blockView[i][j].getBlockCover().setEnabled(false);
if(block[i][j].isMine())
blockView[i][j].seeBlockNameOrIcon();
}
}
time.stop();
spendTime=0;
markMount=mineCount;
}
else {
show(m,n); //见本类后面的show方法
}
}
if(e.getSource()==reStart) {
initMineArea(row,colum,mineCount,grade);
}
if(e.getSource()==time){
spendTime++;
showTime.setText(""+spendTime);
}
inquireWin();
}
public void show(int m,int n) {
if(block[m][n].getAroundMineNumber()>0&&block[m][n].getIsOpen()==false){
blockView[m][n].seeBlockNameOrIcon();
block[m][n].setIsOpen(true);
return;
}
else if(block[m][n].getAroundMineNumber()==0&&block[m][n].getIsOpen()==false){
blockView[m][n].seeBlockNameOrIcon();
block[m][n].setIsOpen(true);
for(int k=Math.max(m-1,0);k<=Math.min(m+1,row-1);k++) {
for(int t=Math.max(n-1,0);t<=Math.min(n+1,colum-1);t++)
show(k,t);
}
}
}
public void mousePressed(MouseEvent e){
JButton source=(JButton)e.getSource();
for(int i=0;i<row;i++) {
for(int j=0;j<colum;j++) {
if(e.getModifiers()==InputEvent.BUTTON3_MASK&&
source==blockView[i][j].getBlockCover()){
if(block[i][j].getIsMark()) {
source.setIcon(null);
block[i][j].setIsMark(false);
markMount=markMount+1;
showMarkedMineCount.setText(""+markMount);
}
else{
source.setIcon(mark);
block[i][j].setIsMark(true);
markMount=markMount-1;
showMarkedMineCount.setText(""+markMount);
}
}
}
}
}
public void inquireWin(){
int number=0;
for(int i=0;i<row;i++) {
for(int j=0;j<colum;j++) {
if(block[i][j].getIsOpen()==false)
number++;
}
}
if(number==mineCount){
time.stop();
record=new Record();
switch(grade){
case 1: record.setGrade("初级");
break;
case 2: record.setGrade("中级");
break;
case 3: record.setGrade("高级");
break;
}
record.setTime(spendTime);
record.setVisible(true);
}
}
public void mouseReleased(MouseEvent e){}
public void mouseEntered(MouseEvent e){}
public void mouseExited(MouseEvent e){}
public void mouseClicked(MouseEvent e){}
}
import javax.swing.ImageIcon;
public class Block {
String name; //名字,比如"雷"或数字
int aroundMineNumber; //周围雷的数目
ImageIcon mineIcon; //雷的图标
boolean isMine=false; //是否是雷
boolean isMark=false; //是否被标记
boolean isOpen=false; //是否被挖开
public void setName(String name) {
this.name=name;
}
public void setAroundMineNumber(int n) {
aroundMineNumber=n;
}
public int getAroundMineNumber() {
return aroundMineNumber;
}
public String getName() {
return name;
}
public boolean isMine() {
return isMine;
}
public void setIsMine(boolean b) {
isMine=b;
}
public void setMineIcon(ImageIcon icon){
mineIcon=icon;
}
public ImageIcon getMineicon(){
return mineIcon;
}
public boolean getIsOpen() {
return isOpen;
}
public void setIsOpen(boolean p) {
isOpen=p;
}
public boolean getIsMark() {
return isMark;
}
public void setIsMark(boolean m) {
isMark=m;
}
}
import javax.swing.*;
import java.awt.*;
public class BlockView extends JPanel{
JLabel blockNameOrIcon; //用来显示Block对象的name、number和mineIcon属性
JButton blockCover; //用来遮挡blockNameOrIcon.
CardLayout card; //卡片式布局
BlockView(){
card=new CardLayout();
setLayout(card);
blockNameOrIcon=new JLabel("",JLabel.CENTER);
blockNameOrIcon.setHorizontalTextPosition(AbstractButton.CENTER);
blockNameOrIcon.setVerticalTextPosition(AbstractButton.CENTER);
blockCover=new JButton();
add("cover",blockCover);
add("view",blockNameOrIcon);
}
public void giveView(Block block){
if(block.isMine){
blockNameOrIcon.setText(block.getName());
blockNameOrIcon.setIcon(block.getMineicon());
}
else {
int n=block.getAroundMineNumber();
if(n>=1)
blockNameOrIcon.setText(""+n);
else
blockNameOrIcon.setText(" ");
}
}
public void seeBlockNameOrIcon(){
card.show(this,"view");
validate();
}
public void seeBlockCover(){
card.show(this,"cover");
validate();
}
public JButton getBlockCover(){
return blockCover;
}
}
import java.util.*;
import javax.swing.*;
public class LayMines{
ImageIcon mineIcon;
LayMines() {
mineIcon=new ImageIcon("mine.gif");
}
public void layMinesForBlock(Block block[][],int mineCount){
int row=block.length;
int column=block[0].length;
LinkedList<Block> list=new LinkedList<Block>();
for(int i=0;i<row;i++) {
for(int j=0;j<column;j++)
list.add(block[i][j]);
}
while(mineCount>0){
int size=list.size(); // list返回节点的个数
int randomIndex=(int)(Math.random()*size);
Block b=list.get(randomIndex);
b.setIsMine(true);
b.setName("雷");
b.setMineIcon(mineIcon);
list.remove(randomIndex); //list删除索引值为randomIndex的节点
mineCount--;
}
for(int i=0;i<row;i++){
for(int j=0;j<column;j++){
if(block[i][j].isMine()){
block[i][j].setIsOpen(false);
block[i][j].setIsMark(false);
}
else {
int mineNumber=0;
for(int k=Math.max(i-1,0);k<=Math.min(i+1,row-1);k++) {
for(int t=Math.max(j-1,0);t<=Math.min(j+1,column-1);t++){
if(block[k][t].isMine())
mineNumber++;
}
}
block[i][j].setIsOpen(false);
block[i][j].setIsMark(false);
block[i][j].setName(""+mineNumber);
block[i][j].setAroundMineNumber(mineNumber);
}
}
}
}
}
import java.io.*;
import java.util.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class Record extends JDialog implements ActionListener{
int time=0;
String grade=null;
String key=null;
String message=null;
JTextField textName;
JLabel label=null;
JButton 确定,取消;
public Record(){
setTitle("记录你的成绩");
this.time=time;
this.grade=grade;
setBounds(100,100,240,160);
setResizable(false);
setModal(true);
确定=new JButton("确定");
取消=new JButton("取消");
textName=new JTextField(8);
textName.setText("匿名");
确定.addActionListener(this);
取消.addActionListener(this);
setLayout(new GridLayout(2,1));
label=new JLabel("您现在是...高手,输入您的大名上榜");
add(label);
JPanel p=new JPanel();
p.add(textName);
p.add(确定);
p.add(取消);
add(p);
setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
}
public void setGrade(String grade){
this.grade=grade;
label.setText("您现在是"+grade+"高手,输入您的大名上榜");
}
public void setTime(int time){
this.time=time;
}
public void actionPerformed(ActionEvent e){
if(e.getSource()==确定){
message=grade+"#"+time+"#"+" "+textName.getText();
key=grade;
writeRecord(key,message);
setVisible(false);
}
if(e.getSource()==取消){
setVisible(false);
}
}
public void writeRecord(String key,String message){
File f=new File("英雄榜.txt");
try{ FileInputStream in=new FileInputStream(f);
ObjectInputStream object_in=new ObjectInputStream(in);
Hashtable hashtable=(Hashtable)object_in.readObject();
object_in.close();
in.close();
String temp=(String)hashtable.get(key);
StringTokenizer fenxi=new StringTokenizer(temp,"#");
fenxi.nextToken();
int n=Integer.parseInt(fenxi.nextToken());
if(time<n){
hashtable.put(key,message);
FileOutputStream out=new FileOutputStream(f);
ObjectOutputStream object_out=new ObjectOutputStream(out);
object_out.writeObject(hashtable);
object_out.close();
out.close();
}
}
catch(Exception e) {
System.out.println(e);
}
}
}
import java.io.*;
import java.util.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class ShowRecord extends JDialog implements ActionListener{
File file=new File("英雄榜.txt");
String name=null;
Hashtable hashtable=null;
JButton 显示,重新记分;
JLabel label初级[],label中级[],label高级[];
public ShowRecord(JFrame frame,Hashtable h) {
setTitle("扫雷英雄榜");
hashtable=h;
setBounds(100,100,320,185);
setResizable(false);
setVisible(false);
setModal(true);
label初级=new JLabel[3];
label中级=new JLabel[3];
label高级=new JLabel[3];
for(int i=0;i<3;i++) {
label初级[i]=new JLabel();
label初级[i].setBorder(null);
label中级[i]=new JLabel();
label中级[i].setBorder(null);
label高级[i]=new JLabel();
label高级[i].setBorder(null);
}
label初级[0].setText("初级");
label初级[1].setText(""+999);
label初级[1].setText("匿名");
label中级[0].setText("中级");
label中级[1].setText(""+999);
label中级[1].setText("匿名");
label高级[0].setText("高级");
label高级[1].setText(""+999);
label高级[1].setText("匿名");
JPanel pCenter=new JPanel();
pCenter.setLayout(new GridLayout(3,3));
for(int i=0;i<3;i++)
pCenter.add(label初级[i]);
for(int i=0;i<3;i++)
pCenter.add(label中级[i]);
for(int i=0;i<3;i++)
pCenter.add(label高级[i]);
pCenter.setBorder(BorderFactory.createTitledBorder("扫雷英雄榜"));
显示=new JButton("显示成绩");
重新记分=new JButton("重新记分");
显示.addActionListener(this);
重新记分.addActionListener(this);
JPanel pSouth=new JPanel();
pSouth.setLayout(new FlowLayout(FlowLayout.RIGHT));
pSouth.add(重新记分);
pSouth.add(显示);
add(pCenter,BorderLayout.CENTER);
add(pSouth,BorderLayout.SOUTH) ;
}
public void readAndShow(){
try{ FileInputStream in=new FileInputStream(file);
ObjectInputStream object_in=new ObjectInputStream(in);
hashtable=(Hashtable)object_in.readObject();
object_in.close();
in.close();
String temp=(String)hashtable.get("初级");
StringTokenizer fenxi=new StringTokenizer(temp,"#");
label初级[0].setText(fenxi.nextToken());
label初级[1].setText(fenxi.nextToken());
label初级[2].setText(fenxi.nextToken());
temp=(String)hashtable.get("中级");
fenxi=new StringTokenizer(temp,"#");
label中级[0].setText(fenxi.nextToken());
label中级[1].setText(fenxi.nextToken());
label中级[2].setText(fenxi.nextToken());
temp=(String)hashtable.get("高级");
fenxi=new StringTokenizer(temp,"#");
label高级[0].setText(fenxi.nextToken());
label高级[1].setText(fenxi.nextToken());
label高级[2].setText(fenxi.nextToken());
}
catch(Exception e){}
}
public void actionPerformed(ActionEvent e) {
if(e.getSource()==重新记分) {
hashtable.put("初级","初级#"+999+"#匿名");
label初级[0].setText("初级");
label初级[1].setText(""+999);
label初级[2].setText("匿名");
hashtable.put("中级","中级#"+999+"#匿名");
label中级[0].setText("初级");
label中级[1].setText(""+999);
label中级[2].setText("匿名");
hashtable.put("高级","高级#"+999+"#匿名");
label高级[0].setText("初级");
label高级[1].setText(""+999);
label高级[2].setText("匿名");
try{ FileOutputStream out=new FileOutputStream(file);
ObjectOutputStream object_out=new ObjectOutputStream(out);
object_out.writeObject(hashtable);
object_out.close();
out.close();
}
catch(IOException event){}
setVisible(false);
}
if(e.getSource()==显示){
readAndShow();
}
}
}
6总结
我课程设计选这个题目原因是我一直比较喜欢这个游戏,对这款游戏的操作以及玩法度比较了解,所以做起来比较容易点,同时我也想玩玩自己亲手做出这个小游戏,所以选了这个题目,扫雷游戏是一款智力游戏,这款游戏将一定的地雷分布在小格子里,最终胜利是玩家将所有的地雷都找出。Java是我们这个学期新学的语言,通过这个课程设计,我对以前学的知识有了更深一步的了解,这次设计的时间有限,所以我做了一个自己比较喜欢的小游戏,刚开始做时,虽然知道主要思想但把它要表示出来真的很不容易,通过查资料,请教同学,上网,知道了知识可能是自己一个人要花很长时间知道的,经过这段时间的努力,终于做出了这款游戏,虽然还有很多不足,但做出来后还是很开心的,测试这个游戏的功能时,感觉很不错,通过这个课程设计我对以前java有了一个更深一步的认识。