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

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);
 	}
}
实现效果截图

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

发布了5 篇原创文章 · 获赞 0 · 访问量 115

猜你喜欢

转载自blog.csdn.net/AD_CSY/article/details/105657409