1. /**
  2. * 一个简单的扫雷游戏
      MainFram.java
  3. */
  4.  
  5. package www.waston;
  6.  
  7. import java.awt.BorderLayout;
  8. import java.awt.Color;
  9. import java.awt.GridLayout;
  10. import java.awt.Insets;
  11. import java.awt.event.ActionEvent;
  12. import java.awt.event.ActionListener;
  13. import java.awt.event.MouseEvent;
  14. import java.awt.event.MouseListener;
  15. import java.util.Random;
  16.  
  17. import javax.swing.ImageIcon;
  18. import javax.swing.JButton;
  19. import javax.swing.JFrame;
  20. import javax.swing.JLabel;
  21. import javax.swing.JMenu;
  22. import javax.swing.JMenuBar;
  23. import javax.swing.JMenuItem;
  24. import javax.swing.JOptionPane;
  25. import javax.swing.JPanel;
  26.  
  27. /**
  28. * 主窗体类
  29. * @author thnk
  30. *
  31. */
  32. public class MineFrame extends JFrame implements ActionListener,MouseListener,Runnable{
  33.  
  34. private static final long serialVersionUID = 1L;
  35.  
  36. private JPanel jp1;
  37. private JPanel jp2;
  38. private JMenuBar menuBar;
  39. private JButton[][] buttons;
  40. private JLabel showMine;//显示剩余地雷的个数
  41. private JLabel showTime;//显示已使用的时间
  42. private int time;//已使用的时间
  43. boolean isOver = true;//游戏是否还在继续
  44. private int[] vis;//是地雷按钮的角标
  45. private int[][] numbers;//按钮上显示的数字
  46. private boolean[][] isclicked;//该按钮是否被点击
  47. private int cols;//地雷的行和列
  48. private int rows;
  49. private int totalCounts;//地雷的总个数
  50. private int clickCounts;//已经点开的个数
  51. private int gaussCounts;//猜中的个数
  52.  
  53. public MineFrame(){
  54. //基本的设置
  55. super("扫雷游戏");
  56. this.setLocation(300,200);
  57. this.setVisible(true);
  58. this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  59.  
  60. //创建菜单栏
  61. createMenus();
  62.  
  63. //初始化标签信息
  64. showMine = new JLabel();
  65. showTime = new JLabel();
  66. jp1 = new JPanel();
  67. jp2 = new JPanel();
  68. jp1.add(showMine);
  69. jp1.add(new JLabel(" "));
  70. jp1.add(showTime);
  71. this.add(jp1,BorderLayout.NORTH);
  72. this.add(jp2,BorderLayout.CENTER);
  73.  
  74. //初始化游戏
  75. initGame(9,9,10);
  76.  
  77. }
  78.  
  79. //创建菜单
  80. private void createMenus(){
  81. menuBar = new JMenuBar();
  82. JMenu options = new JMenu("选项");
  83. JMenuItem newGame = new JMenuItem("新游戏");//开始游戏
  84. JMenuItem exit = new JMenuItem("退出");
  85. options.add(newGame);
  86. options.add(exit);
  87.  
  88. //游戏等级
  89. JMenu setting = new JMenu("设置");
  90. JMenuItem easy = new JMenuItem("容易");
  91. JMenuItem medium = new JMenuItem("中等");
  92. JMenuItem difficult = new JMenuItem("困难");
  93. setting.add(easy);
  94. setting.add(medium);
  95. setting.add(difficult);
  96.  
  97. //游戏帮助
  98. JMenu help = new JMenu("帮助");
  99. JMenuItem about = new JMenuItem("关于");
  100. help.add(about);
  101.  
  102. menuBar.add(options);
  103. menuBar.add(setting);
  104. menuBar.add(help);
  105. this.setJMenuBar(menuBar);
  106.  
  107. //注册监听器
  108. newGame.setActionCommand("newGame");
  109. newGame.addActionListener(this);
  110.  
  111. exit.setActionCommand("exit");
  112. exit.addActionListener(this);
  113.  
  114. easy.setActionCommand("easy");
  115. easy.addActionListener(this);
  116. medium.setActionCommand("medium");
  117. medium.addActionListener(this);
  118. difficult.setActionCommand("difficult");
  119. difficult.addActionListener(this);
  120.  
  121. about.setActionCommand("help");
  122. about.addActionListener(this);
  123. }
  124.  
  125. //初始化游戏
  126. public void initGame(int rows,int cols,int totalCounts){
  127. this.rows = rows;
  128. this.cols = cols;
  129. this.totalCounts = totalCounts;
  130. isclicked = new boolean[rows][cols];
  131. time = 0;
  132. isOver = true;
  133. clickCounts = 0;
  134. gaussCounts = 0;
  135.  
  136. showMine.setText("你以标记地雷个数:0");
  137. showTime.setText("您已使用时间:0秒");
  138. jp2.removeAll();//移除掉原来的按钮
  139. createMines();
  140. //设置大小
  141. this.setSize(rows*35,cols*35);
  142. //设置出现的位置,居中
  143. int x = (int) this.getToolkit().getScreenSize().getWidth();
  144. int y = (int) this.getToolkit().getScreenSize().getHeight();
  145. this.setLocation((int)(x-this.getSize().getWidth())/2,
  146. (int)(y-this.getSize().getHeight())/2);
  147.  
  148. //开启线程计时
  149. Thread t = new Thread(this);
  150. t.start();
  151. }
  152.  
  153. //创建按钮,初始化界面,由createMines()调用
  154. private void createButtons(){
  155. jp2.setLayout(new GridLayout(rows, cols));
  156. buttons = new JButton[rows][cols];
  157. for(int i=0;i<rows;i++){
  158. for(int j=0;j<cols;j++){
  159. buttons[i][j] = new JButton();
  160. buttons[i][j].setMargin(new Insets(0,0,0,0));
  161. //buttons[i][j].setText(numbers[i][j]+"");
  162. buttons[i][j].addMouseListener(this);
  163. buttons[i][j].setName(i+" "+j);//设置按钮的名字,方便知道是哪个按钮触发,并且传递角标
  164. jp2.add(buttons[i][j]);
  165. }
  166. }
  167.  
  168. }
  169.  
  170. //随机创建地雷,并算出每一个点应显示的周围地雷的个数
  171. private void createMines(){
  172. //通过该数组计算出地雷周围八个格子应该显示的数字
  173. int[][] dir = {{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}};
  174. numbers = new int[rows][cols];
  175. vis = new int[totalCounts];
  176. for(int i=0;i<vis.length;i++){
  177. boolean flag = true;
  178. int index = new Random().nextInt(rows*cols);
  179. for(int j=0;j<i;j++){
  180. if(vis[j]==index){
  181. flag = false;
  182. i--;
  183. break;
  184. }
  185. }
  186. if(flag){
  187. vis[i] = index;
  188. int x = index/cols;
  189. int y = index%cols;
  190. //本身是地雷,让数字等于地雷的总个数加1
  191. numbers[x][y] = totalCounts+1;
  192. for(int j=0;j<dir.length;j++){
  193. int realX = x+dir[j][0];
  194. int realY = y+dir[j][1];
  195. //如果这个点是有效的(没有出界)并且本身不是地雷
  196. if(realX>=0&&realX<rows&&realY>=0&&realY<cols&&numbers[realX][realY]<totalCounts+1)
  197. numbers[realX][realY]++;
  198. }
  199. }
  200. }
  201.  
  202. createButtons();
  203. }
  204.  
  205. //踩到地雷后,显示所有地雷
  206. private void showAllMine(){
  207. for(int i=0;i<vis.length;i++){
  208. int x = vis[i]/cols;
  209. int y = vis[i]%cols;
  210. ImageIcon icon = new ImageIcon("2.jpg");
  211. buttons[x][y].setIcon(icon);
  212. }
  213. }
  214.  
  215. //当点击一个空白区域时,显示这一块不是地雷按钮
  216. private void showEmpty(int x,int y){
  217. buttons[x][y].setEnabled(false);
  218. buttons[x][y].setBackground(Color.GREEN);
  219. isclicked[x][y] = true;
  220. int[][] dir = {{0,-1},{-1,0},{0,1},{1,0}};
  221. for(int i=0;i<4;i++){
  222. int nextX = x+dir[i][0];
  223. int nextY = y+dir[i][1];
  224. //还没有被点过
  225. if(nextX>=0&&nextX<rows&&nextY>=0&&nextY<cols&&!isclicked[nextX][nextY]){
  226.  
  227. if(numbers[nextX][nextY]==0){
  228. showEmpty(nextX,nextY);
  229. }
  230. else if(numbers[nextX][nextY]<=8){
  231. buttons[nextX][nextY].setText(numbers[nextX][nextY]+"");
  232. buttons[nextX][nextY].setBackground(Color.GREEN);
  233. }
  234. }
  235. }
  236. }
  237.  
  238. //该线程用来计算使用时间
  239. @Override
  240. public void run() {
  241. time = 0;
  242. while(isOver){
  243. try {
  244. Thread.sleep(1000);//睡眠一秒钟
  245. time++;
  246. //System.out.println(time);
  247. showTime.setText("您已使用时间:"+time+"秒!");
  248. } catch (InterruptedException e) {
  249. e.printStackTrace();
  250. }
  251. }
  252. }
  253.  
  254. @Override
  255. public void actionPerformed(ActionEvent e) {
  256. //退出游戏
  257. if(e.getActionCommand().equals("exit")){
  258. System.exit(0);
  259. }
  260. //新游戏
  261. else if("newGame".equals(e.getActionCommand())){
  262. isOver = false;
  263. initGame(rows,cols,10);
  264. }
  265. else if("easy".equals(e.getActionCommand())){
  266. isOver = false;
  267. initGame(9,9,10);
  268. }
  269. else if("medium".equals(e.getActionCommand())){
  270. isOver = false;
  271. initGame(15,15,50);
  272. }
  273. else if("difficult".equals(e.getActionCommand())){
  274. isOver = false;
  275. initGame(22,22,100);
  276. }
  277. //游戏帮助
  278. else if("help".equals(e.getActionCommand())){
  279. String information = "尽快的找到游戏中所有布置的雷,这样你才能获取胜利!\n"
  280. +"记住,千万不要踩中地雷,否则您就输了!";
  281. JOptionPane.showMessageDialog(null,information);
  282. }
  283. }
  284.  
  285. @Override
  286. public void mouseClicked(MouseEvent e) {
  287. //System.out.println(e.getModifiers());
  288. //如果已经猜中地雷了,再次点击按钮将不再触发事件
  289. if(!isOver)
  290. return;
  291.  
  292. JButton source = (JButton) e.getSource();
  293. String[] infos = source.getName().split(" ");
  294. int x = Integer.parseInt(infos[0]);
  295. int y = Integer.parseInt(infos[1]);
  296. if(e.getModifiers()==MouseEvent.BUTTON1_MASK){
  297. isclicked[x][y] = true;//该按钮已被点击过
  298. if(numbers[x][y]==totalCounts+1){
  299. showAllMine();
  300. isOver = false;//游戏结束
  301. JOptionPane.showMessageDialog(null, "你踩中地雷了,请重新开始!");
  302. return;
  303. }
  304. if(numbers[x][y]==0){
  305. showEmpty(x, y);
  306. return;
  307. }
  308. source.setBackground(Color.GREEN);
  309. source.setText(numbers[x][y]+"");
  310. //source.setEnabled(false);
  311.  
  312. }else if(e.getModifiers()==MouseEvent.BUTTON3_MASK){
  313. //奇数次右键标记地雷
  314. if(!isclicked[x][y]){
  315. ImageIcon icon = new ImageIcon("1.png");
  316. source.setIcon(icon);
  317. clickCounts++;
  318. showMine.setText("你以标记地雷个数: "+clickCounts);
  319. if(numbers[x][y]==totalCounts+1){
  320. gaussCounts++;
  321. }
  322. if(gaussCounts==totalCounts){
  323. JOptionPane.showMessageDialog(null, "恭喜您赢啦!");
  324. }
  325. }
  326. //偶数次右键取消标记
  327. else{
  328. clickCounts--;
  329. showMine.setText("你以标记地雷个数: "+clickCounts);
  330. if(numbers[x][y]==totalCounts+1){
  331. gaussCounts--;
  332. }
  333. //去掉图标
  334. ImageIcon icon = new ImageIcon();
  335. source.setIcon(icon);
  336. }
  337. isclicked[x][y] = !isclicked[x][y];
  338. }
  339. }
  340.  
  341. @Override
  342. public void mousePressed(MouseEvent e) {
  343.  
  344. }
  345.  
  346. @Override
  347. public void mouseReleased(MouseEvent e) {
  348.  
  349. }
  350.  
  351. @Override
  352. public void mouseEntered(MouseEvent e) {
  353.  
  354. }
  355.  
  356. @Override
  357. public void mouseExited(MouseEvent e) {
  358.  
  359. }
  360.  
  361. }

MineTest.java

  1. package www.waston;
  2.  
  3. public class MineTest {
  4.  
  5. public static void main(String[] args) {
  6. new MineFrame();
  7. }
  8.  
  9. }

java实现简单扫雷游戏的更多相关文章

  1. JavaSwing 版本的简单扫雷游戏

    JavaSwing 版本的简单扫雷游戏 一.扫雷游戏的基本规则 1.扫雷游戏分为初级.中级.高级和自定义四个级别. 单击游戏模式可以选择"初级"."中级".&q ...

  2. Java版的扫雷游戏源码

    package com.xz.sl; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Container; i ...

  3. Java GUI 简单台球游戏模型

    完成效果: 1 package com.neuedu.test; 2 3 import java.awt.Frame; 4 import java.awt.Graphics; 5 import jav ...

  4. 无聊的周末用Java写个扫雷小游戏

    周末无聊,用Java写了一个扫雷程序,说起来,这个应该是在学校的时候,写会比较好玩,毕竟自己实现一个小游戏,还是比较好玩的.说实话,扫雷程序里面核心的东西,只有点击的时候,去触发更新数据这一步. Sw ...

  5. Java练习(模拟扫雷游戏)

    要为扫雷游戏布置地雷,扫雷游戏的扫雷面板可以用二维int数组表示.如某位置为地雷,则该位置用数字-1表示, 如该位置不是地雷,则暂时用数字0表示. 编写程序完成在该二维数组中随机布雷的操作,程序读入3 ...

  6. java实现简单窗体小游戏----球球大作战

    java实现简单窗体小游戏----球球大作战需求分析1.分析小球的属性: ​ 坐标.大小.颜色.方向.速度 2.抽象类:Ball ​ 设计类:BallMain—创建窗体 ​ BallJPanel—画小 ...

  7. Java实现 LeetCode 529 扫雷游戏(DFS)

    529. 扫雷游戏 让我们一起来玩扫雷游戏! 给定一个代表游戏板的二维字符矩阵. 'M' 代表一个未挖出的地雷,'E' 代表一个未挖出的空方块,'B' 代表没有相邻(上,下,左,右,和所有4个对角线) ...

  8. 【Android】自己动手做个扫雷游戏

    1. 游戏规则 扫雷是玩法极其简单的小游戏,点击玩家认为不存在雷的区域,标记出全部地雷所在的区域,即可获得胜利.当点击不包含雷的块的时候,可能它底下存在一个数,也可能是一个空白块.当点击中有数字的块时 ...

  9. C# -- HttpWebRequest 和 HttpWebResponse 的使用 C#编写扫雷游戏 使用IIS调试ASP.NET网站程序 WCF入门教程 ASP.Net Core开发(踩坑)指南 ASP.Net Core Razor+AdminLTE 小试牛刀 webservice创建、部署和调用 .net接收post请求并把数据转为字典格式

    C# -- HttpWebRequest 和 HttpWebResponse 的使用 C# -- HttpWebRequest 和 HttpWebResponse 的使用 结合使用HttpWebReq ...

随机推荐

  1. Scrum 团队成立 -- 软件工程

      团队项目选题  : 金融工具:复利计算与投资记录项目继续升级,开发定位明确.功能专注的工具类软件 团队队员 : 蔡舜 , 林宇粲 , 王昕明 , 卢晓洵 团队目标 : 不断完善 团队口号 : 永不 ...

  2. 20172325 2017-2018-2 《Java程序设计》第九周学习总结

    20172325 2017-2018-2 <Java程序设计>第九周学习总结 教材学习内容总结 异常 1.学习了异常的基本概念: 2.区分异常与错误: 一个异常是指一个定义非正常情况或错误 ...

  3. [Selenium] CSS3 选择器

    在 CSS 中,选择器是一种模式,用于选择需要添加样式的元素. "CSS" 列指示该属性是在哪个 CSS 版本中定义的.(CSS1.CSS2 还是 CSS3.) 选择器 例子 例子 ...

  4. Jmeter运行过程中如何让Fiddler同时可以抓获到服务器的应答报文

    在默认情况下,Jmeter运行过程中,Fiddler是抓不到对应的应答报文的. 但是,在某些时候,我们希望分析Jmeter执行失败的原因,想了解Jmeter获取到的应答报文是否有问题,就需要同服务器返 ...

  5. c++11多线程学习笔记之三 condition_variable使用

    从windows角度来说,condition_variable类似event. 阻塞等待出发,不过condition_variable可以批量出发. 代码如下: // 1111111.cpp : 定义 ...

  6. hadoop 学习(二)ubuntu hadoop 2.7.0 伪分部安装

    本篇是基于上一篇,ubuntu 安装hadoop单机版基础上的 1.配置core-site.xml /usr/local/hadoop/etc/hadoop/core-site.xml 包含了hado ...

  7. 利用windows.h头文件写一个简单的C语言倒计时

    今天写一个简单的倒计时函数 代码如下: #include<stdio.h> #include<windows.h> int main() { int i; printf(&qu ...

  8. 2018.09.29 bzoj3675: [Apio2014]序列分割(斜率优化dp)

    传送门 斜率优化dp经典题目. 首先需要证明只要选择的K个断点是相同的,那么得到的答案也是相同的. 根据分治的思想,我们只需要证明有两个断点时成立,就能推出K个断点时成立. 我们设两个断点分成的三段连 ...

  9. 2018.09.10 bzoj1499: [NOI2005]瑰丽华尔兹(单调队列优化dp)

    传送门 单调队列优化dp好题. 这题其实很简单. 我们很容易想到一个O(T∗n∗m)" role="presentation" style="position: ...

  10. git分支删除

    1.列出本地分支: git branch 2.删除本地分支: git branch -D BranchName 其中-D也可以是--delete,如: git branch --delete Bran ...