在好例子网,分享、交流、成长!
您当前所在位置:首页Java 开发实例Android平台开发 → Java 实现扫雷游戏(MineSweeper)

Java 实现扫雷游戏(MineSweeper)

Android平台开发

下载此实例
  • 开发语言:Java
  • 实例大小:0.41M
  • 下载次数:39
  • 浏览次数:486
  • 发布时间:2015-09-11
  • 实例类别:Android平台开发
  • 发 布 人:crazycode
  • 文件格式:.zip
  • 所需积分:2
 相关标签: 游戏 java 扫雷

实例介绍

【实例简介】

【实例截图】


【核心代码】

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);
	}

}

标签: 游戏 java 扫雷

实例下载地址

Java 实现扫雷游戏(MineSweeper)

不能下载?内容有错? 点击这里报错 + 投诉 + 提问

好例子网口号:伸出你的我的手 — 分享

网友评论

发表评论

(您的评论需要经过审核才能显示)

查看所有0条评论>>

小贴士

感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。

  • 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
  • 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
  • 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
  • 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。

关于好例子网

本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明

;
报警