欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

java+Swing实现一个简单的“扫雷”游戏

程序员文章站 2022-04-03 08:51:34
...

java+Swing实现一个简单的“扫雷”游戏

比较适合Java初学者

我是一个Java初学者,前几天跟着网络课程简单的敲了一个“扫雷”,欢迎大家评论指出不足之处。
废话少说,直接上代码。个别没有注释到的地方,请大家百度。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.Timer;

public class MineSweeper1 extends JFrame implements ActionListener {
	public static void main(String[] args) {
  		new MineSweeper1();
 	}
	JFrame frame=new JFrame();//创建窗体
	//这里的图片大家可以根据自己的喜欢设置
	ImageIcon BannerIcon=new ImageIcon("C:\\Users\\csycsycsy\\eclipse-workspace\\扫雷1.0\\src\\image\\alien.png");
	ImageIcon guessIcon=new ImageIcon("C:/Users/csycsycsy/eclipse-workspace/扫雷1.0/src/image/Guess.png");
	ImageIcon boomIcon=new ImageIcon("C:/Users/csycsycsy/eclipse-workspace/扫雷1.0/src/image/boom.png");
	ImageIcon failIcon=new ImageIcon("C:/Users/csycsycsy/eclipse-workspace/扫雷1.0/src/image/fail.png");
	ImageIcon winIcon=new ImageIcon("C:/Users/csycsycsy/eclipse-workspace/扫雷1.0/src/image/win.png");
	ImageIcon winflagIcon=new ImageIcon("C:/Users/csycsycsy/eclipse-workspace/扫雷1.0/src/image/winflag.png");

	int row=8;//行
	int col=8;//列
	int data[][]=new int[row][col];//row是行,col是列
	JButton btns[][]=new JButton[row][col];
	int leicode=-1;//雷的代号
	int leinum=10;//雷的数量
	int time=0;//设置时间
	int opened=0;
	int unopened=row*col;
	
	JButton BannerBut=new JButton(BannerIcon);//创建按钮BannerIcon
	JLabel label1=new JLabel("待开:"+unopened);
	JLabel label2=new JLabel("已开:"+opened);
	JLabel label3=new JLabel("用时:"+time+"秒");
	Timer timer=new Timer(1000,this);

	public MineSweeper1() {
 		frame.setSize(850, 850);
  		frame.setTitle("扫雷1.0");
  		frame.setResizable(true);//设置窗口是否可以任意改变大小
  		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//点击窗口的“×”后不做任何操作,直接退出
  		frame.setLayout(new BorderLayout());//设置Banner为BorderLayout
  
  		SetHeader();//设置顶部
  		addlei();//埋雷的方法
  		SetButtons();
  		timer.start();//开启定时
  
  		frame.setLocationRelativeTo(null);//设置Jframe居中显示
  		frame.setVisible(true);//显示出窗口
 	}
 
 	/**
  	* 埋雷
  	*/
 	private void addlei() {
  		Random rand=new Random();
  		for(int i=0;i<leinum;) {
   			int r=rand.nextInt(row);
   			int c=rand.nextInt(col);
   			if(data[r][c]!=leicode) {
    				data[r][c]=leicode;
    				i++;
   			}
  		}
  		for (int i = 0; i < row; i++) {
   			for (int j = 0; j < col; j++) {
    				if(data[i][j] == leicode) continue;
    				int tempCount = 0;
    				//这里那么多的if是为了防止数组越界
    				if (i>0 && j>0 && data[i-1][j-1] == leicode) tempCount++;
    				if (i>0 && data[i-1][j] == leicode) tempCount++;
    				if (i>0 && j<(col-1) && data[i-1][j+1] == leicode) tempCount++;
    				if (j>0 && data[i][j-1] ==  leicode) tempCount++;
    				if (j<(row-1) && data[i][j+1] == leicode) tempCount++;
    				if (i<(row-1) && j>0 && data[i+1][j-1] == leicode) tempCount++;
    				if (i<(row-1) && data[i+1][j] == leicode) tempCount++;
    				if (i<(row-1) && j<(col-1) && data[i+1][j+1] == leicode) tempCount++;
    				data[i][j] = tempCount;
   			}  
  		}
 	}

	/**
  	* 设置雷区
  	*/
 	private void SetButtons() {
  		Container con=new 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(guessIcon);
    				btn.addActionListener(this);
    				btn.setOpaque(true);
    				btn.setBackground(Color.ORANGE);
    				//JButton btn=new JButton(data[i][j] + "");
    				btn.setFont(new Font("楷体",Font.BOLD,40));
    				btn.setMargin(new Insets(0,0,0,0));
    				con.add(btn);
    				btns[i][j]=btn;
   			}
  		}
  		frame.add(con, BorderLayout.CENTER);
 	}

	/**
  	* 设置顶部
  	*/
 	private void SetHeader() {
  		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(BannerBut, c1);
  		BannerBut.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));

		BannerBut.setOpaque(true);
  		BannerBut.setBackground(Color.white);
  		BannerBut.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);
 	}

 	/**监听鼠标
  	* @Override
  	*/
 	public void actionPerformed(ActionEvent e) {
  		if(e.getSource() instanceof Timer) {//计时器
   			time++;
   			label3.setText("用时:"+time);
   			timer.start();
   			return;
  		}
  
  		JButton btn=(JButton)e.getSource();//
  		if(btn.equals(BannerBut)) {
   			restart();
   			return;
  		}

		for(int i=0;i<row;i++) {
   			for(int j=0;j<col;j++) {
    				if(btn.equals(btns[i][j])) {
     					if(data[i][j]==leicode) {
      						lose();
     					}else {
      						opencell(i,j);
      						checkWin();
     					}
     					return;
    				}
   			}
  		}
 	}

	/**
  	* 重新开始
  	*/
 	private void restart() {
  		for(int i=0;i<row;i++) {
   			for(int j=0;j<col;j++) {
    				data[i][j]=0;
    				btns[i][j].setBackground(Color.ORANGE);
    				btns[i][j].setEnabled(true);
    				btns[i][j].setText("");
    				btns[i][j].setIcon(guessIcon);
   			}
  		}
  		unopened=row*col;
  		opened=0;
  		time=0;
  		label1.setText("待开:"+unopened);
  		label2.setText("已开:"+opened);
  		label3.setText("用时:"+time);
  		addlei();
  		timer.start();
 	}

	/**
  	* 赢了游戏的处理
  	*/
 	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++;
   			}
  		}
  		if(count == leinum) {
   			timer.stop();
   			for (int i = 0; i < row; i++) {
    				for (int j = 0; j < col; j++) {
     					if(btns[i][j].isEnabled()) {
      						btns[i][j].setIcon(winflagIcon);
     					}
    				}
   			}
		BannerBut.setIcon(winIcon);
   			JOptionPane.showMessageDialog(frame, "你赢了, Yeah!\n点击Banner重新开始", "赢了", JOptionPane.PLAIN_MESSAGE );
  		}  
 	}

	/**
  	* 游戏失败的判定
  	*/
 	private void lose() {
  		timer.stop();
  		BannerBut.setIcon(failIcon);
  		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) {
      						btn.setEnabled(false);
      						btn.setIcon(boomIcon);
      						btn.setDisabledIcon(boomIcon);
     					}else if(data[i][j]==0) {
      						btn.setText("");
      						btn.setIcon(null);
      						btn.setEnabled(false);
					}else {
      						btn.setIcon(null);
      						btn.setEnabled(false);//已经被打开
      						btn.setOpaque(true);
      						btn.setText(data[i][j]+"");
     					}
    				}
   			}
  		}
  		JOptionPane.showMessageDialog(frame, "你输了!");
 	}

	/**
  	* 打开格子
  	* @param i
  	* @param j
  	*/
 	private void opencell(int i,int j) {
  		JButton btn=btns[i][j];
  		if(!btn.isEnabled())return;
  
  			btn.setIcon(null);
  			btn.setEnabled(false);//已经被打开
  			btn.setOpaque(true);
  			btn.setBackground(Color.WHITE);
  			btn.setText(data[i][j]+"");
  			update_dates();

			//同上,防止数组越界
			if(data[i][j]==0) {
   			if (i>0 && j>0 && data[i-1][j-1] == 0) opencell(i-1,j-1);
   			if (i>0 && data[i-1][j] == 0) opencell(i-1,j);
   			if (i>0 && j<(col-1) && data[i-1][j+1] == 0) opencell(i-1,j+1);
   			if (j>0 && data[i][j-1] ==  0) opencell(i,j-1);
   			if (j<(row-1) && data[i][j+1] == 0) opencell(i,j+1);
   			if (i<(row-1) && j>0 && data[i+1][j-1] == 0) opencell(i+1,j-1);
   			if (i<(row-1) && data[i+1][j] == 0) opencell(i+1,j);
   			if (i<(row-1) && j<(col-1) #&& data[i+1][j+1] == 0) opencell(i+1,j+1);
   			btn.setText("");
  		}
 	}

	/**
  	* 更新数据
  	*/
 	private void update_dates() {
  		opened++;
  		unopened--;
  		label1.setText("待开:"+unopened);
  		label2.setText("已开:"+opened);
 	}
}
实现效果截图

java+Swing实现一个简单的“扫雷”游戏
我打包了一个可执行的jar包,里面有源代码,需要的小伙伴请点击下方链接。
链接:https://x-x.fun/i/RU7425cfc83rY
更多Java学习资料,请点击以下链接
链接:https://pan.baidu.com/s/1xYtkXyDqWJVM34vkjtIKHw
提取码:l1mv

相关标签: Java初学者