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

📄 minepanel.java

📁 用java实现的全真模拟windows下的扫雷程序。不过目前实现以button方式实现。改进可以考虑以位图形式实现
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/*
 * MinePanel.java 1.0 2003-6-15
 *
 * Copyleft (c) 2003 RatKing.
 */

package jmine;

import java.awt.*;
import java.awt.event.*;
import java.util.Random;
import java.util.Vector;
import javax.swing.*;
import javax.swing.border.*;

/**
 * 总面板,包括上侧的笑脸按钮面板和下侧的雷区面板
 */
public class MinePanel extends JPanel implements MouseListener {
    private JMine jmine;

    public static final int ONE_SECOND = 1000;  // 1秒 = 1000毫秒

    public static final int LOW_LEVEL       = 0;  // 初级
    public static final int MIDDLE_LEVEL    = 1;  // 中级
    public static final int HIGH_LEVEL      = 2;  // 高级
    public static final int CUSTOM_LEVEL    = 3;  // 自定义...

    public static final int READY   = 0;  // 准备就绪
    public static final int PLAY    = 1;  // 开始游戏
    public static final int PAUSE   = 2;  // 暂停游戏
    public static final int WIN     = 3;  // 胜利结束
    public static final int LOSE    = 4;  // 失败结束

    private int gameLevel   = LOW_LEVEL;  // 难度级别
    private int mineRows    = 0;  // 雷区高度
    private int mineColumns = 0;  // 雷区宽度
    private int totalMines  = 0;  // 地雷总数

    public boolean isMark   = true;  // 标记
    public boolean isColor  = true;  // 颜色
    public boolean isSound  = true;  // 声音

    private int state = READY;  // 系统运行状态

    /**
     * 是否鼠标中键按下
     * 当鼠标中键按下,或鼠标左右键同时按下时,为true
     * 当释放了鼠标中键,或鼠标左右键同时按下后释放任意一个,则为false
     */
    private boolean isMiddlePressed = false;

    /** 开始按钮面板 */
    JPanel startPanel = new JPanel();
    /** 雷区面板 */
    JPanel mineField = new JPanel();

    GridLayout gridLayout = new GridLayout();
    Border raisedbevel = BorderFactory.createRaisedBevelBorder();
    Border loweredbevel = BorderFactory.createLoweredBevelBorder();
    Border margin1 = new EmptyBorder(6,6,6,6);
    Border margin2 = new EmptyBorder(4,6,4,6);
    BorderLayout borderLayout = new BorderLayout();

    public FaceButton faceButton;   // 笑脸按钮
    public MineButton[][] mineButton;  // 雷区按钮
    public Counter remainMines; // 剩余地雷数
    public Counter totalTime;   // 所用时间(秒数)
    public Timer timer;         // 计时器

    public MinePanel(JMine jmine) {
        this(jmine, LOW_LEVEL);
    }

    public MinePanel(JMine jmine, int gameLevel) {
        this.jmine = jmine;
        init();
        setGameLevel(gameLevel);
    }

    /** 面板初始化,组装面板,制定布局与边框 */
    public void init() {
        // 设置面板的边框
        this.setBorder(new CompoundBorder(raisedbevel, margin1));
        startPanel.setBorder(new CompoundBorder(loweredbevel, margin2));
        mineField.setBorder(loweredbevel);

        // 设置面板的布局
        borderLayout.setVgap(6);  // 设置总面板中开始面板与地雷面板之间的间距
        this.setLayout(borderLayout);
        mineField.setLayout(gridLayout);
        startPanel.setLayout(new BoxLayout(startPanel, BoxLayout.X_AXIS));

        // 组装开始按钮
        faceButton = new FaceButton(jmine);
        remainMines = new Counter(jmine, totalMines);
        totalTime = new Counter(jmine, 0);
        totalTime.addMouseListener(new MouseAdapter() {
            public void mousePressed(MouseEvent e) {
                // 若按下中键,或同时按下鼠标左键和右键,则暂停计时
                if ((e.getButton() == MouseEvent.BUTTON2
                        || (e.getModifiersEx() & (InputEvent.BUTTON1_DOWN_MASK | InputEvent.BUTTON3_DOWN_MASK))
                        == (InputEvent.BUTTON1_DOWN_MASK | InputEvent.BUTTON3_DOWN_MASK))) {
                    if (timer.isRunning()) {
                        timer.stop();
                        //state = PAUSE;
                    }
                    else if (state == PLAY) {
                        timer.start();
                    }
                }
            }
        });

        startPanel.add(remainMines);
        startPanel.add(Box.createHorizontalGlue());
        startPanel.add(faceButton);
        startPanel.add(Box.createHorizontalGlue());
        startPanel.add(totalTime);
        faceButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                replay();
            }
        });

        // 定义时钟及其事件处理方法
        timer = new Timer(ONE_SECOND, new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
        	totalTime.increase();  // “计时器”每增加1秒,“所用时间”就也增加1秒
        	if (isSound) {
        	    Toolkit.getDefaultToolkit().beep();
        	}
            }
        });

        // 组装总面板
        this.add(startPanel, BorderLayout.NORTH);
        this.add(mineField, BorderLayout.CENTER);
        this.addMouseListener(this);
    }  // init()

    public int getGameLevel() {
        return gameLevel;
    }

    public void setGameLevel(int gameLevel) {
        this.gameLevel = gameLevel;

        if (gameLevel == LOW_LEVEL) {
            reset(9, 9, 10);
        }
        else if (gameLevel == MIDDLE_LEVEL) {
            reset(16, 16, 40);
        }
        else if (gameLevel == HIGH_LEVEL) {
            reset(16, 30, 99);
        }
    }

    public void setGameLevel(int mineRows, int mineColumns, int totalMines) {
        gameLevel = CUSTOM_LEVEL;
        reset(mineRows, mineColumns, totalMines);
    }

    public void replay() {
        reset(mineRows, mineColumns, totalMines);

    }

    /**
     * 系统重置
     */
    private void reset(int mineRows, int mineColumns, int totalMines) {
        state = READY;
        timer.stop();

        remainMines.setNumber(totalMines);
        faceButton.setIconStyle(FaceButton.FACE_SMILE);
        totalTime.setNumber(0);

        // 是否雷区大小发生改变
        boolean isChanged = false;

        if (this.mineRows != mineRows
                || this.mineColumns != mineColumns
                || this.totalMines != totalMines) {
            isChanged = true;
            this.mineRows = mineRows;
            this.mineColumns = mineColumns;
            this.totalMines = totalMines;
        }

        if (isChanged) {
            // 清除雷区所有地雷按钮
            mineField.removeAll();

            // 重置mineField面板中GridLayout布局的高度与宽度
            gridLayout.setRows(mineRows);       // 设置地雷的行数
            gridLayout.setColumns(mineColumns); // 设置地雷的列数

            // 生成地雷按钮,并组装到地雷面板中
            mineButton = new MineButton[mineRows][mineColumns];
            for (int i = 0; i < mineRows; i++) {
                for (int j = 0; j < mineColumns; j++) {
                    mineButton[i][j] = new MineButton(jmine, i, j);
                    mineButton[i][j].addMouseListener(this);
                    mineField.add(mineButton[i][j]);
                }
            }
        }

        // 重置所有地雷按钮为初始状态
        for (int i = 0; i < mineRows; i++) {
            for (int j = 0; j < mineColumns; j++) {
                mineButton[i][j].setMine(false);
                mineButton[i][j].setIconStyle(MineButton.ICON_NULL);
            }
        }

        // 随机分布地雷
        Random random = new Random();
        int k = 0;
        while (k < totalMines) {
            int r = random.nextInt(mineRows);
            int c = random.nextInt(mineColumns);
            if (!mineButton[r][c].isMine()) {
                mineButton[r][c].setMine(true);
                k++;
            }
        }
        validate();  // 使改动生效
    }

    public int getMineRows() {
        return mineRows;
    }

    public void setMineRows(int mineRows) {
        this.mineRows = mineRows;
    }

    public int getMineColumns() {
        return mineColumns;
    }

    public void setMineColumns(int mineColumns) {
        this.mineColumns = mineColumns;
    }

    public int getTotalMines() {
        return totalMines;
    }

    public void setTotalMines(int totalMines) {
        this.totalMines = totalMines;
    }

    // 定义鼠标事件处理方法
    public void mouseClicked(MouseEvent e) {
    }

    public void mousePressed(MouseEvent e) {
        if (state != READY && state != PLAY)
            return;

        faceButton.setIconStyle(FaceButton.FACE_O);
        Object object = e.getSource();
        if (!(object instanceof MineButton))
            return;




        int button = e.getButton();
        int modifiers = e.getModifiers();
        int modifiersEx = e.getModifiersEx();

        MineButton mb = (MineButton) object;

        // 按钮呈凹下的样子
        if (mb.getIconStyle() == MineButton.ICON_NULL
                || mb.getIconStyle() == MineButton.ICON_MARK) {
            mb.setBorderDown();
        }

        // 若仅按下鼠标右键,且左键未按下
        if (button == MouseEvent.BUTTON3
                && (modifiersEx & InputEvent.BUTTON1_DOWN_MASK)
                != InputEvent.BUTTON1_DOWN_MASK) {
            // 处理插上小红旗过程
            if (mb.getIconStyle() == MineButton.ICON_NULL) {
                mb.setIconStyle(MineButton.ICON_FLAG);
                remainMines.decrease();
                if (checkWinning()) {
                    doWin();
                }
            }
            else if (mb.getIconStyle() == MineButton.ICON_FLAG) {
                if (isMark) {
                    mb.setIconStyle(MineButton.ICON_MARK);
                }
                else {
                    mb.setIconStyle(MineButton.ICON_NULL);
                }
                remainMines.increase();
            }
            else if (mb.getIconStyle() == MineButton.ICON_MARK) {
                mb.setIconStyle(MineButton.ICON_NULL);
            }
            return;
        }

        // 若按下中键,或同时按下鼠标左键和右键
        if (button == MouseEvent.BUTTON2
                || (modifiersEx & (InputEvent.BUTTON1_DOWN_MASK | InputEvent.BUTTON3_DOWN_MASK))
                == (InputEvent.BUTTON1_DOWN_MASK | InputEvent.BUTTON3_DOWN_MASK)) {
            isMiddlePressed = true;
            doDownAround(mb);
        }
    }

    public void mouseReleased(MouseEvent e) {
        if (state != READY && state != PLAY)
            return;

        faceButton.setIconStyle(FaceButton.FACE_SMILE);
        Object object = e.getSource();
        if (!(object instanceof MineButton))
            return;
        MineButton mb = (MineButton) object;

        int button = e.getButton();
        int modifiers = e.getModifiers();
        int modifiersEx = e.getModifiersEx();

        // 如果在地雷按钮外部释放鼠标,则把该鼠标释放事件传输到鼠标所在的按钮
        if (!mb.contains(e.getX(), e.getY())) {
            int x = e.getX();
            int y = e.getY();
            int width = mb.getSize().width;
            int height = mb.getSize().height;
            int row = mb.getRow();
            int column = mb.getColumn();

            //System.out.println("Debug: row = " + row + ", column = " + column + ", e = " + e);
            if (y > 0)
                row += y / height;
            else
                row -= -y / height + 1;
            if (x > 0)
                column += x / width;
            else
                column -= -x / width + 1;

            if (row >= 0 && column >= 0 && row < mineRows && column < mineColumns) {
                //System.out.println("Debug2: row = " + row + ", column = " + column
                //        + ", e = " + SwingUtilities.convertMouseEvent(mb, e, mineButton[row][column]));
                mineButton[row][column].dispatchEvent(SwingUtilities.convertMouseEvent(mb, e, mineButton[row][column]));
            }

            return;
        }

        // 若释放了左键,且此时右键未按下
        if (button == MouseEvent.BUTTON1 && !isMiddlePressed
                && ((modifiersEx & InputEvent.BUTTON3_DOWN_MASK) != InputEvent.BUTTON3_DOWN_MASK)) {
            treadMineButton(mb);
        }
        // 若释放了中键,或释放了左右键同时按下后的任何一个
        if (isMiddlePressed || button == MouseEvent.BUTTON2
                || (button == MouseEvent.BUTTON1
                && (modifiersEx & InputEvent.BUTTON3_DOWN_MASK) == InputEvent.BUTTON3_DOWN_MASK)
                || (button == MouseEvent.BUTTON3
                && (modifiersEx & InputEvent.BUTTON1_DOWN_MASK) == InputEvent.BUTTON1_DOWN_MASK)) {
            isMiddlePressed = false;
            doDoubleDownReleased(mb);
        }

    }

    public void mouseEntered(MouseEvent e) {
        if (state != READY && state != PLAY)
            return;

        Object object = e.getSource();
        int modifiersEx = e.getModifiersEx();

        if (!(object instanceof MineButton))
            return;
        MineButton mb = (MineButton) object;

        // 若按下了鼠标左键、或中键,或同时按下了左右键
        if ((modifiersEx & InputEvent.BUTTON1_DOWN_MASK) == InputEvent.BUTTON1_DOWN_MASK
                || (modifiersEx & InputEvent.BUTTON2_DOWN_MASK) == InputEvent.BUTTON2_DOWN_MASK
                || (modifiersEx & (InputEvent.BUTTON1_DOWN_MASK | InputEvent.BUTTON3_DOWN_MASK))
                == (InputEvent.BUTTON1_DOWN_MASK | InputEvent.BUTTON3_DOWN_MASK)) {
            // 按钮呈凹下的样子
            if (mb.getIconStyle() == MineButton.ICON_NULL
                    || mb.getIconStyle() == MineButton.ICON_MARK) {
                mb.setBorderDown();
            }
        }

        // 若按下了鼠标中键,或同时按下了鼠标左键和右键
        if ((modifiersEx & InputEvent.BUTTON2_DOWN_MASK) == InputEvent.BUTTON2_DOWN_MASK
                ||(modifiersEx & (InputEvent.BUTTON1_DOWN_MASK | InputEvent.BUTTON3_DOWN_MASK))
                == (InputEvent.BUTTON1_DOWN_MASK | InputEvent.BUTTON3_DOWN_MASK)) {
            // 周围按钮呈凹下的样子
            doDownAround(mb);
        }
    }

    public void mouseExited(MouseEvent e) {
        if (state != READY && state != PLAY)
            return;

        Object object = e.getSource();
        int modifiersEx = e.getModifiersEx();

        if (!(object instanceof MineButton))
            return;
        MineButton mb = (MineButton) object;
        // 按钮呈凸出的样子
        if (mb.getIconStyle() == MineButton.ICON_NULL
                || mb.getIconStyle() == MineButton.ICON_MARK) {
            mb.setBorderUp();
        }

        // 若按下了鼠标中键,或同时按下了鼠标左键和右键
        if ((modifiersEx & InputEvent.BUTTON2_DOWN_MASK) == InputEvent.BUTTON2_DOWN_MASK
                ||(modifiersEx & (InputEvent.BUTTON1_DOWN_MASK | InputEvent.BUTTON3_DOWN_MASK))
                == (InputEvent.BUTTON1_DOWN_MASK | InputEvent.BUTTON3_DOWN_MASK)) {
            // 周围按钮呈凸出的样子
            doUpAround(mb);

⌨️ 快捷键说明

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