用java做出简单一个扫雷游戏

1.创造窗口

   //创建扫雷窗口界面  
	public Saolei() {
		
			frame.setSize(600,700);
			frame.setResizable(false);//设置窗口尺寸不能变化
			frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
			frame.setLayout(new BorderLayout());//分块
			setHeader();//设置界面初始化
			addlei();   //添加雷
			setButtons();//添加按钮
			timer.start();   //启动时钟;
			frame.setVisible(true);
		}

2.定义数据结构以及初始化

//数据结构start
	int ROW = 20;
	int COL = 20;
	int [][] data = new int[ROW][COL];
	JButton[][] btns = new JButton[ROW][COL];
	int LEICOUNT = 30;   //雷个数
	int LEICODE = -1;
	int unopened = ROW*COL;
	int opened = 0;
	int timeSecond =0;
	//三个 jlabel 状态栏 已开未开,用时
	JLabel label1= new JLabel("待开:"+unopened);
	JLabel label2= new JLabel("已开:"+opened);
	JLabel label3= new JLabel("用时:"+timeSecond+"s");
	Timer timer = new Timer(1000, this); //定义时间为一秒  

3.窗体按钮

private void setButtons() {
	  Container con = new Container();//container容器
	  con.setLayout(new GridLayout(ROW,COL));//创建方格
	  
	  for(int i=0;i<ROW;i++) {
		  for(int j=0;j<COL;j++) {
			  JButton btn = new JButton();
			  btn.setOpaque(true);
			  btn.setBackground(new Color(200,183,113));  //设置扫雷背景颜色
			  btn.addActionListener(this);  //Btn添加按钮监听事件
			  btn.setMargin(new Insets(0,0,0,0));  //button数字显示不出来,加上该语句即可显示
			  con.add(btn);
			  btns[i][j] = btn;
		  }
	  }
	  frame.add(con,BorderLayout.CENTER);//中间位置
	  
	}

4.埋雷

private void addlei() {
		Random rand = new Random();
		for(int i=0;i<LEICOUNT;) {
			int r = rand.nextInt(ROW);
			int c= rand.nextInt(COL);
			if(data[r][c]!=LEICODE) {
				data[r][c] = LEICODE;
				i++;
//				System.out.println(r+"  "+c+" "+data[r][c]);
			}
		}
		

5.计算周围雷的数量

//计算周边雷的数量
		  for(int i=0;i<ROW;i++) {
			  for(int j=0;j<COL;j++) {
				  if(data[i][j]!=LEICODE) {
					   int  c=0;
					   if(i>0&&j>0&&data[i-1][j-1]==LEICODE) c++;
					   if(i>0&&data[i-1][j]==LEICODE) c++;
					   if(i>0&&j<19&&data[i-1][j+1]==LEICODE) c++;
					   if(j>0&&data[i][j-1]==LEICODE) c++;
					   if(j<19&&data[i][j+1]==LEICODE) c++;
					   if(i<19&&j>0&&data[i+1][j-1]==LEICODE) c++;
					   if(i<19&&data[i+1][j]==LEICODE) c++;
					   if(i<19&&j<19&&data[i+1][j+1]==LEICODE) c++;
					   data[i][j]=c;
				  }	 
			  }
		  }

6.Banner设置

//设置开头显示
	private void setHeader() {
		//设置画布 Jpanel
		JPanel panel = new JPanel(new GridBagLayout());
		GridBagConstraints c1 = new GridBagConstraints(0,0,3,1,1.0,1.0,GridBagConstraints.CENTER,GridBagConstraints.BOTH,new Insets(0,0,0,0),0,0);
		panel.add(bannerBtn,c1);
		
		bannerBtn.addActionListener(this);
		label1.setOpaque(true);    //设置不透明,背景色,
		label1.setBackground(Color.white);   
		label1.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY));
		
		label2.setOpaque(true);
		label2.setBackground(Color.white);
		label2.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY));
		
		label3.setOpaque(true);
		label3.setBackground(Color.white);
		label3.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY));
		
		bannerBtn.setOpaque(true);
		bannerBtn.setBackground(Color.white);
		bannerBtn.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY));
		
		GridBagConstraints c2 = new GridBagConstraints(0,1,1,1,1.0,1.0,GridBagConstraints.CENTER,GridBagConstraints.BOTH,new Insets(0,0,0,0),0,0);
		panel.add(label1,c2);
		GridBagConstraints c3 = new GridBagConstraints(1,1,1,1,1.0,1.0,GridBagConstraints.CENTER,GridBagConstraints.BOTH,new Insets(0,0,0,0),0,0);
		panel.add(label2,c3);
		GridBagConstraints c4 = new GridBagConstraints(2,1,1,1,1.0,1.0,GridBagConstraints.CENTER,GridBagConstraints.BOTH,new Insets(0,0,0,0),0,0);
		panel.add(label3,c4);
		
		frame.add(panel,BorderLayout.NORTH);
		
	}

7.游戏胜利还是失败

	//判断胜利!!!
	
	private void checkWin() {
		
		 int count=0;
			for(int i=0;i<ROW;i++) {
				for(int j=0;j<COL;j++) {
					if(btns[i][j].isEnabled()) {
						count++;
						
					}
				}
			}
			unopened = count;
			opened =  ROW*COL-count;
			
			label1.setText("待开:"+ unopened);
			label2.setText("已开:"+ opened);
			if(count==LEICOUNT) {
				timer.stop(); 
				bannerBtn.setText("游戏胜利!!!");
				for(int i=0;i<ROW;i++) {
					for(int j=0;j<COL;j++) {
						if(btns[i][j].isEnabled()) {
							  btns[i][j].setBackground(new Color(100,183,0));
                   
						}
					}
				}
				bannerBtn.setText("Banner:restart!");
				JOptionPane.showMessageDialog(frame, "恭喜你!游戏胜利啦!\n 可以点击上面的Banner重新开始!","游戏结束!",JOptionPane.PLAIN_MESSAGE);
			}
			
		
	}

	//踩雷成功,游戏结束!
	private void lose() {
		timer.stop();
		 bannerBtn.setText("很遗憾,踩雷成功,游戏结束!!!");
		for(int i=0;i<ROW;i++) {
			for(int j=0;j<COL;j++) {
				if(btns[i][j].isEnabled()) {
					JButton btn = btns[i][j];
					if(data[i][j]==LEICODE) {
//					btns[i][j].setEnabled(false);	btns[i][j].setIcon(bombIcon); btns[i][j].setDisabledIcon(bombIcon);
				   
						btn.setBackground(Color.red);	 //置为红色
						btn.setText(data[i][j]+"");
					}
					else {
						btn.setIcon(null);
						btn.setEnabled(false);   //btn已经打开不可点击
						btn.setOpaque(true);
		
					}
				}
			}
		}
		bannerBtn.setText("Banner:restart!");
		JOptionPane.showMessageDialog(frame, "很遗憾,暴雷成功,游戏结束!!!\n 可以点击上面的Banner重新开始!","游戏结束!",JOptionPane.PLAIN_MESSAGE);
		
	}

8.空白级联打开(实现点击一个即可打开多个)

	private void openCell(int i,int j,int Blankcount ){
		JButton btn=btns[i][j];
		if(!btn.isEnabled()) return ;
		if(Blankcount==10)   //部分打开,设置数字限制
			return;
		btn.setIcon(null);
		btn.setEnabled(false);
		btn.setOpaque(true);
		Blankcount++;
		btn.setBackground(Color.GREEN);
		btn.setText(data[i][j]+"");
		if(data[i][j]==0) {
			 if(i>0&&j>0&&data[i-1][j-1]==0) openCell(i-1,j-1,Blankcount);
			   if(i>0&&data[i-1][j]==0) openCell(i-1,j,Blankcount);
			   if(i>0&&j<19&&data[i-1][j+1]==0) openCell(i-1,j+1,Blankcount);
			   if(j>0&&data[i][j-1]==0) openCell(i,j-1,Blankcount);
			   if(j<19&&data[i][j+1]==0) openCell(i,j+1,Blankcount);
			   if(i<19&&j>0&&data[i+1][j-1]==0) openCell(i+1,j-1,Blankcount);
			   if(i<19&&data[i+1][j]==0) openCell(i+1,j,Blankcount);
			   if(i<19&&j<19&&data[i+1][j+1]==0) openCell(i+1,j+1,Blankcount);
		}
		
	}

9.最终游戏界面

在这里插入图片描述
在这里插入图片描述

总结

游戏界面颜色设置的有点丑,代码是跟着某站上老师做的,感谢老师!

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值