⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 minepanel.java

📁 java版的扫雷,功能比较齐全
💻 JAVA
字号:
package clearminegame;

import java.awt.*;
import java.awt.event.*;
import java.text.*;
import java.util.*;

import javax.swing.*;
import javax.swing.Timer;

public class MinePanel extends JPanel {

    private Random rnd = new Random();
    private DecimalFormat fmt = new DecimalFormat("000");

    private int rowCount;
    private int columnCount;
    private int mineCount;
    private int warnCount;
    private int secondCount = 0;
    private int rightCount = 0;//正确翻开的方块数
    private MineLabel [][]mineArray;
    private JPanel pnlArea = new JPanel();
    private JPanel pnlControl = new JPanel(new BorderLayout());
    private JButton btnStart = new JButton("重玩");
    private JLabel lblMineCount =  createDisplayLabel("剩余雷数");
    private JLabel lblTime =  createDisplayLabel("游戏计时");
    private GridLayout mineLayout = new GridLayout(1, 1);
    private Timer timer;
    private boolean ready;

    public MinePanel() {
        setLayout(new BorderLayout());
        //
        JPanel pnlWest = new JPanel();
        pnlWest.add(lblTime);
        pnlControl.add("West", pnlWest);
        JPanel pnlCenter = new JPanel();
        pnlCenter.add( btnStart );
        pnlControl.add(pnlCenter);
        JPanel pnlEast = new JPanel();
        pnlEast.add(lblMineCount);
        pnlControl.add("East", pnlEast);
        //
        add("North", pnlControl);
        //
        pnlArea.setBorder( BorderFactory.createLoweredBevelBorder() );
        pnlArea.setLayout(mineLayout);
        JPanel containPanel = new JPanel();
        containPanel.add(pnlArea);
        add(containPanel);
        //
        btnStart.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                restart();
            }
        });
        //
        timer = new Timer(1000, new ActionListener(){
            public void actionPerformed(ActionEvent e) {
                secondCount ++;
                lblTime.setText(fmt.format(secondCount));
                if (secondCount==999) {
                    fail();
                }
            }
        });
    }
    //
    private JLabel createDisplayLabel(String toolTipText)
    {
        JLabel lbl = new JLabel();
        lbl.setHorizontalAlignment(JLabel.CENTER);
        lbl.setPreferredSize(new Dimension(48, 24));
        lbl.setBorder(BorderFactory.createLoweredBevelBorder());
        lbl.setFont(new Font(null, Font.BOLD, 18));
        lbl.setForeground(Color.RED);
        lbl.setToolTipText(toolTipText);
        return lbl;
    }
    //按指定的参数开始新的游戏
    public void startNew(int rowCount, int columnCount, int mineCount)
    {
        this.rowCount = rowCount;
        this.mineLayout.setRows(rowCount);

        this.columnCount = columnCount;
        this.mineLayout.setColumns(columnCount);

        this.mineCount = mineCount;
        //确定雷区大小
        int width = columnCount * MineLabel.SIZE;
        int height = rowCount * MineLabel.SIZE;
        pnlArea.setPreferredSize(new Dimension(width + 4, height + 4));
        //
        pnlArea.setVisible(false);
        //清除原有方块
        MineLabel lblMine;
        if(mineArray!=null)
        {
            for (int i = 0; i < mineArray.length; i++) {
               for (int j = 0; j < mineArray[i].length; j++) {
                   lblMine = mineArray[i][j];
                   if(lblMine!=null)
                   {
                       pnlArea.remove(lblMine);
                       mineArray[i][j] = lblMine = null;
                   }
               }
           }
        }
        //重新添加方块
        mineArray = new MineLabel[rowCount][columnCount];
        for (int i = 0; i < rowCount; i++) {
            for (int j = 0; j < columnCount; j++) {
                lblMine = new MineLabel(this, i, j);
                mineArray[i][j] = lblMine;
                pnlArea.add(lblMine);
            }
        }
        //
        pnlArea.setVisible(true);
        //
        ready();
    }
    //重玩
    private void restart()
    {
        //技巧:先隐藏再显示,避免给方块设置边界时不断更新
        setVisible(false);
        //恢复所有按钮到初始状态
        for (int i = 0; i < mineArray.length; i++) {
            for (int j = 0; j < mineArray[i].length; j++) {
                mineArray[i][j].init();
            }
        }
        //
        setVisible(true);
        //
        ready();
    }

    private void ready()
    {
        timer.stop();
        //计数清零
        rightCount = 0;
        secondCount = 0;
        lblTime.setText(fmt.format(secondCount));
        setWarnCount(0);
        //
        ready = true;
    }

    void start(int startRow, int startColumn)
    {
        ready = false;
        //随机布雷
        for (int i = 0; i < mineCount; i++) {
            //随机坐标
            int rowIndex, columnIndex;
            //
            MineLabel lblMine;
            do
            {
                rowIndex = rnd.nextInt(rowCount);
                columnIndex = rnd.nextInt(columnCount);
                lblMine = mineArray[rowIndex][columnIndex];
            }while( rowIndex==startRow && columnIndex==startColumn || lblMine.isMine() );//如果是开始位置或为雷则继续获取下一可能的位置
            //设置为雷
            lblMine.setMine(true);
            //处理周围的按钮,value都应加1
            for (int r = rowIndex - 1 ; r <= rowIndex + 1 ; r++) {
                if (r<0 || r>=rowCount ) {
                    continue;
                }
                for (int c = columnIndex - 1 ; c <= columnIndex + 1; c++) {
                    if ( c<0 || c>=columnCount || ( c==columnIndex && r==rowIndex )/*跳过自己*/ ) {
                        continue;
                    }
                    mineArray[r][c].addValue();
                }
            }
        }
        //刷新界面
        //repaint(0, 0, 0, getWidth(), getHeight());
        //开始计时
        timer.start();
    }

    public void fail()
    {
        //停止计时
        timer.stop();
        //
        MineLabel lblMine;
        for (int i = 0; i < rowCount; i++) {
            for (int j = 0; j < columnCount; j++) {
                lblMine = mineArray[i][j];
                //如果是雷
                if (lblMine.isMine() ) {
                    if(!lblMine.isClicked())//如果没有点击过则显示雷的状态
                    {
                        lblMine.setForeground(MineLabel.COLOR_MINE);
                        lblMine.setText(MineLabel.TEXT_MINE);
                    }
                }
                else if(lblMine.isWarn())//如果不是雷但标记为警告则提示错误
                {
                    lblMine.setForeground(MineLabel.COLOR_ERROR);
                    lblMine.setText(MineLabel.TEXT_ERROR);
                }
                lblMine.setClicked(true);
            }
        }
    }

    //检查是否已获胜
    private void check()
    {
        //如果正确数和警告数加起来等于总方块数,则说明过关
        if(rightCount+warnCount==rowCount*columnCount)
        {
            timer.stop();
            JOptionPane.showMessageDialog(this, "恭喜过关!您的成绩是 " + secondCount + " 秒。", "消息", JOptionPane.INFORMATION_MESSAGE);
        }
    }

    public synchronized void addRigthCount()
    {
        rightCount ++;
        check();
    }

    public int getColumnCount() {
        return columnCount;
    }

    public int getMineCount() {
        return mineCount;
    }

    public int getRowCount() {
        return rowCount;
    }

    public MineLabel[][] getMineArray() {
        return mineArray;
    }

    public int getWarnCount() {
        return warnCount;
    }

    public synchronized void setWarnCount(int warnCount) {
        this.warnCount = warnCount;
        this.lblMineCount.setText( fmt.format(mineCount - warnCount) );
        check();
    }

    public boolean isReady()
    {
        return ready;
    }

    public boolean isPlaying()
    {
        return timer.isRunning();
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -