Java编程实现三种等级的扫雷游戏(完整版) 您所在的位置:网站首页 扫雷高级玩法 Java编程实现三种等级的扫雷游戏(完整版)

Java编程实现三种等级的扫雷游戏(完整版)

#Java编程实现三种等级的扫雷游戏(完整版)| 来源: 网络整理| 查看: 265

大家好,我是陈橘又青,今天用Java编程实现图形化界面的扫雷游戏(三种难度),以下是完整的开发思路以及代码,供各位讨论交流。

文章目录 一、效果展示初级难度中级难度高级难度测试界面 二、项目介绍项目背景功能分析 三、代码展示图形界面设计(gui包)用户操作设计(data包)游戏视图设计(view包) 四、代码测试五、项目结构六、设计总结

一、效果展示 初级难度

中级难度

高级难度

测试界面

二、项目介绍 项目背景

扫雷是一款大众类的益智小游戏。根据点击格子出现的数字找出所有非雷格子,同时避免踩雷,踩到一个雷即全盘皆输。这款游戏有着很长的历史,从扫雷被开发出来到现在进行了无数次的优化,这款游戏通过简单的玩法,加上一个好看的游戏界面,每一处的细节都体现了扫雷的魅力。

功能分析

完成 难度选择,雷随机生成,数字生成,左右键翻开 等功能实现 游戏四种状态: 难度选择、游戏状态、游戏胜利、游戏失败 游戏难度: 初级、中级、高级(不同难度对应不同的雷区大小和雷数量) 游戏核心: 二维数组 的相关操作 其他: 窗口绘制、界面规划、操作计数、重新开始。

三、代码展示 图形界面设计(gui包)

主类:AppWindows类

AppWindow类负责创建游戏的主窗口,该类含有main方法,程序从该类开始执行。

package ch8.gui; import java.awt.*; import javax.swing.*; import javax.swing.event.*; import java.awt.event.*; import ch8.view.MineArea; import ch8.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,9,10,gradeOne.getText());//创建初级扫雷区 add(mineArea,BorderLayout.CENTER); showHeroRecord=new ShowRecord(); setBounds(300,100,500,450); setVisible(true); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); validate(); } public void menuSelected(MenuEvent e){ if(e.getSource()==gradeOne){ mineArea.initMineArea(9,9,10,gradeOne.getText()); validate(); } else if(e.getSource()==gradeTwo){ mineArea.initMineArea(16,16,40,gradeTwo.getText()); validate(); } else if(e.getSource()==gradeThree){ mineArea.initMineArea(22,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 ch8.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 ch8.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=0;i //在雷区布置mineCount个雷 initBlock(block); //先都设置是无雷 int row=block.length; int column=block[0].length; LinkedList list=new LinkedList(); for(int i=0;i //开始布雷 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 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 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 ch8.data; import java.util.Stack; public class PeopleScoutMine { public Block [][] block; //雷区的全部方块 Stack notMineBlock; //存放一个方块周围区域内不是雷的方块 int m,n ; //方块的索引下标 int row,colum; //雷区的行和列 int mineCount; //雷的数目 public PeopleScoutMine(){ notMineBlock = new Stack(); } public void setBlock(Block [][] block,int mineCount){ this.block = block; this.mineCount = mineCount; row = block.length; colum = block[0].length; } public Stack getNoMineAroundBlock(Block bk){//得到方块bk附近区域不是雷的方块 notMineBlock.clear(); for(int i=0;i 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()>0&&block[m][n].getIsOpen()==false){ block[m][n].setIsOpen(true); notMineBlock.push(block[m][n]); //将不是雷的方块压栈 return; } else if(block[m][n].getAroundMineNumber()==0&&block[m][n].getIsOpen()==false){ block[m][n].setIsOpen(true); notMineBlock.push(block[m][n]); //将不是雷的方块压栈 for(int k=Math.max(m-1,0);k boolean isOK = false; int number=0; for(int i=0;i if(block[i][j].getIsOpen()==false) number++; } } if(number==mineCount){ isOK =true; } return isOK; } }

RecordOrShowRecord类

package ch8.data; import java.sql.*; public class RecordOrShowRecord{ Connection con; String tableName ; int heroNumber = 3; //英雄榜显示的最多英雄数目 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(50) ,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(1,name); sta.setInt(2,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][2]; rs.beforeFirst(); int i=0; while(rs.next()) { record[i][0] = rs.getString(1); record[i][1] = 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 = 0; 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 ch8.data; public interface ViewForBlock { public void acceptBlock(Block block);//确定是哪个方块的视图 public void setDataOnView(); //设置视图上需要显示的数据 public void seeBlockNameOrIcon();//显示图标方块上的名字或 public void seeBlockCover(); //显示视图上负责遮挡的组件 public Object getBlockCover(); //得到视图上的遮挡组件 } 游戏视图设计(view包)

BlockView类

package ch8.view; import javax.swing.*; import java.awt.*; import ch8.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>=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; } }

MineArea类

package ch8.view; import java.awt.*; import java.awt.event.*; import javax.swing.*; import ch8.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=0; //扫雷的用时 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(1000,this); //计时器,每个一秒触发ActionEvent事件一次 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(); //创建布雷者 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=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 for(int j=0;j 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=-1,n=-1; for(int i=0;i if(e.getSource()==blockView[i][j].getBlockCover()){ m=i; n=j; break; } } } if(block[m][n].isMine()) { //用户输掉游戏 for(int i=0;i blockView[i][j].getBlockCover().setEnabled(false);//用户单击无效了 if(block[i][j].isMine()) blockView[i][j].seeBlockNameOrIcon(); //视图显示方块上的数据信息 } } time.stop(); spendTime=0; //恢复初始值 markMount=mineCount; //恢复初始值 playMusic.playMusic(); //播放类爆炸的声音 } else { //扫雷者得到block[m][n]周围区域不是雷的方块 Stack 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=0;i 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 mouseReleased(MouseEvent e){} public void mouseEntered(MouseEvent e){} public void mouseExited(MouseEvent e){} public void mouseClicked(MouseEvent e){} }

PlayMusic类

package ch8.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 ch8.view; import javax.swing.*; import java.awt.event.*; import ch8.data.RecordOrShowRecord; 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 confirm,cancel; public Record(){ setTitle("记录你的成绩"); this.time=time; this.grade=grade; setBounds(100,100,240,160); setResizable(false); setModal(true); confirm=new JButton("确定"); cancel=new JButton("取消"); textName=new JTextField(8); textName.setText("匿名"); confirm.addActionListener(this); cancel.addActionListener(this); setLayout(new java.awt.GridLayout(2,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 ch8.view; import java.awt.*; import javax.swing.*; import ch8.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,15)); add(new JScrollPane(showMess)); setTitle("显示英雄榜"); setBounds(400,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 =0 ;i public static void main(String [] args) { Block block[][] = new Block[5][10]; //雷区 for(int i=0;i block[i][j] = new Block(); } } LayMines layMines = new LayMines(); //布雷者 PeopleScoutMine peopleScoutMine = new PeopleScoutMine(); //扫雷者 layMines.layMinesForBlock(block,10); //在雷区布雷 System.out.println("雷区情况:"); intputShow(block); peopleScoutMine.setBlock(block,10); //准备扫雷 Stack stack = peopleScoutMine.getNoMineAroundBlock(block[0][0]);//扫雷 if(block[0][0].isMine()){ System.out.println("我的天啊,踩着地雷了啊"); return; } System.out.println("扫雷情况:"); intputProcess(block,stack); System.out.println("成功了吗:"+peopleScoutMine.verifyWin()); if(block[3][3].isMine()){ System.out.println("我的天啊,踩着地雷了啊"); return; } stack = peopleScoutMine.getNoMineAroundBlock(block[3][3]);//扫雷 System.out.println("扫雷情况:"); intputProcess(block,stack); System.out.println("成功了吗:"+peopleScoutMine.verifyWin()); } static void intputProcess(Block [][] block,Stack stack){ int k = 0; for(int i=0;i if(!stack.contains(block[i][j])&&block[i][j].getIsOpen()==false){ System.out.printf("%2s","■ "); //输出■表示未挖开方块 } else { int m = block[i][j].getAroundMineNumber();//显示周围雷的数目 System.out.printf("%2s","□"+m); } } System.out.println(); } } static void intputShow(Block [][] block){ int k = 0; for(int i=0;i if(block[i][j].isMine()){ System.out.printf("%2s","#"); //输出#表示是地雷 } else { int m = block[i][j].getAroundMineNumber();//显示周围雷的数目 System.out.printf("%2s",m); } } System.out.println(); } } } 五、项目结构

六、设计总结

本次项目设计是通过 Java语言编制一个扫雷游戏,Java语言是当今较为流行的网络编程语言,它具有面向对象、跨平台、分布应用等特点。这次设计,还有利于加深对 Java课程的进一步了解,也可以巩固所学 Java语言基本知识,增进 Java语言编辑基本功,拓宽常用类库的应用。采用面向对象思想的程序,锻炼了面向对象的设计能力,使编程者通过该教学环节与手段,把所学课程及相关知识加以融会贯通,全面掌握 Java语言的编程思想及面向对象程序设计的方法。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有