java实现简单扫雷游戏
- /**
- * 一个简单的扫雷游戏
MainFram.java- */
- package www.waston;
- import java.awt.BorderLayout;
- import java.awt.Color;
- import java.awt.GridLayout;
- import java.awt.Insets;
- import java.awt.event.ActionEvent;
- import java.awt.event.ActionListener;
- import java.awt.event.MouseEvent;
- import java.awt.event.MouseListener;
- import java.util.Random;
- import javax.swing.ImageIcon;
- import javax.swing.JButton;
- import javax.swing.JFrame;
- import javax.swing.JLabel;
- import javax.swing.JMenu;
- import javax.swing.JMenuBar;
- import javax.swing.JMenuItem;
- import javax.swing.JOptionPane;
- import javax.swing.JPanel;
- /**
- * 主窗体类
- * @author thnk
- *
- */
- public class MineFrame extends JFrame implements ActionListener,MouseListener,Runnable{
- private static final long serialVersionUID = 1L;
- private JPanel jp1;
- private JPanel jp2;
- private JMenuBar menuBar;
- private JButton[][] buttons;
- private JLabel showMine;//显示剩余地雷的个数
- private JLabel showTime;//显示已使用的时间
- private int time;//已使用的时间
- boolean isOver = true;//游戏是否还在继续
- private int[] vis;//是地雷按钮的角标
- private int[][] numbers;//按钮上显示的数字
- private boolean[][] isclicked;//该按钮是否被点击
- private int cols;//地雷的行和列
- private int rows;
- private int totalCounts;//地雷的总个数
- private int clickCounts;//已经点开的个数
- private int gaussCounts;//猜中的个数
- public MineFrame(){
- //基本的设置
- super("扫雷游戏");
- this.setLocation(300,200);
- this.setVisible(true);
- this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
- //创建菜单栏
- createMenus();
- //初始化标签信息
- showMine = new JLabel();
- showTime = new JLabel();
- jp1 = new JPanel();
- jp2 = new JPanel();
- jp1.add(showMine);
- jp1.add(new JLabel(" "));
- jp1.add(showTime);
- this.add(jp1,BorderLayout.NORTH);
- this.add(jp2,BorderLayout.CENTER);
- //初始化游戏
- initGame(9,9,10);
- }
- //创建菜单
- private void createMenus(){
- menuBar = new JMenuBar();
- JMenu options = new JMenu("选项");
- JMenuItem newGame = new JMenuItem("新游戏");//开始游戏
- JMenuItem exit = new JMenuItem("退出");
- options.add(newGame);
- options.add(exit);
- //游戏等级
- JMenu setting = new JMenu("设置");
- JMenuItem easy = new JMenuItem("容易");
- JMenuItem medium = new JMenuItem("中等");
- JMenuItem difficult = new JMenuItem("困难");
- setting.add(easy);
- setting.add(medium);
- setting.add(difficult);
- //游戏帮助
- JMenu help = new JMenu("帮助");
- JMenuItem about = new JMenuItem("关于");
- help.add(about);
- menuBar.add(options);
- menuBar.add(setting);
- menuBar.add(help);
- this.setJMenuBar(menuBar);
- //注册监听器
- newGame.setActionCommand("newGame");
- newGame.addActionListener(this);
- exit.setActionCommand("exit");
- exit.addActionListener(this);
- easy.setActionCommand("easy");
- easy.addActionListener(this);
- medium.setActionCommand("medium");
- medium.addActionListener(this);
- difficult.setActionCommand("difficult");
- difficult.addActionListener(this);
- about.setActionCommand("help");
- about.addActionListener(this);
- }
- //初始化游戏
- public void initGame(int rows,int cols,int totalCounts){
- this.rows = rows;
- this.cols = cols;
- this.totalCounts = totalCounts;
- isclicked = new boolean[rows][cols];
- time = 0;
- isOver = true;
- clickCounts = 0;
- gaussCounts = 0;
- showMine.setText("你以标记地雷个数:0");
- showTime.setText("您已使用时间:0秒");
- jp2.removeAll();//移除掉原来的按钮
- createMines();
- //设置大小
- this.setSize(rows*35,cols*35);
- //设置出现的位置,居中
- int x = (int) this.getToolkit().getScreenSize().getWidth();
- int y = (int) this.getToolkit().getScreenSize().getHeight();
- this.setLocation((int)(x-this.getSize().getWidth())/2,
- (int)(y-this.getSize().getHeight())/2);
- //开启线程计时
- Thread t = new Thread(this);
- t.start();
- }
- //创建按钮,初始化界面,由createMines()调用
- private void createButtons(){
- jp2.setLayout(new GridLayout(rows, cols));
- buttons = new JButton[rows][cols];
- for(int i=0;i<rows;i++){
- for(int j=0;j<cols;j++){
- buttons[i][j] = new JButton();
- buttons[i][j].setMargin(new Insets(0,0,0,0));
- //buttons[i][j].setText(numbers[i][j]+"");
- buttons[i][j].addMouseListener(this);
- buttons[i][j].setName(i+" "+j);//设置按钮的名字,方便知道是哪个按钮触发,并且传递角标
- jp2.add(buttons[i][j]);
- }
- }
- }
- //随机创建地雷,并算出每一个点应显示的周围地雷的个数
- private void createMines(){
- //通过该数组计算出地雷周围八个格子应该显示的数字
- int[][] dir = {{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}};
- numbers = new int[rows][cols];
- vis = new int[totalCounts];
- for(int i=0;i<vis.length;i++){
- boolean flag = true;
- int index = new Random().nextInt(rows*cols);
- for(int j=0;j<i;j++){
- if(vis[j]==index){
- flag = false;
- i--;
- break;
- }
- }
- if(flag){
- vis[i] = index;
- int x = index/cols;
- int y = index%cols;
- //本身是地雷,让数字等于地雷的总个数加1
- numbers[x][y] = totalCounts+1;
- for(int j=0;j<dir.length;j++){
- int realX = x+dir[j][0];
- int realY = y+dir[j][1];
- //如果这个点是有效的(没有出界)并且本身不是地雷
- if(realX>=0&&realX<rows&&realY>=0&&realY<cols&&numbers[realX][realY]<totalCounts+1)
- numbers[realX][realY]++;
- }
- }
- }
- createButtons();
- }
- //踩到地雷后,显示所有地雷
- private void showAllMine(){
- for(int i=0;i<vis.length;i++){
- int x = vis[i]/cols;
- int y = vis[i]%cols;
- ImageIcon icon = new ImageIcon("2.jpg");
- buttons[x][y].setIcon(icon);
- }
- }
- //当点击一个空白区域时,显示这一块不是地雷按钮
- private void showEmpty(int x,int y){
- buttons[x][y].setEnabled(false);
- buttons[x][y].setBackground(Color.GREEN);
- isclicked[x][y] = true;
- int[][] dir = {{0,-1},{-1,0},{0,1},{1,0}};
- for(int i=0;i<4;i++){
- int nextX = x+dir[i][0];
- int nextY = y+dir[i][1];
- //还没有被点过
- if(nextX>=0&&nextX<rows&&nextY>=0&&nextY<cols&&!isclicked[nextX][nextY]){
- if(numbers[nextX][nextY]==0){
- showEmpty(nextX,nextY);
- }
- else if(numbers[nextX][nextY]<=8){
- buttons[nextX][nextY].setText(numbers[nextX][nextY]+"");
- buttons[nextX][nextY].setBackground(Color.GREEN);
- }
- }
- }
- }
- //该线程用来计算使用时间
- @Override
- public void run() {
- time = 0;
- while(isOver){
- try {
- Thread.sleep(1000);//睡眠一秒钟
- time++;
- //System.out.println(time);
- showTime.setText("您已使用时间:"+time+"秒!");
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
- @Override
- public void actionPerformed(ActionEvent e) {
- //退出游戏
- if(e.getActionCommand().equals("exit")){
- System.exit(0);
- }
- //新游戏
- else if("newGame".equals(e.getActionCommand())){
- isOver = false;
- initGame(rows,cols,10);
- }
- else if("easy".equals(e.getActionCommand())){
- isOver = false;
- initGame(9,9,10);
- }
- else if("medium".equals(e.getActionCommand())){
- isOver = false;
- initGame(15,15,50);
- }
- else if("difficult".equals(e.getActionCommand())){
- isOver = false;
- initGame(22,22,100);
- }
- //游戏帮助
- else if("help".equals(e.getActionCommand())){
- String information = "尽快的找到游戏中所有布置的雷,这样你才能获取胜利!\n"
- +"记住,千万不要踩中地雷,否则您就输了!";
- JOptionPane.showMessageDialog(null,information);
- }
- }
- @Override
- public void mouseClicked(MouseEvent e) {
- //System.out.println(e.getModifiers());
- //如果已经猜中地雷了,再次点击按钮将不再触发事件
- if(!isOver)
- return;
- JButton source = (JButton) e.getSource();
- String[] infos = source.getName().split(" ");
- int x = Integer.parseInt(infos[0]);
- int y = Integer.parseInt(infos[1]);
- if(e.getModifiers()==MouseEvent.BUTTON1_MASK){
- isclicked[x][y] = true;//该按钮已被点击过
- if(numbers[x][y]==totalCounts+1){
- showAllMine();
- isOver = false;//游戏结束
- JOptionPane.showMessageDialog(null, "你踩中地雷了,请重新开始!");
- return;
- }
- if(numbers[x][y]==0){
- showEmpty(x, y);
- return;
- }
- source.setBackground(Color.GREEN);
- source.setText(numbers[x][y]+"");
- //source.setEnabled(false);
- }else if(e.getModifiers()==MouseEvent.BUTTON3_MASK){
- //奇数次右键标记地雷
- if(!isclicked[x][y]){
- ImageIcon icon = new ImageIcon("1.png");
- source.setIcon(icon);
- clickCounts++;
- showMine.setText("你以标记地雷个数: "+clickCounts);
- if(numbers[x][y]==totalCounts+1){
- gaussCounts++;
- }
- if(gaussCounts==totalCounts){
- JOptionPane.showMessageDialog(null, "恭喜您赢啦!");
- }
- }
- //偶数次右键取消标记
- else{
- clickCounts--;
- showMine.setText("你以标记地雷个数: "+clickCounts);
- if(numbers[x][y]==totalCounts+1){
- gaussCounts--;
- }
- //去掉图标
- ImageIcon icon = new ImageIcon();
- source.setIcon(icon);
- }
- isclicked[x][y] = !isclicked[x][y];
- }
- }
- @Override
- public void mousePressed(MouseEvent e) {
- }
- @Override
- public void mouseReleased(MouseEvent e) {
- }
- @Override
- public void mouseEntered(MouseEvent e) {
- }
- @Override
- public void mouseExited(MouseEvent e) {
- }
- }
MineTest.java
- package www.waston;
- public class MineTest {
- public static void main(String[] args) {
- new MineFrame();
- }
- }
java实现简单扫雷游戏的更多相关文章
- JavaSwing 版本的简单扫雷游戏
JavaSwing 版本的简单扫雷游戏 一.扫雷游戏的基本规则 1.扫雷游戏分为初级.中级.高级和自定义四个级别. 单击游戏模式可以选择"初级"."中级".&q ...
- Java版的扫雷游戏源码
package com.xz.sl; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Container; i ...
- Java GUI 简单台球游戏模型
完成效果: 1 package com.neuedu.test; 2 3 import java.awt.Frame; 4 import java.awt.Graphics; 5 import jav ...
- 无聊的周末用Java写个扫雷小游戏
周末无聊,用Java写了一个扫雷程序,说起来,这个应该是在学校的时候,写会比较好玩,毕竟自己实现一个小游戏,还是比较好玩的.说实话,扫雷程序里面核心的东西,只有点击的时候,去触发更新数据这一步. Sw ...
- Java练习(模拟扫雷游戏)
要为扫雷游戏布置地雷,扫雷游戏的扫雷面板可以用二维int数组表示.如某位置为地雷,则该位置用数字-1表示, 如该位置不是地雷,则暂时用数字0表示. 编写程序完成在该二维数组中随机布雷的操作,程序读入3 ...
- java实现简单窗体小游戏----球球大作战
java实现简单窗体小游戏----球球大作战需求分析1.分析小球的属性: 坐标.大小.颜色.方向.速度 2.抽象类:Ball 设计类:BallMain—创建窗体 BallJPanel—画小 ...
- Java实现 LeetCode 529 扫雷游戏(DFS)
529. 扫雷游戏 让我们一起来玩扫雷游戏! 给定一个代表游戏板的二维字符矩阵. 'M' 代表一个未挖出的地雷,'E' 代表一个未挖出的空方块,'B' 代表没有相邻(上,下,左,右,和所有4个对角线) ...
- 【Android】自己动手做个扫雷游戏
1. 游戏规则 扫雷是玩法极其简单的小游戏,点击玩家认为不存在雷的区域,标记出全部地雷所在的区域,即可获得胜利.当点击不包含雷的块的时候,可能它底下存在一个数,也可能是一个空白块.当点击中有数字的块时 ...
- 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 ...
随机推荐
- Scrum 团队成立 -- 软件工程
团队项目选题 : 金融工具:复利计算与投资记录项目继续升级,开发定位明确.功能专注的工具类软件 团队队员 : 蔡舜 , 林宇粲 , 王昕明 , 卢晓洵 团队目标 : 不断完善 团队口号 : 永不 ...
- 20172325 2017-2018-2 《Java程序设计》第九周学习总结
20172325 2017-2018-2 <Java程序设计>第九周学习总结 教材学习内容总结 异常 1.学习了异常的基本概念: 2.区分异常与错误: 一个异常是指一个定义非正常情况或错误 ...
- [Selenium] CSS3 选择器
在 CSS 中,选择器是一种模式,用于选择需要添加样式的元素. "CSS" 列指示该属性是在哪个 CSS 版本中定义的.(CSS1.CSS2 还是 CSS3.) 选择器 例子 例子 ...
- Jmeter运行过程中如何让Fiddler同时可以抓获到服务器的应答报文
在默认情况下,Jmeter运行过程中,Fiddler是抓不到对应的应答报文的. 但是,在某些时候,我们希望分析Jmeter执行失败的原因,想了解Jmeter获取到的应答报文是否有问题,就需要同服务器返 ...
- c++11多线程学习笔记之三 condition_variable使用
从windows角度来说,condition_variable类似event. 阻塞等待出发,不过condition_variable可以批量出发. 代码如下: // 1111111.cpp : 定义 ...
- hadoop 学习(二)ubuntu hadoop 2.7.0 伪分部安装
本篇是基于上一篇,ubuntu 安装hadoop单机版基础上的 1.配置core-site.xml /usr/local/hadoop/etc/hadoop/core-site.xml 包含了hado ...
- 利用windows.h头文件写一个简单的C语言倒计时
今天写一个简单的倒计时函数 代码如下: #include<stdio.h> #include<windows.h> int main() { int i; printf(&qu ...
- 2018.09.29 bzoj3675: [Apio2014]序列分割(斜率优化dp)
传送门 斜率优化dp经典题目. 首先需要证明只要选择的K个断点是相同的,那么得到的答案也是相同的. 根据分治的思想,我们只需要证明有两个断点时成立,就能推出K个断点时成立. 我们设两个断点分成的三段连 ...
- 2018.09.10 bzoj1499: [NOI2005]瑰丽华尔兹(单调队列优化dp)
传送门 单调队列优化dp好题. 这题其实很简单. 我们很容易想到一个O(T∗n∗m)" role="presentation" style="position: ...
- git分支删除
1.列出本地分支: git branch 2.删除本地分支: git branch -D BranchName 其中-D也可以是--delete,如: git branch --delete Bran ...