Java基础,Java写一个简单的扫雷游戏

 2023-09-23 阅读 24 评论 0

摘要:〇、目录 一、前言 二、过程中遇到的困难 三、代码 四、成品图 五、代码存在的bug 六、完善建议 七、结语 一、前言 这个学期学习了Java,课程的最后一项作业就是做一个扫雷游戏和一个计算器,经历一段时间的煎熬终于做出来了,就想来分享一下我的喜悦和成果

〇、目录
一、前言
二、过程中遇到的困难
三、代码
四、成品图
五、代码存在的bug
六、完善建议
七、结语
一、前言
这个学期学习了Java,课程的最后一项作业就是做一个扫雷游戏和一个计算器,经历一段时间的煎熬终于做出来了,就想来分享一下我的喜悦和成果。

在老师布置作业后,我的计算器代码就根据老师黑板上代码微调后很快就收工了,而这个扫雷也是有了明确的思路,但是却找不到相对应的代码来实现,后来在百度上看了一位前辈的扫雷代码终于解决了我问题。这里是那位前辈的扫雷代码链接

Java基础、其实回过头来看,我写这个代码确实极其简陋,相比我在百度上找的各种大佬做出来的扫雷,感觉差距极大。但是想想是我自己做出来的还是很高兴的,但是也明白我还只是个小白。

二、过程中遇到的困难
老师一布置作业我就想出来了一个做法,那就是做两层组件,底层是label,可以用来显示数字和雷,如下图所示这样的效果,其中"!"表示随机生成的雷。
图1
再在这上面盖一层相同数量button组件,点击一个button,这个button就消失,显示出下层的label。

当我开始写代码时,我就卡在了这一步。我定义一个panel并设置了20*20的gridlayout(网格布局),当我添加进去400个label时,成功达到了上图的底层效果,但是当我再添加400个button时,就出现问题了,这个button不会重叠到label上面,而是继续向下排列,和label处于了同一层,然后百度了好久都没有解决问题,最后决定看看别人的代码是怎么做的。最后看了某位前辈的作品,原来他是清除了panel原有的layout,用坐标放置组件,这样就可以重叠了,于是后面我就很快的写好了。
(也许这个问题也有其他的解决方法,我感觉用gridlayout也可以做出的,知道怎么做的大佬可以说一下)

简单Java程序。三、代码
最重要的代码来了

package testone;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

java设计扫雷游戏代码,import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;

public class Try1 {
JFrame f;
JPanel p,p1,p2;
int n = 20; //扫雷正方形界面的的边长(只能手动修改控制难度)
int boomnumber = 50; //设置雷的个数(只能手动修改控制难度)后续可以添加按键修改难度
JButton zuobi,restart; //作弊和重新开始的按钮
JButton b[][] = new JButton[n][n];
JLabel l[][] = new JLabel[n][n]; //下层显示的label
int boxy[][]; //存储雷的横纵坐标的数组
int visited[][] = new int[n][n]; //被访问记录,访问过为1
Try1() {

	f = new JFrame("扫雷");f.setBounds(600, 200, 495, 545);p = new JPanel();    //扫雷游戏面板p.setLayout(null);   //清除原有的layout,后面使用坐标放置组件p1 = new JPanel();   //最底层面板p2 = new JPanel();   //放置功能按键的面板p1.setLayout(new BorderLayout());p2.setLayout(new GridLayout(1,3)); //网格布局,一行三列p.setBackground(new Color(193, 210, 240));makeboom(n, p);   //自己定义的函数,生成雷和数组label的makebutton(n, p); //生成扫雷按钮的,会覆盖在底层label上zuobi =new JButton("作弊");zuobi.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {for (int i[]:boxy) {b[i[0]][i[1]].setText(".");}}});restart = new JButton("重新开始"); restart.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {f.dispose();  //关闭new Try1();}});p1.add(p,BorderLayout.CENTER);p1.add(p2,BorderLayout.NORTH);p2.add(restart);p2.add(zuobi);f.add(p1);f.setVisible(true);f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}public void makebutton(int n, JPanel a) {for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++) {a.add(b[i][j] = new JButton());b[i][j].setBounds(j * 24, i * 24, 24, 24);b[i][j].addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {// TODO Auto-generated method stubJButton d = (JButton) e.getSource();int index = 0;int indey = 0;for (int i = 0; i < n; i++) { //获取点击的按钮的坐标for (int j = 0; j < n; j++) {if (d == b[i][j]) {index = i;indey = j;}}}open(index,indey);}});}}
}public void makeboom(int n, JPanel a) {boxy = boom(n, boomnumber);for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++) {l[i][j] = new JLabel("0", JLabel.CENTER);l[i][j].setBounds(j * 24, i * 24, 24, 24);l[i][j].setBorder(BorderFactory.createLineBorder(Color.GRAY));l[i][j].setOpaque(true);l[i][j].setVisible(false);a.add(l[i][j]);}}for (int i = 0; i < boomnumber; i++) {l[boxy[i][0]][boxy[i][1]].setText("!");visited[boxy[i][0]][boxy[i][1]] = 1;}setshuzi();for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++) {if(l[i][j].getText().equals("0")) {l[i][j].setText("");}}}
}public  int[][] boom(int n, int m) { // n是网格最大长宽,m是雷的个数int[][] boxy = new int[m][2];int cishu = 0;while (cishu != m) {int x = (int)(Math.random() * n);int y = (int)(Math.random() * n);if(isrepeat(x,y,boxy,cishu) == 0){boxy[cishu][0] = x;boxy[cishu][1] = y;cishu++;}}return boxy;
}public int isrepeat(int x, int y, int a[][], int cishu) {int is = 0;for (int i = 0; i < cishu; i++) {if (a[i][0] == x && a[i][1] == y) {is = 1;break;} else {is = 0;}}return is;
}public void setshuzi() {for (int[] i:boxy) {int x = i[0];int y = i[1];for(int u = x-1;u<x+2;u++) {for(int v = y-1;v<y+2;v++) {if(u>=0&&u<n&&v>=0&&v<n) {String s = l[u][v].getText();if(!s.equals("!")) {int lnumb = Integer.parseInt(s);lnumb ++;l[u][v].setText(lnumb+"");}}}}}
}public void open(int x,int y) {b[x][y].setVisible(false);l[x][y].setVisible(true);visited[x][y]=1;if(iswin()) {JOptionPane.showMessageDialog(null,"游戏获胜","游戏获胜",JOptionPane.PLAIN_MESSAGE);}else {if(l[x][y].getText().equals("!")) {JOptionPane.showMessageDialog(null,"您失败了","游戏结束",JOptionPane.PLAIN_MESSAGE);}else if(l[x][y].getText().equals("")){for(int u = x-1;u<x+2;u++) {for(int v = y-1;v<y+2;v++) {if(u>=0&&u<n&&v>=0&&v<n&&visited[u][v]!=1) {open(u,v);}}}}else {}}
}public boolean iswin() {int last =-1;for(int i[]:visited) {if(Arrays.binarySearch(i, 0)< 0) {last = 1;}else {//只要存在1个没有访问的,就判定没有赢,退出循环last = -1;break;}}if(last==1) {return true;}else {return false;}
}
public static void main(String[] args) {Try1 t = new Try1();
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
四、成品图
在这里插入图片描述

简单得Java,五、代码存在的bug
1.游戏获胜判断提前:
游戏获胜判断每次点击按钮都要判断的,如果所有的位置都被访问过即可获胜(其中生成雷的位置提在生成雷时编辑为访问过的状态),但是在还未全部点击的情况,就会提醒游戏获胜。
2.游戏失败还能继续游戏:
这个问题可以解决,但是由于本人太懒了没写,只要在踩雷后使所有button不可见即可。
3.未知…(等待读者发现)

六、完善建议
1.雷的颜色可以设置高亮颜色,踩雷后更醒目。
2.添加可控难度的按钮,可以放到菜单栏。
3.设置插旗子的功能。如果可以的话,最好用图片而不是字符。

七、结语
欢迎评论留言交流,有错误或者修改建议请评论留言,可能回复不及时请见谅。

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/2/91434.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息