快捷搜索:

JAVA语言课程设计——扫雷小游戏

1.设计内容 设计一个界面为10*10的扫雷程序,雷的个数不少于10个。功能如Windows系统给定的扫雷游戏。 效果如图:扫雷界面 2.设计要求 界面美观,鼠标的左右键好用。左键:直接显示有几个雷,如果该区域本身就是雷,游戏结束。右键:设置该区域为雷,如果设为雷区,再点右键则该区域返回没点开状态。双击:如果一个区域四周设置的雷数=该区域显示的个数,双击则可以直接显示该区域四周的数字。 3.设计思想 定义一个类B,继承于JButton,该类有4个变量整型变量num、x、y和boolean类型isclicked。//isclickd代表是否点开;num代表周围地雷个数,如果num=100;代表是雷;x,y这个雷区在数组中的位置。 定义主程序类A,实现界面和鼠标点击的响应 搭建界面,其中JPanel设置为10行10列的布局,定义10*10的二维B类数组 用随机函数生成10个地雷位置,每次新生成的雷的位置要与以前的比较是否重复 初始化100个Block,为每一个Block注册监听器,该Block块记下自己的坐标位置,添加到面板中 在Block数组中将是雷的位置num=100,将四周8个位置不是雷区域的num+1; 实现鼠标事件mouseClicked(MouseEvent e) 得到被点击的block块 (1) 如果双击鼠标, 判定该区域四周已出现雷的个数是否等于该区域的num,如果不相等,没有反应;如果相等,将该区域四周的八个区域点击开(调用递归函数click); (2) 如果是单击鼠标左键,如果该区域不是雷,调用递归函数,显示区域数字;如果是雷,直接提示游戏结束 (3)如果单机鼠标右键,如果该区域没点开过,显示雷图片,标识isclicked已经点过,排出雷的个数count+1,如果该数量等于雷总数,提示游戏过关;如果该区域点过,上面有雷的图片,才能修改回没点开状态,count--; 8.Click()递归函数,成片的打开空白区域 如果这个区域已经打开,返回; 如果没点开,标识已经点开,设置背景颜色。如果这个block块只是数字,显示数字;如果是空白区,递归调用,将周边的8个位置调用click函数,调用之前要判定是否越界; 代码如下: package test;import java.awt.Color;import java.awt.GridLayout;import java.awt.event.MouseEvent;import java.awt.event.MouseListener;import java.awt.event.WindowAdapter;import java.awt.event.WindowEvent;import java.util.Random;import javax.swing.ImageIcon;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JOptionPane;import javax.swing.JPanel;class Block extends JButton { //雷块block定义public boolean isclicked=false;//isclickd代表是否点开public int num=0; //周围地雷个数,如果num=100;代表是雷public int x=0,y=0; //这个雷区在数组中的位置。}public class Bomb extends JFrame implements MouseListener{Block b[][]=new Block[10][10]; private int count=0;//游戏中,找出的雷数;private int rand[]=new int[20];private int leishu=10; //布雷的个数private JPanel p=new JPanel();private ImageIcon blei=new ImageIcon("images/lei.png");//地雷图片private ImageIcon lei=new ImageIcon("images/ilei.png");//踩雷图片public Bomb(){setTitle("扫雷");setSize(500,500);setLocation(500,20);p.setLayout(new GridLayout(10,10)); //网格布局random(); //随机确定地雷位置initBlack(); //初始化100个Blockzhilei(); //放置雷进Block数组,确定每个位置周围的雷数add(p);addWindowListener(new WindowAdapter(){public void windowClosing(WindowEvent e){System.exit(0);}});//关闭窗口setVisible(true); //窗口可见}//初始化随机雷数组private void random(){int k=0,i,x;//已经生成的雷的个数boolean b=true;//新生成的是否与以前的重复Random r=new Random();while(k<leishu) {//只要雷的个数不够x=r.nextInt(99);//随机位置0~100for(i=0;i<k;i++) {//到已经生成的雷比较是否有重复的if(x==rand[i]) {b=false;break;}//如果有,跳出循环}if(b) rand[k++]=x;//如果没有,使用并放到数组中}}//初始化Blockprivate void initBlack(){int i,j;for(i=0;i<10;i++) {for(j=0;j<10;j++) {b[i][j]=new Block();//初始化100的Block按钮b[i][j].addMouseListener(this);//为每一个Block注册监听器b[i][j].x=i;b[i][j].y=j;//记下自己坐标的位置p.add(b[i][j]);//添加到面板中}}}//放置雷进Black数组private void zhilei(){int x,y;//放置雷进Black数组的代码for(int i=0;i<leishu;i++) {x=rand[i]/10;y=rand[i];//取出数组中一个雷的位置计算行和列的值b[x][y].num=100;//表示这个black是雷if((x-1>=0)&&(b[x-1][y].num!=100)) b[x-1][y].num++;if((x+1<10)&&(b[x+1][y].num!=100)) b[x+1][y].num++;if((y-1>=0)&&(b[x][y-1].num!=100)) b[x][y-1].num++;if((y+1<10)&&(b[x][y+1].num!=100)) b[x][y+1].num++;//四周八个位置不是雷区域的num+1if((x-1>=0)&&(y-1>=0)&&(b[x-1][y-1].num!=100)) b[x-1][y-1].num++;if((x-1>=0)&&(y+1<10)&&(b[x-1][y+1].num!=100)) b[x-1][y+1].num++;if((x+1<10)&&(y-1>=0)&&(b[x+1][y-1].num!=100)) b[x+1][y-1].num++;if((x+1<10)&&(y+1<10)&&(b[x+1][y+1].num!=100)) b[x+1][y+1].num++;}}//主函数public static void main(String args[]){Bomb bomb=new Bomb(); //创建对象,显示界面}public void click(int x,int y){//递归函数,成片的打开空白区域if(b[x][y].isclicked)return;//如果这个区域点开了else {//如果没点开b[x][y].isclicked=true;//标识符已经点开b[x][y].setBackground(Color.lightGray);if(b[x][y].num!=0) {b[x][y].setText(b[x][y].num+"");}//如果这个block块只是数字,显示数字else {//如果是空白区域,递归调用将8个位置调用click函数if(x>0&&y>0) {click(x-1,y-1);}if(x>0) {click(x-1,y);}if(x>0&&y<9) {click(x-1,y+1);}if(y>0) {click(x,y-1);}if(y<9) {click(x,y+1);}if(x<9&&y>0) {click(x+1,y-1);}if(x<9) {click(x+1,y);}if(x<9&&y<9) {click(x+1,y+1);}}}}//实现鼠标事件@Overridepublic void mouseClicked(MouseEvent e) { // TODO Auto-generated method stubBlock a=(Block)(e.getSource());//得到被点击的block块if(e.getClickCount()==2){ //如果双击;int n=0;int x=a.x,y=a.y;if(x>0&&y>0) {if((b[x-1][y-1].isclicked)&&(b[x-1][y-1].num==100))n++;}if(x>0) {if((b[x-1][y].isclicked)&&(b[x-1][y].num==100))n++;}if(x>0&&y<9) {if((b[x-1][y+1].isclicked)&&(b[x-1][y+1].num==100))n++;}if(y>0) {if((b[x][y-1].isclicked)&&(b[x][y-1].num==100))n++;}if(y<9) {if((b[x][y+1].isclicked)&&(b[x][y+1].num==100))n++;}if(x<9&&y>0) {if((b[x+1][y-1].isclicked)&&(b[x+1][y-1].num==100))n++;}if(x<9) {if((b[x+1][y].isclicked)&&(b[x+1][y].num==100))n++;}if(x<9&&y<9) {if((b[x+1][y+1].isclicked)&&(b[x+1][y+1].num==100))n++;}if(n==a.num) {//如果当前四周用右键点击的雷的个数等于该区域的numa.num=0;a.isclicked=false;//设置该区域为空白区,并且没点开过,否则调用不了click函数。click(x,y);//将四周八个区域点开a.num=n;//重新给num赋值}} else{ //如果是单击;if(e.getButton()==e.BUTTON1) {//左键if(a.num!=100) {click(a.x,a.y);}//如果不是雷,调用递归函数,显示周围数字else {//如果是雷,直接提示游戏结束a.setIcon(blei);//踩雷图片JOptionPane.showMessageDialog(null, "游戏结束");}}if(e.getButton()==e.BUTTON3) {//右键if(!a.isclicked) {//如果没点开a.setIcon(lei);//地雷图片a.isclicked=true;//标识符已经点过count++;//排除雷的个数+1if(count==leishu) {JOptionPane.showMessageDialog(null, "恭喜您过关了!");}}else {//如果点开了if(lei==a.getIcon()) {//如果有雷的图片,才能修改a.setIcon(null);//改为空a.isclicked=false;//标识符没有点过count--;}}}}}@Overridepublic void mouseEntered(MouseEvent e) {}@Overridepublic void mouseExited(MouseEvent e) {}@Overridepublic void mousePressed(MouseEvent e) {}@Overridepublic void mouseReleased(MouseEvent e) {}}
经验分享 程序员 微信小程序 职场和发展