Java Swing实现扫雷源码
作者:掉队洋先生 发布时间:2023-11-10 08:16:20
标签:Java,Swing,扫雷
本文实例为大家分享了Java Swing实现扫雷源码的具体代码,供大家参考,具体内容如下
先来看下效果
运行时只需要创建一个GameWindow的对象即可,可使用有参构造函数自定义雷区行列数及 * 个数,也可使用无参构造函数设置默认值(小旗和 * 的图标自己去找吧,我就不在这里放了)
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.LinkedList;
public class GameWindow{
private static Font labelFont = new Font("隶书",Font.BOLD,45);
private static Font buttonFont = new Font("隶书",Font.CENTER_BASELINE,20);
private static Icon flag = new ImageIcon("src/images/小旗.jpg");//小旗图标
private static Icon bomb = new ImageIcon("src/images/ * .png");// * 图标
private static int labelWeight = 30;//小方块(雷区)宽度
private static int labelHeigth = 30;//小方块(雷区)高度
private static int labelSpace = 1;//小方块(雷区)间距
private static int scoreHeight = 50;//积分区域高度
private static int[] x8 = {-1,-1,-1,0,0,1,1,1};//原坐标周围 8 个坐标的 x 值变化
private static int[] y8 = {-1,0,1,-1,1,-1,0,1};//原坐标周围 8 个坐标的 y 值变化
private static int[] x4 = {0,0,1,-1};//原坐标周围 4 个坐标的 x 值变化
private static int[] y4 = {1,-1,0,0};//原坐标周围 4 个坐标的 x 值变化
private JFrame frame;
private int[][] data;//存储和 * 位置有关数据,值为-1时表示 *
private JLabel[][] labels;
private JPanel mainPanel;//雷区主面板
private JPanel scorePanel;//积分区域面板
private JLabel areaLabel;//未扫雷区个数标签
private JLabel bombLabel;//剩余地雷数标签
private int width;//窗体宽度
private int height;//窗体高度
private int row;//行数
private int column;//列数
private int bombNum;// * 个数
private int remainArea;//未扫雷区个数
private int remainBomb;//剩余地雷数
public GameWindow(int row,int column,int bombNum){
frame = new JFrame("扫雷-洋仔小游戏");
this.row = row;
this.column = column;
this.bombNum = bombNum;
mainPanel = new JPanel();
init();
}
public GameWindow(){
this(10,10,20);
}
private void setWidthAndHeight(){
width = labelWeight * column + (column + 1) * labelSpace;
height = scoreHeight + labelHeigth * row + (row + 1) * labelSpace;
}
private void setBomb(){
if(bombNum > row * column)
throw new RuntimeException(" * 数设置过多!");
data = new int[row][column];
int count = 0;
while (count < bombNum){
int r = (int)(Math.random() * row);
int c = (int)(Math.random() * column);
System.out.println("r = " + r + "\tc = " + c);
if(data[r][c] == -1)
continue;
data[r][c] = -1;
for(int i = 0; i < 8; i ++){
int x = r + x8[i];
int y = c + y8[i];
if(x < 0 || x >= row || y < 0 || y >= column || data[x][y] == -1)
continue;
data[r + x8[i]][c + y8[i]] ++;
}
count ++;
System.out.println(count);
}
}
private class ButtonListener extends MouseAdapter {
private JButton button;
private int r;
private int w;
private GameWindow window;
private boolean disabled = true;
public ButtonListener(JButton button,int r,int w,GameWindow window){
this.button = button;
this.r = r;
this.w = w;
this.window = window;
}
@Override
public void mouseClicked(MouseEvent mouseEvent) {
synchronized (window){
if(!button.isEnabled())
return;
if(mouseEvent.getButton() == MouseEvent.BUTTON3){
if(disabled) {
button.setIcon(flag);
data[r][w] -= 20;
remainBomb --;
remainArea --;
}
else {
button.setIcon(null);
data[r][w] += 20;
remainBomb ++;
remainArea ++;
}
disabled = !disabled;
bombLabel.setText("" + remainBomb);
areaLabel.setText("" + remainArea);
return;
}
if(!disabled)
return;
int cnt = 1;
button.setVisible(false);
if(data[r][w] == -1){
gameOver();
// System.out.println("\n点到 * ,全体按钮已禁用");
return;
}
LinkedList<int[]> stack = new LinkedList<>();
stack.push(new int[]{r,w});
data[r][w] = -1;
while (stack.size() > 0){
int[] source = stack.pop();
for(int i = 0; i < 4; i ++){
int x = source[0] + x4[i];
int y = source[1] + y4[i];
if(x < 0 || x >= row || y < 0 || y >= column || data[x][y] < 0)
continue;
if(data[x][y] == 0)
stack.push(new int[]{x,y});
labels[x][y].getLabelFor().setVisible(false);
cnt ++;
data[x][y] = -1;
}
}
remainArea -= cnt;
areaLabel.setText("" + remainArea);
if(remainArea == remainBomb){
gameOver();
}
}
}
}
private void gameOver(){
for(JLabel[] ls : labels){
for(JLabel l : ls){
JButton button = (JButton) l.getLabelFor();
button.setEnabled(false);
}
}
}
private void init(){
setWidthAndHeight();
frame.setBounds(380,100,width + 9,height + 32);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.setLayout(null);
mainPanel.setBackground(Color.GRAY);
mainPanel.setBounds(1,scoreHeight + 1,width,height);
mainPanel.setLayout(null);
scorePanel = new JPanel();
scorePanel.setBounds(0,0,width,scoreHeight);
scorePanel.setLayout(new GridLayout(1,3,0,0));
areaLabel = new JLabel();
areaLabel.setFont(labelFont);
areaLabel.setHorizontalAlignment(JLabel.CENTER);
scorePanel.add(areaLabel);
JLabel buttonLabel = new JLabel();
scorePanel.add(buttonLabel);
JButton resetButton = new JButton("重开");
resetButton.setFont(buttonFont);
resetButton.setFocusPainted(false);
resetButton.setBounds(width/ 24,10,width / 4,30);
resetButton.addActionListener((event)->{
frame.setVisible(false);
mainPanel.removeAll();
resetGame();
});
buttonLabel.add(resetButton);
bombLabel = new JLabel();
bombLabel.setFont(labelFont);
bombLabel.setHorizontalAlignment(JLabel.CENTER);
scorePanel.add(bombLabel);
frame.add(scorePanel);
frame.add(mainPanel);
resetGame();
}
public void resetGame(){
setBomb();
remainArea = row * column;
remainBomb = bombNum;
labels = new JLabel[row][column];
System.gc();
for(int i = 0; i < row; i ++){
for(int j = 0; j < column; j ++){
labels[i][j] = new JLabel();
//设置元素居中
labels[i][j].setHorizontalAlignment(JLabel.CENTER);
if(data[i][j] == -1) {
labels[i][j].setIcon(bomb);
}
else if(data[i][j] > 0)
labels[i][j].setText("" + data[i][j]);
int y = (i + 1) * labelSpace + i * labelWeight;
int x = (j + 1) * labelSpace + j * labelHeigth;
labels[i][j].setBounds(x,y,labelWeight,labelHeigth);
JButton button = new JButton();
button.addMouseListener(new ButtonListener(button,i,j,this));
button.setBounds(0,0,labelWeight,labelHeigth);
labels[i][j].setLayout(null);
labels[i][j].add(button);
labels[i][j].setLabelFor(button);
mainPanel.add(labels[i][j]);
}
}
areaLabel.setText("" + remainArea);
bombLabel.setText("" + remainBomb);
frame.setVisible(true);
}
}
来源:https://blog.csdn.net/qq_46121425/article/details/122775637
0
投稿
猜你喜欢
- 上帝之火本系列讲述的是开源实时监控告警解决方案Prometheus,这个单词很牛逼。每次我都能联想到带来上帝之火的希腊之神,普罗米修斯。而这
- 最近要做一个网站,要求实现验证码程序,经过不断调试,终于成功实现功能。一、验证码生成类生成验证码的话需要用到java的Graphics类库,
- Android中的异步消息机制分为四个部分:Message、Handler、MessageQueue和Looper。其中,Message是线
- mysql实现配置中心本公司配置数据的管理是通过mysql进行配置管理,因为已经搭建好了,所以自己动手重新搭建一遍,熟悉整个流程。有关项目源
- GET请求不支持对象传参问题@GetMapping("/getByParam")String hello(Student
- 在类中自定义的“函数”称为“方法”,由于C#是完全面向对象的
- Java及数据库对日期进行格式化Java对日期进行格式化可使用java.text.SimpleDateFormat示例package com
- 最近几年玩得最疯狂的应该是发红包了,尤其是过年的时候特别受欢迎,下面写了红包的随机算法,其实挺简单的,仅是提供一种思路,希望可以给大家一些启
- 前言gps定位服务的学习是这段时间gps课程的学习内容,之前老师一直在将概念,今天终于是实践课(其实就是给了一个案例,让自己照着敲).不过在
- mybatis-plus自动配置mapper.xml与java接口映射本来没有mybatis-plus的话,这个工作是通过mybatis-s
- Java项目涉及到数据库交互,以往常用的是JDBC,现在则有Hibernate、Mybatis等这些持久化支持。项目中用到了MyBatis,
- Struts2是流行和成熟的基于MVC设计模式的Web应用程序框架。 Struts2不只是Struts1下一个版本,它是一个完全重写的Str
- 前言在原生的 Android 或 iOS 中,都提供了基本的键值对存储方式,Android 是 SharedPreferences,iOS
- 简介使用配置类和注解代替web.xml和SpringMVC配置文件的功能在Servlet3.0环境中,容器会在类路径中查找实现javax.s
- 字符, 字节与字符串字符与字符串字符串内部包含一个字符数组,String 可以和 char[] 相互转换.字符数组变为字符串:public
- @Order控制配置类/AOP/方法/字段的加载顺序1.AOP加载顺序 @Component &nbs
- 前言前面介绍了APP顶部导航栏AppBar,今天来介绍下Flutter实现APP底部导航栏。我们以仿写微信的底部导航栏来举例说明。要实现类似
- 对接前端后效果展示如图:1、CPU相关信息实体类/** * CPU相关信息 * * @author csp */public class
- 一、何为栈?栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称
- 在JAVA克隆对象不能简单的使用clone方法,clone方法只是进行浅克隆。请看下方:深度克隆类:Java代码 import java.i