我又来水博客了……把之前的库存发一发~

扫雷java程序 扫雷的java代码_扫雷java程序

开发工具:IDEA

不到三百行代码即可开发一个简单的扫雷小游戏,只需掌握Java基础语法知识以及部分swing知识点即可~

运行效果如图:

扫雷java程序 扫雷的java代码_java_02


扫雷java程序 扫雷的java代码_游戏_03


项目中图片可自行从网络上寻找替换

想要原始项目压缩文件可私聊博主~

代码如下:

package Mine;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

public class Mine implements ActionListener{

    JFrame frame = new JFrame();//JFrame设置初始界面

    ImageIcon bannerIcon =new ImageIcon(getClass().getResource("banner.JPG"));//设置头部图片
    ImageIcon guessIcon =new ImageIcon(getClass().getResource("guess.png"));
    ImageIcon bombIcon =new ImageIcon(getClass().getResource("bomb.png"));
    ImageIcon failIcon =new ImageIcon(getClass().getResource("fail.JPG"));
    ImageIcon winIcon =new ImageIcon(getClass().getResource("win.JPG"));
    ImageIcon win_flagIcon =new ImageIcon(getClass().getResource("win_flag.png"));

    //扫雷基本数据结构
    private final int row = 20;//行
    private final int col = 20;//列
    private final int[][] data = new int[row][col];//数据
    JButton[][] btns = new JButton[row][col];//按钮的行列
    private final int mineCount = 20;//雷的总数
    private final int mineCode = -1;//雷的代码
    private int unOpen = row * col;//未开
    private int open = 0;//已开
    private int second = 0;//设置初始时间

    JButton bannerBtn = new JButton((bannerIcon));//JButton设置头部菜单栏并导入图片

    JLabel label1 = new JLabel("待开启:"+ unOpen);//添加计时和已开待开
    JLabel label2 = new JLabel("已开启:"+ open);
    JLabel label3 = new JLabel("用时:"+ second + "s");//设置表头

    Timer timer=new Timer(1000,this);//1000ms触发一次

    //构造一个扫雷方法
    public Mine(){
        frame.setSize(700,800);//设置高和宽
        frame.setResizable(false);//不能改变大小
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//退出
        frame.setLayout(new BorderLayout());//设置界面布局

        setHead();//设置头部

        addMine();//添加雷

        setButtons();//设置主界面

        timer.start();//计时器第一次启动

        frame.setVisible(true);//显示
    }

    //添加雷
    private void addMine(){
        Random rand = new Random();//随机布雷
        for (int i = 0; i < mineCount;) {//不能i++,可能会重复,导致雷的数量变少
            int r = rand.nextInt(row);
            int c = rand.nextInt(col);
            if (data[r][c] != mineCode){
                data[r][c] = mineCode;
                i++;//直到放满雷
            }
        }

        //开始计算周边雷的数量
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                if (data[i][j]==mineCode)
                    continue;
                int count =0;//无需判断i,j,不会越界,但要判断其他八种情况是否越界
                if (i>0 && j>0 && data[i-1][j-1] == mineCode)
                    count++;
                if (i>0 && data[i-1][j] == mineCode)
                    count++;
                if (i>0 && j<19 && data[i-1][j+1] == mineCode)
                    count++;
                if (j>0 && data[i][j-1] ==  mineCode)
                    count++;
                if (j<19 && data[i][j+1] == mineCode)
                    count++;
                if (i<19 && j>0 && data[i+1][j-1] == mineCode)
                    count++;
                if (i<19 && data[i+1][j] == mineCode)
                    count++;
                if (i<19 && j<19 && data[i+1][j+1] == mineCode)
                    count++;
                data[i][j] = count;
            }
        }
    }

    //设置一个20*20的主界面的按钮
    private void setButtons(){
        Container con=new Container();//和panel类似,更加轻量化
        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.setOpaque(true);//设置为不透明,否则按钮颜色无法显示
                btn.setBackground(Color.orange);//设置按钮背景色
                btn.addActionListener(this);
                con.add(btn);
                btns[i][j]=btn;
            }
        }
        frame.add(con,BorderLayout.CENTER);
    }

    //设置顶部
    private void setHead(){
        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.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY));
        bannerBtn.setBackground(Color.white);

        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){//判断类型是否为Timer
            second++;
            label3.setText("用时:"+second+"s");
            timer.start();//执行完一次启动一次时钟
            return;
        }

        JButton btn=(JButton)e.getSource();//强制类型转换
        if (btn.equals(bannerBtn)){
            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]==mineCode){
                        lose();
                    }else {
                        openBlank(i, j);
                        checkWin();
                    }
                    return;
                }
            }
        }
    }

    //游戏赢啦!!!
    private void checkWin(){
        int wincount=0;
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                if (btns[i][j].isEnabled()){
                    wincount++;
                }
            }
        }
        if (wincount==mineCount){//如果和类的数量相等就赢了
            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(win_flagIcon);//把雷的图片换成小旗子
                    }
                }
            }
            bannerBtn.setIcon(winIcon);
            JOptionPane.showMessageDialog(frame,"你赢啦!!!\n请点击顶部图片重新开始","你赢了!",JOptionPane.PLAIN_MESSAGE);
        }
    }

    //游戏输了…………
    private void lose(){
        timer.stop();
        bannerBtn.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]==mineCode){
                        btns[i][j].setEnabled(false);
                        btns[i][j].setIcon(bombIcon);
                        btns[i][j].setDisabledIcon(bombIcon);
                    }else {
                        btn.setIcon(null);//先清空
                        btn.setEnabled(false);//点开之后不必再响应
                        btn.setOpaque(true);//设置为不透明
                        btn.setText(data[i][j]+"");
                        btn.setMargin(new Insets(0,0,0,0));//执行之前的操作后显示数字为...,经查询需要加上这条语句才能显示数字
                    }//踩雷后全部打开
                }
            }
        }
        JOptionPane.showMessageDialog(frame,"你GG了!!!\n请点击顶部图片重新开始","你死啦!!!",JOptionPane.PLAIN_MESSAGE);
    }

    //空格自动打开
    private void openBlank(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.CYAN);//按钮色
        btn.setText(data[i][j]+"");
        btn.setMargin(new Insets(0,0,0,0));//执行之前的操作后显示数字为...,经查询需要加上这条语句

        addOpenCount();//让上方表格动起来

        if(data[i][j] == 0) {//如果周围有空格继续打开
            if (i>0 && j>0 && data[i-1][j-1] >= 0)
                openBlank(i-1, j-1);
            if (i>0 && data[i-1][j] >= 0)
                openBlank(i-1, j);
            if (i>0 && j<19 && data[i-1][j+1] >= 0)
                openBlank(i-1, j+1);
            if (j>0 && data[i][j-1] >= 0)
                openBlank(i, j-1);
            if (j<19 && data[i][j+1] >= 0)
                openBlank(i, j+1);
            if (i<19 && j>0 && data[i+1][j-1] >= 0)
                openBlank(i+1, j-1);
            if (i<19 && data[i+1][j] >= 0)
                openBlank(i+1, j);
            if (i<19 && j<19 && data[i+1][j+1] >= 0)
                openBlank(i+1, j+1);
        }
    }

    //让上方的表格栏随着按钮的展开动起来
    private void addOpenCount(){
        open++;
        unOpen--;
        label1.setText("待开启:"+unOpen);
        label2.setText("已开启:"+open);
    }

    //重新启动要数据清零,按钮恢复,时间重启
    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);
            }
        }
        //顶部状态栏的恢复
        unOpen=row*col;
        open=0;
        second=0;
        label1.setText("待开启:"+unOpen);
        label2.setText("已开启:"+open);
        label3.setText("用时:"+second+"s");
        bannerBtn.setIcon(bannerIcon);//标题图片恢复

        addMine();
        timer.start();
    }
    //main方法
    public static void main(String[] args) {
        new Mine();
    }
}```