目录
- 一、效果展示
- 初级难度
- 中级难度
- 高级难度
- 测试界面
- 二、项目介绍
- 项目背景
- 功能分析
- 三、代码展示
- 图形界面设计(gui包)
- 用户操作设计(data包)
- 游戏视图设计(view包)
- 四、代码测试
- 五、项目结构
- 六、设计总结
- 总结
一、效果展示
初级难度
中级难度
高级难度
测试界面
二、项目介绍
项目背景
扫雷是一款大众类的益智小游戏。根据点击格子出现的数字找出所有非雷格子,同时避免踩雷,踩到一个雷即全盘皆输。这款游戏有着很长的历史,从扫雷被开发出来到现在进行了无数次的优化,这款游戏通过简单的玩法,加上一个好看的游戏界面,每一处的细节都体现了扫雷的魅力。
功能分析
完成 难度选择,雷随机生成,数字生成,左右键翻开 等功能实现
游戏四种状态: 难度选择、游戏状态、游戏胜利、游戏失败
游戏难度: 初级、中级、高级(不同难度对应不同的雷区大小和雷数量)
游戏核心: 二维数组 的相关操作
其他: 窗口绘制、界面规划、操作计数、重新开始。
三、代码展示
图形界面设计(gui包)
主类:AppWindows类
AppWindow类负责创建游戏的主窗口,该类含有main方法,程序从该类开始执行。
package ch.gui; | |
import java.awt.*; | |
import javax.swing.*; | |
import javax.swing.event.*; | |
import java.awt.event.*; | |
import ch.view.MineArea; | |
import ch.view.ShowRecord; | |
public class AppWindow extends JFrame implements MenuListener,ActionListener{ | |
JMenuBar bar; | |
JMenu fileMenu; | |
JMenu gradeOne,gradeTwo,gradeThree;//扫雷级别 | |
JMenuItem gradeOneList,gradeTwoList,gradeThreeList;//初,中,高级英雄榜 | |
MineArea mineArea=null; //扫雷区域 | |
ShowRecord showHeroRecord=null; //查看英雄榜 | |
public AppWindow(){ | |
bar=new JMenuBar(); | |
fileMenu=new JMenu("扫雷游戏"); | |
gradeOne=new JMenu("初级"); | |
gradeTwo=new JMenu("中级"); | |
gradeThree=new JMenu("高级"); | |
gradeOneList=new JMenuItem("初级英雄榜"); | |
gradeTwoList=new JMenuItem("中级英雄榜"); | |
gradeThreeList=new JMenuItem("高级英雄榜"); | |
gradeOne.add(gradeOneList); | |
gradeTwo.add(gradeTwoList); | |
gradeThree.add(gradeThreeList); | |
fileMenu.add(gradeOne); | |
fileMenu.add(gradeTwo); | |
fileMenu.add(gradeThree); | |
bar.add(fileMenu); | |
setJMenuBar(bar); | |
gradeOne.addMenuListener(this); | |
gradeTwo.addMenuListener(this); | |
gradeThree.addMenuListener(this); | |
gradeOneList.addActionListener(this); | |
gradeTwoList.addActionListener(this); | |
gradeThreeList.addActionListener(this); | |
mineArea=new MineArea(,9,10,gradeOne.getText());//创建初级扫雷区 | |
add(mineArea,BorderLayout.CENTER); | |
showHeroRecord=new ShowRecord(); | |
setBounds(,100,500,450); | |
setVisible(true); | |
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); | |
validate(); | |
} | |
public void menuSelected(MenuEvent e){ | |
if(e.getSource()==gradeOne){ | |
mineArea.initMineArea(,9,10,gradeOne.getText()); | |
validate(); | |
} | |
else if(e.getSource()==gradeTwo){ | |
mineArea.initMineArea(,16,40,gradeTwo.getText()); | |
validate(); | |
} | |
else if(e.getSource()==gradeThree){ | |
mineArea.initMineArea(,30,99,gradeThree.getText()); | |
validate(); | |
} | |
} | |
public void menuCanceled(MenuEvent e){} | |
public void menuDeselected(MenuEvent e){} | |
public void actionPerformed(ActionEvent e){ | |
if(e.getSource()==gradeOneList){ | |
showHeroRecord.setGrade(gradeOne.getText()); | |
showHeroRecord.showRecord(); | |
} | |
else if(e.getSource()==gradeTwoList){ | |
showHeroRecord.setGrade(gradeTwo.getText()); | |
showHeroRecord.showRecord(); | |
} | |
else if(e.getSource()==gradeThreeList){ | |
showHeroRecord.setGrade(gradeThree.getText()); | |
showHeroRecord.showRecord(); | |
} | |
} | |
public static void main(String args[]){ | |
new AppWindow(); | |
} | |
} |
用户操作设计(data包)
Block类
package ch.data; | |
import javax.swing.ImageIcon; | |
public class Block { | |
String name; //名字,比如"雷"或数字 | |
int aroundMineNumber; //如果不是类,此数据是周围雷的数目 | |
ImageIcon mineIcon; //雷的图标 | |
public boolean isMine=false; //是否是雷 | |
boolean isMark=false; //是否被标记 | |
boolean isOpen=false; //是否被挖开 | |
ViewForBlock blockView; //方块的视图 | |
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; | |
} | |
public void setBlockView(ViewForBlock view){ | |
blockView = view; | |
blockView.acceptBlock(this); | |
} | |
public ViewForBlock getBlockView(){ | |
return blockView ; | |
} | |
} |
LayMines类
package ch.data; | |
import java.util.LinkedList; | |
import javax.swing.ImageIcon; | |
public class LayMines { | |
ImageIcon mineIcon; | |
public LayMines() { | |
mineIcon=new ImageIcon("扫雷图片/mine.gif"); | |
} | |
public void initBlock(Block [][] block){ | |
for(int i=;i<block.length;i++) { | |
for(int j=;j<block[i].length;j++) | |
block[i][j].setIsMine(false); | |
} | |
} | |
public void layMinesForBlock(Block [][] block,int mineCount){ //在雷区布置mineCount个雷 | |
initBlock(block); //先都设置是无雷 | |
int row=block.length; | |
int column=block[].length; | |
LinkedList<Block> list=new LinkedList<Block>(); | |
for(int i=;i<row;i++) { | |
for(int j=;j<column;j++) | |
list.add(block[i][j]); | |
} | |
while(mineCount>){ //开始布雷 | |
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=;i<row;i++){ //检查布雷情况,标记每个方块周围的雷的数目 | |
for(int j=;j<column;j++){ | |
if(block[i][j].isMine()){ | |
block[i][j].setIsOpen(false); | |
block[i][j].setIsMark(false); | |
} | |
else { | |
int mineNumber=; | |
for(int k=Math.max(i-,0);k<=Math.min(i+1,row-1);k++) { | |
for(int t=Math.max(j-,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); //设置该方块周围的雷数目 | |
} | |
} | |
} | |
} | |
} |
PeopleScoutMine类
package ch.data; | |
import java.util.Stack; | |
public class PeopleScoutMine { | |
public Block [][] block; //雷区的全部方块 | |
Stack<Block> notMineBlock; //存放一个方块周围区域内不是雷的方块 | |
int m,n ; //方块的索引下标 | |
int row,colum; //雷区的行和列 | |
int mineCount; //雷的数目 | |
public PeopleScoutMine(){ | |
notMineBlock = new Stack<Block>(); | |
} | |
public void setBlock(Block [][] block,int mineCount){ | |
this.block = block; | |
this.mineCount = mineCount; | |
row = block.length; | |
colum = block[].length; | |
} | |
public Stack<Block> getNoMineAroundBlock(Block bk){//得到方块bk附近区域不是雷的方块 | |
notMineBlock.clear(); | |
for(int i=;i<row;i++) { //寻找bk在雷区block中的位置索引 | |
for(int j=;j<colum;j++) { | |
if(bk == block[i][j]){ | |
m=i; | |
n=j; | |
break; | |
} | |
} | |
} | |
if(!bk.isMine()) { //方块不是雷 | |
show(m,n); //见后面的递归方法 | |
} | |
return notMineBlock; | |
} | |
public void show(int m,int n) { | |
if(block[m][n].getAroundMineNumber()>&&block[m][n].getIsOpen()==false){ | |
block[m][n].setIsOpen(true); | |
notMineBlock.push(block[m][n]); //将不是雷的方块压栈 | |
return; | |
} | |
else if(block[m][n].getAroundMineNumber()==&&block[m][n].getIsOpen()==false){ | |
block[m][n].setIsOpen(true); | |
notMineBlock.push(block[m][n]); //将不是雷的方块压栈 | |
for(int k=Math.max(m-,0);k<=Math.min(m+1,row-1);k++) { | |
for(int t=Math.max(n-,0);t<=Math.min(n+1,colum-1);t++) | |
show(k,t); | |
} | |
} | |
} | |
public boolean verifyWin(){ | |
boolean isOK = false; | |
int number=; | |
for(int i=;i<row;i++) { | |
for(int j=;j<colum;j++) { | |
if(block[i][j].getIsOpen()==false) | |
number++; | |
} | |
} | |
if(number==mineCount){ | |
isOK =true; | |
} | |
return isOK; | |
} | |
} |
RecordOrShowRecord类
package ch.data; | |
import java.sql.*; | |
public class RecordOrShowRecord{ | |
Connection con; | |
String tableName ; | |
int heroNumber =; //英雄榜显示的最多英雄数目 | |
public RecordOrShowRecord(){ | |
try{Class.forName("org.apache.derby.jdbc.EmbeddedDriver"); | |
} | |
catch(Exception e){} | |
} | |
public void setTable(String str){ | |
tableName = "t_"+str; | |
connectDatabase();//连接数据库 | |
try { | |
Statement sta = con.createStatement(); | |
String SQL="create table "+tableName+ | |
"(p_name varchar() ,p_time int)"; | |
sta.executeUpdate(SQL);//创建表 | |
con.close(); | |
} | |
catch(SQLException e) {//如果表已经存在,将触发SQL异常,即不再创建该表 | |
} | |
} | |
public boolean addRecord(String name,int time){ | |
boolean ok = true; | |
if(tableName == null) | |
ok = false; | |
//检查time是否达到标准(进入前heroNumber名),见后面的verifyScore方法: | |
int amount = verifyScore(time); | |
if(amount >= heroNumber) { | |
ok = false; | |
} | |
else { | |
connectDatabase(); //连接数据库 | |
try { | |
String SQL ="insert into "+tableName+" values(?,?)"; | |
PreparedStatement sta = con.prepareStatement(SQL); | |
sta.setString(,name); | |
sta.setInt(,time); | |
sta.executeUpdate(); | |
con.close(); | |
ok = true; | |
} | |
catch(SQLException e) { | |
ok = false; | |
} | |
} | |
return ok; | |
} | |
public String [][] queryRecord(){ | |
if(tableName == null) | |
return null; | |
String [][] record = null; | |
Statement sql; | |
ResultSet rs; | |
try { | |
sql= | |
con.createStatement | |
(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY); | |
String str = "select * from "+tableName+" order by p_time "; | |
rs=sql.executeQuery(str); | |
boolean boo =rs.last(); | |
if(boo == false) | |
return null; | |
int recordAmount =rs.getRow();//结果集中的全部记录 | |
record = new String[recordAmount][]; | |
rs.beforeFirst(); | |
int i=; | |
while(rs.next()) { | |
record[i][] = rs.getString(1); | |
record[i][] = rs.getString(2); | |
i++; | |
} | |
con.close(); | |
} | |
catch(SQLException e) {} | |
return record; | |
} | |
private void connectDatabase(){ | |
try{ | |
String uri ="jdbc:derby:record;create=true"; | |
con=DriverManager.getConnection(uri); //连接数据库,如果不存在就创建 | |
} | |
catch(Exception e){} | |
} | |
private int verifyScore(int time){ | |
if(tableName == null) | |
return Integer.MAX_VALUE ; | |
connectDatabase(); //连接数据库 | |
Statement sql; | |
ResultSet rs; | |
int amount =; | |
String str = | |
"select * from "+tableName+" where p_time < "+time; | |
try { | |
sql=con.createStatement(); | |
rs=sql.executeQuery(str); | |
while(rs.next()){ | |
amount++; | |
} | |
con.close(); | |
} | |
catch(SQLException e) {} | |
return amount; | |
} | |
} |
ViewForBlock接口
package ch.data; | |
public interface ViewForBlock { | |
public void acceptBlock(Block block);//确定是哪个方块的视图 | |
public void setDataOnView(); //设置视图上需要显示的数据 | |
public void seeBlockNameOrIcon();//显示图标方块上的名字或 | |
public void seeBlockCover(); //显示视图上负责遮挡的组件 | |
public Object getBlockCover(); //得到视图上的遮挡组件 | |
} |
游戏视图设计(view包)
BlockView类
package ch.view; | |
import javax.swing.*; | |
import java.awt.*; | |
import ch.data.*; | |
public class BlockView extends JPanel implements ViewForBlock{ | |
JLabel blockNameOrIcon; //用来显示Block对象的name、number和mineIcon属性 | |
JButton blockCover; //用来遮挡blockNameOrIcon. | |
CardLayout card; //卡片式布局 | |
Block block ; //被提供视图的方块 | |
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 acceptBlock(Block block){ | |
this.block = block; | |
} | |
public void setDataOnView(){ | |
if(block.isMine()){ | |
blockNameOrIcon.setText(block.getName()); | |
blockNameOrIcon.setIcon(block.getMineicon()); | |
} | |
else { | |
int n=block.getAroundMineNumber(); | |
if(n>=) | |
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; | |
} | |
} |
MineArea类
package ch.view; | |
import java.awt.*; | |
import java.awt.event.*; | |
import javax.swing.*; | |
import ch.data.*; | |
import java.util.Stack; | |
public class MineArea extends JPanel implements ActionListener,MouseListener{ | |
JButton reStart; | |
Block [][] block; //雷区的方块 | |
BlockView [][] blockView; //方块的视图 | |
LayMines lay; //负责布雷 | |
PeopleScoutMine peopleScoutMine; //负责扫雷 | |
int row,colum,mineCount,markMount;//雷区的行数、列数以及地雷个数和用户给出的标记数 | |
ImageIcon mark; //探雷作的标记 | |
String grade; //游戏级别 | |
JPanel pCenter,pNorth; //布局用的面板 | |
JTextField showTime,showMarkedMineCount; //显示用时和探雷作的标记数目(不一定是雷哦) | |
Timer time; //计时器 | |
int spendTime=; //扫雷的用时 | |
Record record; //负责记录到英雄榜 | |
PlayMusic playMusic; //负责播放雷爆炸的声音 | |
public MineArea(int row,int colum,int mineCount,String grade) { | |
record = new Record(); //负责保存成绩到英雄榜 | |
reStart=new JButton("重新开始"); | |
mark=new ImageIcon("扫雷图片/mark.png"); //探雷标记 | |
time=new Timer(,this); //计时器,每个一秒触发ActionEvent事件一次 | |
showTime=new JTextField(); | |
showMarkedMineCount=new JTextField(); | |
showTime.setHorizontalAlignment(JTextField.CENTER); | |
showMarkedMineCount.setHorizontalAlignment(JTextField.CENTER); | |
showMarkedMineCount.setFont(new Font("Arial",Font.BOLD,)); | |
showTime.setFont(new Font("Arial",Font.BOLD,)); | |
pCenter=new JPanel(); | |
pNorth=new JPanel(); | |
lay=new LayMines(); //创建布雷者 | |
peopleScoutMine = new PeopleScoutMine(); //创建扫雷者 | |
initMineArea(row,colum,mineCount,grade); //初始化雷区,见下面的initMineArea方法 | |
reStart.addActionListener(this); | |
pNorth.add(new JLabel("剩余雷数(千万别弄错啊):")); | |
pNorth.add(showMarkedMineCount); | |
pNorth.add(reStart); | |
pNorth.add(new JLabel("用时:")); | |
pNorth.add(showTime); | |
setLayout(new BorderLayout()); | |
add(pNorth,BorderLayout.NORTH); | |
add(pCenter,BorderLayout.CENTER); | |
playMusic = new PlayMusic(); //负责播放触雷爆炸的声音 | |
playMusic.setClipFile("扫雷图片/mine.wav"); | |
} | |
public void initMineArea(int row,int colum,int mineCount,String grade){ | |
pCenter.removeAll(); | |
spendTime=; | |
markMount=mineCount; | |
this.row=row; | |
this.colum=colum; | |
this.mineCount=mineCount; | |
this.grade=grade; | |
block=new Block[row][colum]; | |
for(int i=;i<row;i++){ | |
for(int j=;j<colum;j++) | |
block[i][j]=new Block(); | |
} | |
lay.layMinesForBlock(block,mineCount); //布雷 | |
peopleScoutMine.setBlock(block,mineCount); //准备扫雷 | |
blockView=new BlockView[row][colum]; //创建方块的视图 | |
pCenter.setLayout(new GridLayout(row,colum)); | |
for(int i=;i<row;i++) { | |
for(int j=;j<colum;j++) { | |
blockView[i][j]=new BlockView(); | |
block[i][j].setBlockView(blockView[i][j]); //方块设置自己的视图 | |
blockView[i][j].setDataOnView(); //将block[i][j]的数据放入视图 | |
pCenter.add(blockView[i][j]); | |
blockView[i][j].getBlockCover().addActionListener(this);//注册监视器 | |
blockView[i][j].getBlockCover().addMouseListener(this); | |
blockView[i][j].seeBlockCover(); //初始时盖住block[i][j]的数据信息 | |
blockView[i][j].getBlockCover().setEnabled(true); | |
blockView[i][j].getBlockCover().setIcon(null); | |
} | |
} | |
showMarkedMineCount.setText(""+markMount); | |
repaint(); | |
} | |
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(String grade) { | |
this.grade=grade; | |
} | |
public void actionPerformed(ActionEvent e) { | |
if(e.getSource()!=reStart&&e.getSource()!=time) { | |
time.start(); | |
int m=-,n=-1; | |
for(int i=;i<row;i++) { //找到单击的方块以及它的位置索引 | |
for(int j=;j<colum;j++) { | |
if(e.getSource()==blockView[i][j].getBlockCover()){ | |
m=i; | |
n=j; | |
break; | |
} | |
} | |
} | |
if(block[m][n].isMine()) { //用户输掉游戏 | |
for(int i=;i<row;i++) { | |
for(int j=;j<colum;j++) { | |
blockView[i][j].getBlockCover().setEnabled(false);//用户单击无效了 | |
if(block[i][j].isMine()) | |
blockView[i][j].seeBlockNameOrIcon(); //视图显示方块上的数据信息 | |
} | |
} | |
time.stop(); | |
spendTime=; //恢复初始值 | |
markMount=mineCount; //恢复初始值 | |
playMusic.playMusic(); //播放类爆炸的声音 | |
} | |
else { //扫雷者得到block[m][n]周围区域不是雷的方块 | |
Stack<Block> notMineBlock =peopleScoutMine.getNoMineAroundBlock(block[m][n]); | |
while(!notMineBlock.empty()){ | |
Block bk = notMineBlock.pop(); | |
ViewForBlock viewforBlock = bk.getBlockView(); | |
viewforBlock.seeBlockNameOrIcon();//视图显示方块上的数据信息 | |
System.out.println("ookk"); | |
} | |
} | |
} | |
if(e.getSource()==reStart) { | |
initMineArea(row,colum,mineCount,grade); | |
repaint(); | |
validate(); | |
} | |
if(e.getSource()==time){ | |
spendTime++; | |
showTime.setText(""+spendTime); | |
} | |
if(peopleScoutMine.verifyWin()) { //判断用户是否扫雷成功 | |
time.stop(); | |
record.setGrade(grade); | |
record.setTime(spendTime); | |
record.setVisible(true); //弹出录入到英雄榜对话框 | |
} | |
} | |
public void mousePressed(MouseEvent e){ //探雷:给方块上插一个小旗图标(再次单击取消) | |
JButton source=(JButton)e.getSource(); | |
for(int i=;i<row;i++) { | |
for(int j=;j<colum;j++) { | |
if(e.getModifiers()==InputEvent.BUTTON_MASK&& | |
source==blockView[i][j].getBlockCover()){ | |
if(block[i][j].getIsMark()) { | |
source.setIcon(null); | |
block[i][j].setIsMark(false); | |
markMount=markMount+; | |
showMarkedMineCount.setText(""+markMount); | |
} | |
else{ | |
source.setIcon(mark); | |
block[i][j].setIsMark(true); | |
markMount=markMount-; | |
showMarkedMineCount.setText(""+markMount); | |
} | |
} | |
} | |
} | |
} | |
public void mouseReleased(MouseEvent e){} | |
public void mouseEntered(MouseEvent e){} | |
public void mouseExited(MouseEvent e){} | |
public void mouseClicked(MouseEvent e){} | |
} |
PlayMusic类
package ch.view; | |
import java.net.URI; | |
import java.net.URL; | |
import java.io.File; | |
import java.applet.Applet; | |
import java.applet.AudioClip; | |
public class PlayMusic implements Runnable { | |
String musicName; | |
Thread threadPlay; | |
AudioClip clip = null; | |
public PlayMusic(){ | |
threadPlay = new Thread(this); | |
} | |
public void run() { | |
clip.play(); | |
} | |
public void playMusic(){ | |
threadPlay = new Thread(this); | |
try{ | |
threadPlay.start(); | |
} | |
catch(Exception exp) {} | |
} | |
public void setClipFile(String name){ | |
musicName = name; | |
if(musicName == null) | |
musicName = "扫雷图像/mine.wav"; | |
File file=new File(musicName); | |
try { URI uri=file.toURI(); | |
URL url=uri.toURL(); | |
clip=Applet.newAudioClip(url); | |
} | |
catch(Exception ee){} | |
} | |
} |
Record类
package ch.view; | |
import javax.swing.*; | |
import java.awt.event.*; | |
import ch.data.RecordOrShowRecord; | |
public class Record extends JDialog implements ActionListener{ | |
int time=; | |
String grade=null; | |
String key=null; | |
String message=null; | |
JTextField textName; | |
JLabel label=null; | |
JButton confirm,cancel; | |
public Record(){ | |
setTitle("记录你的成绩"); | |
this.time=time; | |
this.grade=grade; | |
setBounds(,100,240,160); | |
setResizable(false); | |
setModal(true); | |
confirm=new JButton("确定"); | |
cancel=new JButton("取消"); | |
textName=new JTextField(); | |
textName.setText("匿名"); | |
confirm.addActionListener(this); | |
cancel.addActionListener(this); | |
setLayout(new java.awt.GridLayout(,1)); | |
label=new JLabel("输入您的大名看是否可上榜"); | |
add(label); | |
JPanel p=new JPanel(); | |
p.add(textName); | |
p.add(confirm); | |
p.add(cancel); | |
add(p); | |
setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); | |
} | |
public void setGrade(String grade){ | |
this.grade=grade; | |
} | |
public void setTime(int time){ | |
this.time=time; | |
} | |
public void actionPerformed(ActionEvent e){ | |
if(e.getSource()==confirm){ | |
String name = textName.getText(); | |
writeRecord(name,time); | |
setVisible(false); | |
} | |
if(e.getSource()==cancel){ | |
setVisible(false); | |
} | |
} | |
public void writeRecord(String name,int time){ | |
RecordOrShowRecord rd = new RecordOrShowRecord(); | |
rd.setTable(grade); | |
boolean boo= rd.addRecord(name,time); | |
if(boo){ | |
JOptionPane.showMessageDialog | |
(null,"恭喜您,上榜了","消息框", JOptionPane.WARNING_MESSAGE); | |
} | |
else { | |
JOptionPane.showMessageDialog | |
(null,"成绩不能上榜","消息框", JOptionPane.WARNING_MESSAGE); | |
} | |
} | |
} |
ShowRecord类
package ch.view; | |
import java.awt.*; | |
import javax.swing.*; | |
import ch.data.RecordOrShowRecord; | |
public class ShowRecord extends JDialog { | |
String [][] record; | |
JTextArea showMess; | |
RecordOrShowRecord rd;//负责查询数据库的对象 | |
public ShowRecord() { | |
rd = new RecordOrShowRecord(); | |
showMess = new JTextArea(); | |
showMess.setFont(new Font("楷体",Font.BOLD,)); | |
add(new JScrollPane(showMess)); | |
setTitle("显示英雄榜"); | |
setBounds(,200,400,300); | |
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); | |
} | |
public void setGrade(String grade){ | |
rd.setTable(grade); | |
} | |
public void setRecord(String [][]record){ | |
this.record=record; | |
} | |
public void showRecord() { | |
showMess.setText(null); | |
record = rd.queryRecord(); | |
if(record == null ) { | |
JOptionPane.showMessageDialog | |
(null,"没人上榜呢","消息框", JOptionPane.WARNING_MESSAGE); | |
} | |
else { | |
for(int i = ;i<record.length;i++){ | |
int m = i+; | |
showMess.append("\n英雄"+m+":"+record[i][]+" "+"成绩:"+record[i][1]); | |
showMess.append("\n--------------------------------"); | |
} | |
setVisible(true); | |
} | |
} | |
} |
四、代码测试
这里我们创建test包,实现AppTest类来进行代码的测试,代码如下:
package ch.test; | |
import ch.data.*; | |
import java.util.Stack; | |
public class AppTest { | |
public static void main(String [] args) { | |
Block block[][] = new Block[][10]; //雷区 | |
for(int i=;i<block.length;i++) { | |
for(int j =;j<block[i].length;j++) { | |
block[i][j] = new Block(); | |
} | |
} | |
LayMines layMines = new LayMines(); //布雷者 | |
PeopleScoutMine peopleScoutMine = new PeopleScoutMine(); //扫雷者 | |
layMines.layMinesForBlock(block,); //在雷区布雷 | |
System.out.println("雷区情况:"); | |
intputShow(block); | |
peopleScoutMine.setBlock(block,); //准备扫雷 | |
Stack<Block> stack = peopleScoutMine.getNoMineAroundBlock(block[][0]);//扫雷 | |
if(block[][0].isMine()){ | |
System.out.println("我的天啊,踩着地雷了啊"); | |
return; | |
} | |
System.out.println("扫雷情况:"); | |
intputProcess(block,stack); | |
System.out.println("成功了吗:"+peopleScoutMine.verifyWin()); | |
if(block[][3].isMine()){ | |
System.out.println("我的天啊,踩着地雷了啊"); | |
return; | |
} | |
stack = peopleScoutMine.getNoMineAroundBlock(block[][3]);//扫雷 | |
System.out.println("扫雷情况:"); | |
intputProcess(block,stack); | |
System.out.println("成功了吗:"+peopleScoutMine.verifyWin()); | |
} | |
static void intputProcess(Block [][] block,Stack<Block> stack){ | |
int k =; | |
for(int i=;i<block.length;i++) { | |
for(int j =;j<block[i].length;j++){ | |
if(!stack.contains(block[i][j])&&block[i][j].getIsOpen()==false){ | |
System.out.printf("%s","■ "); //输出■表示未挖开方块 | |
} | |
else { | |
int m = block[i][j].getAroundMineNumber();//显示周围雷的数目 | |
System.out.printf("%s","□"+m); | |
} | |
} | |
System.out.println(); | |
} | |
} | |
static void intputShow(Block [][] block){ | |
int k =; | |
for(int i=;i<block.length;i++) { | |
for(int j =;j<block[i].length;j++){ | |
if(block[i][j].isMine()){ | |
System.out.printf("%s","#"); //输出#表示是地雷 | |
} | |
else { | |
int m = block[i][j].getAroundMineNumber();//显示周围雷的数目 | |
System.out.printf("%s",m); | |
} | |
} | |
System.out.println(); | |
} | |
} | |
} |
五、项目结构
六、设计总结
本次项目设计是通过 Java语言编制一个扫雷游戏,Java语言是当今较为流行的网络编程语言,它具有面向对象、跨平台、分布应用等特点。这次设计,还有利于加深对 Java课程的进一步了解,也可以巩固所学 Java语言基本知识,增进 Java语言编辑基本功,拓宽常用类库的应用。采用面向对象思想的程序,锻炼了面向对象的设计能力,使编程者通过该教学环节与手段,把所学课程及相关知识加以融会贯通,全面掌握 Java语言的编程思想及面向对象程序设计的方法。