实例介绍
【实例简介】
【实例截图】
【核心代码】
package com.kerence.mine.mineGUI; import java.awt.Color; import java.awt.GridLayout; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import javax.swing.BorderFactory; import javax.swing.JPanel; import javax.swing.border.BevelBorder; import javax.swing.border.Border; import javax.swing.border.EmptyBorder; import com.kerence.mine.data_structure.MineMatrix; import com.kerence.mine.mine_model.Strategy.MineMatrixSettable; import com.kerence.mine.res.image.ImageIconFactory; /** * 扫雷矩阵面板 * * @author Kerence * */ public class JMineMatrixPanel extends JPanel { private JMineSweeperFrame mineSweeperFrame; /** * 得到一个JMineSweeperFrame的引用,这样才能对statusPanel进行操作 * * @param mineSweeperFrame * 一个JMineSweeperFrame对象的引用 */ public void addMineSweeperFrame(JMineSweeperFrame mineSweeperFrame) { this.mineSweeperFrame = mineSweeperFrame; } /** * 雷块鼠标监听器 * * @author Kerence * */ private class BlockMouseListener extends MouseAdapter { /** * 鼠标移入时进行的操作 */ @Override public void mouseEntered(MouseEvent e) { currentMineBlock = ((JMineBlock) e.getSource()); int row = currentMineBlock.getRow(); int column = currentMineBlock.getColumn(); if (button1Pressed && button3Pressed) { setAutoProbeIcons(row, column); } else { if (button1Pressed) {// 在鼠标左键按下的条件下 if (isFlagged(row, column)) { return; } if (isDigged(row, column)) { return; } else {// 若没被挖则 显示空白 currentMineBlock.setBlankPressed(); return; } } } } /** * 鼠标移出时进行的操作 */ @Override public void mouseExited(MouseEvent e) { if (button3Pressed && button1Pressed) {// 两键同时被按下的情况 // 显示出原图 if (currentMineBlock != null) { int row = currentMineBlock.getRow(); int column = currentMineBlock.getColumn(); revertAutoProbeIcons(row, column); } currentMineBlock = null; return; } if (button3Pressed) {// 右键被按下 currentMineBlock = null; } else {// 右键未被按下 int row = currentMineBlock.getRow(); int column = currentMineBlock.getColumn(); if (button1Pressed) {// 左键按下 显示原图 if (isFlagged(row, column)) { } else if (!isDigged(row, column)) { if (isRabotOn() && isMine(row, column)) { currentMineBlock.setDot(); } else { currentMineBlock.setBlank(); } } currentMineBlock = null; return; } if (isDigged(row, column)) { currentMineBlock = null; return; } else { refreshMineMatrixPanel(); } } currentMineBlock = null; } /** * 鼠标单击时进行的操作 */ @Override public void mousePressed(MouseEvent e) { // 鼠标的操作有哪些 特别是鼠标按下的操作 if (e.getButton() == MouseEvent.BUTTON1) { button1Pressed = true; } else if (e.getButton() == MouseEvent.BUTTON3) { button3Pressed = true; } // 得到被按下的块的行和列 int row = currentMineBlock.getRow(); int column = currentMineBlock.getColumn(); // 左右键都按下,则探测 if (button1Pressed && button3Pressed) {// 两键都被按下 mineSweeperFrame.leftButtonPressedOnMineBlock(); // TODO auto probe setAutoProbeIcons(row, column); // refreshMineMatrixPanel(); } else if (button1Pressed && !button3Pressed) {// 左键按下,右键未按下 mineSweeperFrame.leftButtonPressedOnMineBlock(); if (isDigged(row, column)) { return; } else if (isFlagged(row, column)) {// 被置旗则也不变 return; } jMineMatrix[row][column].setBlankPressed(); } else if (button3Pressed && !button1Pressed) {// 右键被按下 左键未按下 // 若被挖则无反应 if (isDigged(row, column)) { return; } // 未被挖则要判断是否被置旗 是否被置标记 if (isFlagged(row, column)) {// 若已放旗 if (isMarkable()) {// 可标记 setUnFlagged(row, column);// 先取消旗 setMarked(row, column);// 设为标记 } else {// 不可标记 setUnFlagged(row, column);// 取消旗 } } else {// 若未放旗 if (isMarked(row, column)) {// 若被标记 setUnMarked(row, column);// 设置为未标记 } else { setFlagged(row, column); } } mineSweeperFrame.setLEDMineCountLeft(mineMatrix.getMineCount() - mineMatrix.getFlagCount()); refreshMineMatrixPanel(); return; } } /** * 鼠标释放时进行的操作 */ @Override public void mouseReleased(MouseEvent e) {// 它的源是鼠标按下时的组件。 boolean button1Released = false, button3Released = false; if (e.getButton() == MouseEvent.BUTTON1) { button1Pressed = false; button1Released = true; } else if (e.getButton() == MouseEvent.BUTTON3) { button3Pressed = false; button3Released = true; } // 鼠标的操作有哪些 特别是鼠标放开的操作 // 左键放开时 // 右键按下 // 这时要进行的操作是自动探测并挖雷 刷新一次界面 // 鼠标释放事件汇总 左键放开 右键放开。 if ((button1Released && button3Pressed)// 就是进行探测了。 || (button1Pressed && button3Released)) {// 右键按下时 左键放开 // 或者左键按下时右键放开 if (currentMineBlock == null) { return; } int row = currentMineBlock.getRow(); int column = currentMineBlock.getColumn(); mineSweeperFrame.leftButtonReleasedOnMineBlock();// 对状态栏进行的操作 // 恢复图形显示 revertAutoProbeIcons(row, column); if (!isDigged(row, column)) {// 如果没被挖过就不能自动探测 return; } mineMatrix.autoDetectMine(currentMineBlock.getRow(), currentMineBlock.getColumn()); if (mineMatrix.isGameOver()) { // 找到所有雷并 // mineMatrix.gameOver();// 进行gameOver的雷阵设置 gameTerminates(); button3Pressed = false; button1Pressed = false; mineSweeperFrame.gameOver(); } else if (mineMatrix.isGameComplete()) { mineMatrix.gameComplete(); gameTerminates(); button3Pressed = false; button1Pressed = false; mineSweeperFrame.gameComplete(); } refreshMineMatrixPanel();// 刷新图形显示 return; } // 左键放开 // 挖雷 若已被挖开则不挖 刷新一次界面 else if (button1Released && !button3Pressed) {// 右键未按下时左键放开挖雷 mineSweeperFrame.leftButtonReleasedOnMineBlock(); if (currentMineBlock == null) { return; } int row = currentMineBlock.getRow(); int column = currentMineBlock.getColumn(); if (mineMatrix.isDigged(row, column)) {// 判断是否已经被挖开 return; } else {// 没挖开就挖 // 还要判断是否是第一挖 if (mineMatrix.isFlagged(row, column)) {// 要先判断是否放旗。 // 是旗则不挖 return; } if (!mineMatrix.hasGameCommenced()) {// 如果未开局 generateRandomMatrix(row, column);// 并生成雷阵列。 mineMatrix.setGameCommenced(true);// 设置成开局 activateStatusPanel();// 通知主窗口游戏开始。只是对状态栏进行设置而已 // 而且这里的命名好像不好吧。应该换成activatestatuspanel } mineMatrix.digBlock(row, column);// 挖雷包括自动挖开周围的雷 // 如果是雷则自动可以挖开所有的雷。 // 判断是否挖的是雷 if (isMine(row, column)) {// 如果挖的是雷则释放所有监听器 mineMatrix.setGameOver(true); gameTerminates(); // 释放所有雷区按钮的监听器 mineSweeperFrame.gameOver();// 通知扫雷框架对状态进行设置 } else if (mineMatrix.isGameComplete()) { gameTerminates(); mineMatrix.gameComplete(); mineSweeperFrame.gameComplete(); } refreshMineMatrixPanel();// 刷新界面 } } } } /** * 设置row行column列的雷为标记 * * @param row * 行号 * @param column * 列号 */ private void setMarked(int row, int column) { this.mineMatrix.setMarked(row, column); } /** * 设置row行column列的雷为未标记 * * @param row * 行号 * @param column * 列号 */ private void setUnMarked(int row, int column) { this.mineMatrix.setUnMarked(row, column); } /** * 返回是否可以标记 * * @return 要否标记的状态 */ private boolean isMarkable() { return mineMatrix.isMarkable(); } /** * 激活状态栏 */ private void activateStatusPanel() { mineSweeperFrame.gameCommences(); } /** * 设置自动探测状态下雷块周围图标的显示 * * @param row * 雷块的行号 * @param column * 雷块的列号 */ private void setAutoProbeIcons(int row, int column) {// 自动探测时的图标显示 // 将周围被标记的置为标记按下 for (int i = -1; i < 2; i ) { for (int j = -1; j < 2; j ) { setAutoProbeIcon(row i, column j); } } } /** * 设置自动探测状态下恢复雷块周围图标的显示 * * @param row * 雷块的行号 * @param column * 雷块的列号 */ private void revertAutoProbeIcons(int row, int column) {// 自动探测时的图标显示 // 将周围被标记的置为标记按下 for (int i = -1; i < 2; i ) { for (int j = -1; j < 2; j ) { revertAutoProbeIcon(row i, column j); } } } /** * 设置自动探测状态下该雷块的图标显示 * * @param row * 雷块的行号 * @param column * 雷块的列号 */ private void setAutoProbeIcon(int row, int column) {// 自动探测时的图标显示 if (row < 0 || row > this.getMatrixRowCount() - 1 || column < 0 || column > this.getMatrixColumnCount() - 1) { return; } // 将周围被标记的置为标记按下 if (isMarked(row, column)) { this.jMineMatrix[row][column].setMarkPressed(); return; } // 将周围未被挖或者未被置旗不改变图案 if (isDigged(row, column) || isFlagged(row, column)) { return; } // 否则显示为按下 this.jMineMatrix[row][column].setBlankPressed(); } /** * 恢复雷块的自动探测状态下的图标 * * @param row * 雷块的和行号 * @param column * 雷块的列号 */ private void revertAutoProbeIcon(int row, int column) {// 自动探测时的图标显示 if (row < 0 || row > this.getMatrixRowCount() - 1 || column < 0 || column > this.getMatrixColumnCount() - 1) { return; } // 将周围被标记的置为标记按下 if (isMarked(row, column)) { this.jMineMatrix[row][column].setAsk(); return; } // 将周围未被挖或者未被置旗的 置为按下 if (isDigged(row, column) || isFlagged(row, column)) { return; } // 否则显示为空白 if (isRabotOn() && isMine(row, column)) { this.jMineMatrix[row][column].setDot(); return; } this.jMineMatrix[row][column].setBlank(); } MouseListener blockMouseListener = new BlockMouseListener(); private boolean button1Pressed; private boolean button3Pressed; private JMineBlock currentMineBlock; private JMineBlock[][] jMineMatrix; private MineMatrix mineMatrix = new MineMatrix(); /** * 构造方法,设置边界,背景色等。 */ public JMineMatrixPanel() { Border b1 = BorderFactory.createCompoundBorder(new BevelBorder(BevelBorder.LOWERED), new BevelBorder(BevelBorder.LOWERED)); Border b2 = BorderFactory.createCompoundBorder(new EmptyBorder(5, 5, 5, 5), b1); setBorder(b2); setBackground(Color.LIGHT_GRAY); } /** * 重置游戏 */ public void resetGame() {// 重置游戏 this.resetMatrixPanel(); } /** * 游戏结束 */ private void gameTerminates() { // 要做哪些操作 // 1.让所有的点击雷区事件都没有响应, 即释放所有监听器 for (int row = 0; row < this.getMatrixRowCount(); row ) { for (int column = 0; column < this.getMatrixColumnCount(); column ) { jMineMatrix[row][column].removeMouseListener(blockMouseListener); } } } /** * 生成随机布雷的矩阵 其中指定位置不能是雷 * * @param specifiedRow * 指定的雷块行号 * @param specifiedColumn * 指定的雷块列号 */ public void generateRandomMatrix(int specifiedRow, int specifiedColumn) { mineMatrix.generateRandomMatrix(specifiedRow, specifiedColumn); } /** * 得到当前鼠当前指向的雷块的列号 * * @return 列号 */ public int getCurrentBlockColumn() { return currentMineBlock.getColumn(); } /** * 得到当前鼠当前指向的雷块的行号 * * @return 行号 */ public int getCurrentBlockRow() { return currentMineBlock.getRow(); } /** * 得到矩阵列数 * * @return 列数 */ public int getMatrixColumnCount() { return this.mineMatrix.getMatrixColumnCount(); } /** * 得到矩阵行数 * * @return 行数 */ public int getMatrixRowCount() { return this.mineMatrix.getMatrixRowCount(); } /** * 得到矩阵中雷的个数 * * @return 雷个数 */ public int getMineCount() { return this.mineMatrix.getMineCount(); } /** * 得到某个雷块周围的雷的个数 * * @return 周围雷的个数 */ public int getMineCountAround(int row, int column) { return this.mineMatrix.getMineCountAround(row, column); } /** * 返回某个位置的雷块是否被挖 * * @param row * 行号 * @param column * 列号 * @return 被挖的状态 */ public boolean isDigged(int row, int column) { return this.mineMatrix.isDigged(row, column); } /** * 返回某个位置的雷块是否被置旗 * * @param row * 行号 * @param column * 列号 * @return 被置旗的状态 */ public boolean isFlagged(int row, int column) { return this.mineMatrix.isFlagged(row, column); } /** * 返回某个位置的雷块是否被标记 * * @param row * 行号 * @param column * 列号 * @return 被标记的态 */ public boolean isMarked(int row, int column) { return mineMatrix.isMarked(row, column); } /** * 返回某个位置的雷块是否是雷 * * @param row * 行号 * @param column * 列号 * @return 是否是雷的状态 */ public boolean isMine(int row, int column) { return this.mineMatrix.isMine(row, column); } /** * 刷新矩阵面板,即雷阵上的雷状态发生变化时调用这个方法,刷新界面 */ public void refreshMineMatrixPanel() { int row = this.getMatrixRowCount(); int column = this.getMatrixColumnCount(); for (int r = 0; r < row; r ) { for (int c = 0; c < column; c ) { if (this.isDigged(r, c)) {// 被挖过 if (this.isMine(r, c)) {// 是雷 // 被挖是雷 则显示出红雷 this.jMineMatrix[r][c].setRedMine(); } else {// 如果不是雷则显示出数字 // 设置正确数字 被挖是雷无标记 int count = this.getMineCountAround(r, c); this.jMineMatrix[r][c].setNumber(count); } } else {// 没被挖过则 显示是否放置旗 和标记 if (isFlagged(r, c) && !isMine(r, c) && mineMatrix.isGameOver()) {// 没被挖过 被置旗 不是雷 jMineMatrix[r][c].setWrongMine(); continue; } if (!isFlagged(r, c) && isMine(r, c) && mineMatrix.isGameOver()) {// 游戏结束是雷而且没被置旗 jMineMatrix[r][c].setMine(); continue; } if (isFlagged(r, c)) {// 未挖过,是旗 jMineMatrix[r][c].setFlag(); continue; } if (isMarked(r, c)) {// 没被挖过 被置标记 jMineMatrix[r][c].setAsk(); continue; } if (isRabotOn() && isMine(r, c)) {// 开启作弊而且又是雷 jMineMatrix[r][c].setDot(); continue; } // 以上情况都不是,则显示出空白 jMineMatrix[r][c].setBlank(); } } } } /** * 返回外挂是否开启 * * @return 外挂状态 */ private boolean isRabotOn() { return this.mineMatrix.isRatbotOn(); } /** * 返回外挂是否开启 * * @return 外挂状态 */ protected void setDigged(int row, int column) { this.mineMatrix.setDigged(row, column); } /** * 设置某个位置的雷块被标记 * * @param row * 行号 * @param column * 列号 */ public void setFlagged(int row, int column) { this.mineMatrix.setFlagged(row, column); } /** * 更改游戏模式 * * @param mineMatrixSettable * 游戏模式对象引用 */ public void setMineMatrix(MineMatrixSettable mineMatrixSettable) { mineMatrixSettable.setMineMatrix(mineMatrix); mineMatrix.setMineMatrixSettable(mineMatrixSettable); int row = this.getMatrixRowCount(); int column = this.getMatrixColumnCount(); jMineMatrix = new JMineBlock[row][column]; resetMatrixPanel(); } /** * 重置矩阵面板 当游戏模式改变时调用它生成新的雷阵列 */ private void resetMatrixPanel() { resetMineMatrixLabel();// 重置雷标的数量 mineMatrix.resetMatrix();// 重置底层雷阵 } /** * 得到游戏模式 * * @return 游戏模式描述的字符串 */ public String getGameMode() { return this.mineMatrix.getGameMode(); } /** * 重置雷阵列图标 将之前所有的雷块图标都清除然后重新生成雷块图标对象 * */ private void resetMineMatrixLabel() {// 重置雷阵的图标数量。 int row = this.getMatrixRowCount(); int column = this.getMatrixColumnCount(); this.setLayout(new GridLayout(row, column)); this.removeAll(); this.mineMatrix.setGameCommenced(false); for (int r = 0; r < row; r ) { for (int c = 0; c < column; c ) { this.jMineMatrix[r][c] = new JMineBlock(ImageIconFactory.getBlank()); jMineMatrix[r][c].setRow(r); jMineMatrix[r][c].setColumn(c); this.jMineMatrix[r][c].addMouseListener(this.blockMouseListener); this.add(jMineMatrix[r][c]); } } } /** * 取消某个位置的雷块的置旗状态 * * @param row * 行号 * @param column * 列号 */ public void setUnFlagged(int row, int column) { this.mineMatrix.setUnFlagged(row, column); } /** * 得到当前模式雷阵的列数 * */ public int getColumnCount() { return this.mineMatrix.getColumn(); } /** * 得到当前模式雷阵的行数 * */ public int getRowCount() { return this.mineMatrix.getRow(); } /** * 设置是否可以标记 * * @param b * 可否标记的状态 */ public void setMarkable(boolean b) { this.mineMatrix.setMarkable(b); } /** * 设置外挂状态 * * @param b * 外挂状态 */ public void setRabot(boolean b) { this.mineMatrix.setRabot(b); } }
好例子网口号:伸出你的我的手 — 分享!
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明
网友评论
我要评论