掃雷遊戲製作學習過程
阿新 • • 發佈:2022-05-05
1. 掃雷遊戲的構思: 設計為初級,中級,高階三個級別。
因此不妨設定為如下規格: 9x9 16x15和30x16 (行,列)規格不同地雷的數量也不同,分別為 10,40 ,99
2.在這個過程遇到了按鈕大小調整呼叫這些函式:
1 btn.setBounds(x,y,width,height);//設定大小並定位 2 或者 3 btn.setSize(width,height);//設定大小 4 btn.setLocation(x,y);//定位 5 6 父容器的layout要設定為null】 /*1。按鈕之間的設定問題,如何解決? 呼叫函式: public void setMargin(Insets m)設定按鈕邊框和標籤之間的空白。將該空白設定為 null 會造成按鈕使用預設空白。按鈕的預設 Border 物件將使用該值來建立適當的空白。不過,如果在按鈕上設定非預設邊框,則由 Border 物件負責建立適當的空白(否則此屬性將被忽略)。 引數: m - 邊框和標籤之間的間隔
製作到這預設框架已經搭建好了,並附上劣質程式碼來加以顯示:
程式碼如下:
竹類:
1 package Scan_boobs;
2
3 public class Main {
4 static public void main(String args[] )
5 {
6 new window_scan();
7 }
8 }
框架類:
1 /*掃雷預設為9x9的方格 2 * */ 3 package Scan_boobs; 4 import java.awt.*; 5 import javax.swing.*; 6 7 import java.awt.BorderLayout; 8 import java.awt.FlowLayout ; 9 import java.awt.Container ; 10 import java.awt.Font; 11 import java.awt.Insets; 12 import java.awt.event.ActionEvent; 13 import java.awt.event.ActionListener; 14 15 import javax.swing.JPanel ; 16 public class window_scan extends JFrame implements ActionListener 17 { 18 19 private static final long serialVersionUID = 1L; 20 private final int row =9; 21 private final int cow =9; 22 JFrame wind ; 23 JMenuBar myMenubar; //選單條 24 JMenu Menu []; //選單 25 JMenuItem [] Submenu ; //子選單 26 JButton mybutton; //開始按鈕 27 JButton [] grid_button ; //掃雷裡面的按鈕 28 Container mycontainer; 29 /* 30 * 新增到容器中的元件放在一個列表中。列表的順序 31 * 將定義元件在容器內的正向堆疊順序。如果將元件 32 * 新增到容器中時未指定索引,則該索引將被新增到列表尾部 33 * (此後它位於堆疊順序的底部)。 34 * */ 35 JPanel jpanel,jpanel1,jpanel2,jpamel3; /*JPanel 是一般輕量級容器。*/ 36 /* 37 * 設定三個等級,初級,中級,高階 38 */ 39 window_scan() 40 { 41 setTitle("掃雷"); 42 setVisible(true); //設定視窗是否可見 43 setResizable(false); //大小不可更改 44 setBounds(400,100,400,500); //初始的位置(400,100),大小(400,500) 45 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 46 //初始 47 mycontainer=getContentPane(); //這個獲取目前的 48 init(); 49 } 50 void init() { 51 52 Submenu = new JMenuItem [3]; 53 Submenu[0]=new JMenuItem("初級"); 54 Submenu[1]=new JMenuItem("中級"); 55 Submenu[2]=new JMenuItem("高階"); 56 Menu = new JMenu [2]; 57 Menu[0]= new JMenu("設定"); 58 for(int i=0;i<3;i++) 59 { 60 Submenu[i].addActionListener(this); //監聽 61 Menu[0].add(Submenu[i]); 62 } 63 mybutton=new JButton("開始"); //開始按鈕 64 mybutton.addActionListener(this); 65 Menu[1]= new JMenu("幫助"); 66 Menu[1].addActionListener(this); 67 myMenubar =new JMenuBar(); 68 //setJMenuBar(myMenubar); //設定此窗體的選單欄 69 jpanel= new JPanel(); 70 jpanel.add(myMenubar); 71 myMenubar.add(Menu[0]); 72 myMenubar.add(Menu[1]); 73 jpanel1 = new JPanel(); 74 jpanel1.setLayout(new BorderLayout()); //設定佈局 75 jpanel1.add(jpanel,BorderLayout.NORTH); 76 jpanel1.add(mybutton,BorderLayout.CENTER); 77 //設定雷區域 78 jpanel2 = new JPanel(); 79 jpanel2.setLayout(new GridLayout(row,cow,0,0)); //網格佈局 80 grid_button = new JButton [row*cow]; 81 for(int i=0; i<row*cow ; i++) 82 { 83 grid_button[i] = new JButton(""); 84 grid_button[i].setMargin(new Insets(0, 0, 0, 0)); 85 /* 86 *象是容器邊界的表示形式。它指定容器必須在 87 *其各個邊緣留出的空間。這個空間可以是邊界、 88 *空白空間或標題。 89 * */ 90 grid_button[i].setFont(new Font(null,Font.BOLD,25));//設定此容器的字型 91 grid_button[i].addActionListener(this); //行為監視容器 92 grid_button[i].addMouseListener(new MyMouseEvent()); 93 jpanel2.add(grid_button[i]); 94 } 95 mycontainer.add(jpanel1,BorderLayout.NORTH); 96 mycontainer.add(jpanel2,BorderLayout.CENTER); 97 98 } 99 @Override 100 public void actionPerformed(ActionEvent e) { 101 // TODO Auto-generated method stub 102 103 } 104 } 105
訊息對映類:
程式碼:
1 package Scan_boobs; 2 3 import java.awt.event.MouseEvent; 4 import java.awt.event.MouseListener; 5 6 public class MyMouseEvent implements MouseListener { 7 8 @Override 9 public void mouseClicked(MouseEvent e) { 10 // TODO Auto-generated method stub 11 12 } 13 14 @Override 15 public void mouseEntered(MouseEvent e) { 16 // TODO Auto-generated method stub 17 18 } 19 20 @Override 21 public void mouseExited(MouseEvent e) { 22 // TODO Auto-generated method stub 23 24 } 25 26 @Override 27 public void mousePressed(MouseEvent e) { 28 // TODO Auto-generated method stub 29 30 } 31 32 @Override 33 public void mouseReleased(MouseEvent e) { 34 // TODO Auto-generated method stub 35 36 } 37 38 }
下面開始匯入演算法部分:
(1)演算法一: 佈雷的思路:
(2 )演算法二: 挖雷的思路:
設定為5中狀態: 0,1,2,3,4;
抽象出來就是,開啟一個格子,如果裡邊的數字是0(周圍沒有雷)的話,就開啟周圍的8個格子,並繼續搜尋開啟的8個格子中是否有0,如果有就重複...直到開啟一片為0的區域(如果存在的話)。
學習知識點:
注意一點: java中 1無法等同與true
Math.random():產生一個[0,1)之間的隨機數。
暫且做到這個地方:
程式碼:
1 package Scan_boobs;
2
3 public class Main
4 {
5 static public void main(String args[] )
6 {
7 new window_scan();
8 }
9 }
1 /*掃雷預設為9x9的方格
2 * */
3 package Scan_boobs;
4 import java.awt.*;
5 import javax.swing.*;
6
7 import java.awt.BorderLayout;
8 import java.awt.FlowLayout ;
9 import java.awt.Container ;
10 import java.awt.Font;
11 import java.awt.Insets;
12 import java.awt.event.ActionEvent;
13 import java.awt.event.ActionListener;
14 import javax.swing.JPanel ;
15 public class window_scan extends JFrame implements ActionListener
16 {
17
18 private static final long serialVersionUID = 1L;
19 public static int row =9;
20 public static int cow =9;
21 JFrame wind ;
22 JMenuBar myMenubar; //選單條
23 JMenu Menu []; //選單
24 JMenuItem [] Submenu ; //子選單
25 JButton mybutton; //開始按鈕
26 public static JButton [] grid_button ; //掃雷裡面的按鈕
27 Container mycontainer;
28 public static int [][] array; //相應格子的狀態
29 public static int [] boombs; //炸彈的位置
30 public static int boombs_number ; //炸彈的數量
31
32 /*
33 * 新增到容器中的元件放在一個列表中。列表的順序
34 * 將定義元件在容器內的正向堆疊順序。如果將元件
35 * 新增到容器中時未指定索引,則該索引將被新增到列表尾部
36 * (此後它位於堆疊順序的底部)。
37 * */
38
39 JPanel jpanel,jpanel1,jpanel2,jpamel3; /*JPanel 是一般輕量級容器。*/
40
41 /*
42 * 設定三個等級,初級,中級,高階
43 */
44
45 window_scan()
46 {
47 setTitle("掃雷");
48 setVisible(true); //設定視窗是否可見
49 setResizable(false); //大小不可更改
50 setBounds(400,100,400,500); //初始的位置(400,100),大小(400,500)
51 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
52 //初始
53 mycontainer=getContentPane(); //這個獲取目前的
54 wind_init();
55 }
56
57 void wind_init() {
58
59 Submenu = new JMenuItem [3];
60 Submenu[0]=new JMenuItem("初級");
61 Submenu[1]=new JMenuItem("中級");
62 Submenu[2]=new JMenuItem("高階");
63 Menu = new JMenu [2];
64 Menu[0]= new JMenu("設定");
65 for(int i=0;i<3;i++)
66 {
67 Submenu[i].addActionListener(this); //監聽
68 Menu[0].add(Submenu[i]);
69 }
70 mybutton=new JButton("開始"); //開始按鈕
71 mybutton.addActionListener(this);
72 Menu[1]= new JMenu("幫助");
73 Menu[1].addActionListener(this);
74 myMenubar =new JMenuBar();
75 //setJMenuBar(myMenubar); //設定此窗體的選單欄
76 jpanel= new JPanel();
77 jpanel.add(myMenubar);
78 myMenubar.add(Menu[0]);
79 myMenubar.add(Menu[1]);
80 jpanel1 = new JPanel();
81 jpanel1.setLayout(new BorderLayout()); //設定佈局
82 jpanel1.add(jpanel,BorderLayout.NORTH);
83 jpanel1.add(mybutton,BorderLayout.CENTER);
84 grid_button(9,9,0); //初始炸彈設定為〇
85 mycontainer.add(jpanel1,BorderLayout.NORTH);
86 }
87
88 @Override
89 public void actionPerformed(ActionEvent e) {
90 // TODO Auto-generated method stub
91 if(e.getActionCommand()=="初級")
92 {
93 row=cow=9;
94 array = new int [row][cow] ; //設定陣列大小
95 //撤銷原先的按鈕分佈使其失效
96 this.remove(jpanel2);
97 grid_button(row,cow,10);
98 this.pack();
99 //初始化狀態
100 this.init(row,cow);
101 }
102 else if(e.getActionCommand()=="中級")
103 {
104 row=16;
105 cow=15;
106 array =new int [row][cow];
107 this.remove(jpanel2);
108 grid_button(row,cow,40);
109 this.pack();
110 //初始化狀態
111 this.init(row,cow);
112 }
113 else if(e.getActionCommand()=="高階")
114 {
115 row=30;
116 cow=16;
117 array=new int [row+2][cow+2];
118 this.remove(jpanel2);
119 grid_button(row,cow,40);
120 this.pack();
121 //初始化狀態
122 this.init(row,cow);
123 }
124 if(e.getSource()==mybutton) //點選了開始按鈕
125 {
126
127
128 this.init(row,cow);
129 //設定炸彈隨機安放---->這裡需要考慮的是產生不同數字
130
131 boolean [] check_position= new boolean [row*cow+3];
132 for(int i=0; i<boombs_number; i++)
133 {
134 while(true)
135 {
136 int temp_val=(int)(Math.random()*(row*cow)); //[0,1]*(row*cow);
137 if(check_position[temp_val]==false)
138 {
139 check_position[temp_val]=true;
140 boombs[i]=temp_val;
141 break;
142 }
143 }
144 }
145 //安裝炸彈,哇咔咔,果然想想都很有趣...........
146 //首先轉化為x,y的座標
147 int x,y;
148 for(int i=0;i<boombs_number; i++){
149 x=boombs[i]/row;
150 y=boombs[i]%row;
151 array[x][y]=50; //將這個定義為炸彈的狀態
152 }
153 // for(int i=0;i<row+2;i++){
154 // for(int j=0;j<cow+2;j++){
155 // if(i==0||j==0||i==row+1||j==cow+1){
156 // array[i][j]=0;
157 // }
158 // }
159 // }
160
161 //參考別人的程式碼,實在是有點想不到這個演算法怎麼弄,思密達
162 for(int i=1;i<=row;i++)
163 {
164 for(int j=1;j<=cow;j++)
165 {
166 if(array[i][j]!=50)
167 {
168 for(int l=j-1;l<=j+1;l++)
169 {
170 if(array[i-1][l]==50) array[i][j]++;
171 if(array[i+1][l]==50) array[i][j]++;
172 }
173 if(array[i][j-1]==50) array[i][j]++;
174 if(array[i][j+1]==50) array[i][j]++;
175 }
176 }
177 }
178 }
179 for(int i=0;i<cow*row;i++){
180 if(grid_button[i].getText()!="★")
181 {
182 int x=i/cow+1;
183 int y=i%cow+1;
184 if(e.getSource()==grid_button[i]&&array[x][y]==100){
185 grid_button[i].setText("★");
186 grid_button[i].setEnabled(false);
187 array[x][y]=10;
188 for(int k=0;k<cow*row;k++){
189 int m1=k/cow+1;
190 int n1=k%cow+1;
191 if(array[m1][n1]!=10&&grid_button[k].getText()=="★"){
192 grid_button[k].setText("*o*");
193 }
194 }
195 for(int j=0;j<cow*row;j++){
196 int m=j/cow+1;
197 int n=j%cow+1;
198 if(array[m][n]==100){
199 grid_button[j].setText("★");
200 grid_button[j].setEnabled(false);
201 }
202 grid_button[j].setEnabled(false);
203 array[m][n]=10;
204 }
205 }
206 else if(e.getSource()==grid_button[i]){
207 if(array[x][y]==0){
208 wa_lei(array,grid_button,e,i,x,y);
209 array[x][y]=10;
210 grid_button[i].setEnabled(false);
211 }
212 if(array[x][y]!=0&&array[x][y]!=10){
213 grid_button[i].setText(array[x][y]+"");
214 grid_button[i].setEnabled(false);
215 array[x][y]=10;
216 }
217 }
218 }else if(grid_button[i].getText()=="★"){
219 }
220 }
221 }
222 /*************佈置按鈕方法**************************/
223 public void grid_button(int row ,int cow ,int boombs_number)
224 {
225 //設定雷區域
226 jpanel2 = new JPanel();
227 jpanel2.setLayout(new GridLayout(row,cow,0,0)); //網格佈局
228 grid_button = new JButton [row*cow];
229 boombs =new int [boombs_number];
230 for(int i=0; i<row*cow ; i++)
231 {
232 grid_button[i] = new JButton(" "); //有點空格將按鈕弄大些
233 grid_button[i].setMargin(new Insets(0, 0, 0, 0));
234 /*
235 *象是容器邊界的表示形式。它指定容器必須在
236 *其各個邊緣留出的空間。這個空間可以是邊界、
237 *空白空間或標題。
238 * */
239 grid_button[i].setFont(new Font(null,Font.BOLD,25));//設定此容器的字型
240 grid_button[i].addActionListener(this); //行為監視容器
241 grid_button[i].addMouseListener(new MyMouseEvent());
242 // grid_button[i].setText("");
243 // grid_button[i].setEnabled(true);
244 jpanel2.add(grid_button[i]);
245 }
246 mycontainer.add(jpanel2,BorderLayout.CENTER);
247 }
248 /***************初始化狀態****************/
249 public void init(int row,int cow)
250 {
251 for(int i=0;i<row+2;i++){
252 for(int j=0;j<cow+2;j++){
253 array[i][j]=0;
254 }
255 }
256 for(int i=0;i<cow*row;i++){
257 grid_button[i].setText("");
258 grid_button[i].setEnabled(true);
259 }
260 }
261 public void wa_lei(int[][] a,JButton[] btns,ActionEvent e,int i,int x,int y){
262 int p=1;
263 if(a[x][y]==0){
264 a[x][y]=10;
265 btns[i].setEnabled(false); //33
266 for(int l=y-1;l<=y+1;l++){
267 int m=x-1-1;
268 int n=l-1;
269 p=1;
270 System.out.println(a[1][2]);
271 if(n>-1&&n<cow&&m>-1&&m<row)
272 {
273 for(int q=0;q<row&&p==1;q++){//cow-->row;
274 if(((n+cow*q)>=(m*cow))&&((n+cow*q)<(m+1)*cow)){
275 if(a[x-1][l]!=0&&a[x-1][l]!=10){
276 btns[n+cow*q].setText(a[x-1][l]+"");
277 a[x-1][l]=10;
278 btns[n+cow*q].setEnabled(false);
279 }
280 else if(a[x-1][l]==0){
281 //a[x-1][l]=10;
282 btns[n+cow*q].setEnabled(false);
283 wa_lei(a,btns,e,n+cow*q,x-1,l); ////55////
284 a[x-1][l]=10;
285 btns[n+cow*q].setEnabled(false);
286 }
287 p=0;
288
289 }
290 }
291 }
292 p=1;
293 m=x;
294 if(n>-1&&n<cow&&m>-1&&m<cow)
295 {
296 for(int q=0;q<row&&p==1;q++){
297 if(((n+cow*q)>=(m*cow))&&((n+cow*q)<(m+1)*cow)){
298 if(a[x+1][l]!=0&&a[x+1][l]!=10){
299 btns[n+cow*q].setText(a[x+1][l]+"");
300 a[x+1][l]=10;
301 btns[n+cow*q].setEnabled(false);
302 }
303 else if(a[x+1][l]==0){
304
305 wa_lei(a,btns,e,n+cow*q,x+1,l);///55////
306 a[x+1][l]=10;
307 btns[n+cow*q].setEnabled(false);
308 }
309 p=0;
310 }
311 }
312
313 }
314 }
315 int m=x-1;
316 int n=y-1-1;
317 p=1;
318 if(n>-1&&n<cow&&m>-1&&m<cow)
319 {
320 for(int q=0;q<row&&p==1;q++){
321 if(((n+cow*q)>=(m*cow))&&((n+cow*q)<(m+1)*cow)){
322 if(a[x][y-1]!=0&&a[x][y-1]!=10){
323 btns[n+cow*q].setText(a[x][y-1]+"");
324 a[x][y-1]=10;
325 btns[n+cow*q].setEnabled(false);
326 }
327 else if(a[x][y-1]==0){
328
329
330 wa_lei(a,btns,e,n+cow*q,x,y-1);
331
332 a[x][y-1]=10;
333 btns[n+cow*q].setEnabled(false);
334 }
335 p=0;
336 }
337 }
338 }
339 p=1;
340 m=x-1;
341 n=y+1-1;
342 if(n>-1&&n<cow&&m>-1&&m<cow)
343 {
344 for(int q=0;q<row&&p==1;q++){
345 if(((n+cow*q)>=(m*cow))&&((n+cow*q)<(m+1)*cow)){
346 if(a[x][y+1]!=0&&a[x][y+1]!=10){
347 btns[n+cow*q].setText(a[x][y+1]+"");
348 a[x][y+1]=10;
349 btns[n+cow*q].setEnabled(false);
350 }
351 else if(a[x][y+1]==0){
352 wa_lei(a,btns,e,n+cow*q,x,y+1);
353 a[x][y+1]=10;
354 btns[n+cow*q].setEnabled(false);
355 }
356 p=0;
357 }
358 }
359 }
360 }
361
362 }
363
364 }
1 package Scan_boobs;
2
3 import java.awt.event.MouseEvent;
4 import java.awt.event.MouseListener;
5
6 public class MyMouseEvent implements MouseListener {
7 @Override
8 public void mouseClicked(MouseEvent e) {
9 // TODO Auto-generated method stub
10 for(int i=0;i<window_scan.cow*window_scan.row;i++){
11 int x1=i/window_scan.cow+1;
12 int y1=i%window_scan.cow+1;
13 if(e.getSource()==window_scan.grid_button[i]&&window_scan.grid_button[i].getText()!="★"&&window_scan.array[x1][y1]!=10)
14 {
15 if(e.getButton()==MouseEvent.BUTTON3){
16 window_scan.grid_button[i].setText("★");
17 window_scan.boombs_number--;
18 if(window_scan.boombs_number==0){
19 int flag=0;
20 for(int j=0;j<window_scan.cow*window_scan.row;j++){
21 int x=j/window_scan.cow;
22 int y=j%window_scan.cow;
23 if(window_scan.array[x][y]==100&&window_scan.grid_button[j].getText()=="★"){
24 flag++;
25 }
26 }
27 }
28 }
29 }
30
31 else
32 if(e.getSource()==window_scan.grid_button[i]&&window_scan.grid_button[i].getText()=="★"&&window_scan.array[x1][y1]!=-1){
33 if(e.getButton()==MouseEvent.BUTTON3){
34 window_scan.grid_button[i].setText("");
35 window_scan.boombs_number++;
36 window_scan.grid_button[i].setEnabled(true);
37 }
38 }
39 }
40
41 }
42
43 @Override
44 public void mouseEntered(MouseEvent e) {
45 // TODO Auto-generated method stub
46
47 }
48
49 @Override
50 public void mouseExited(MouseEvent e) {
51 // TODO Auto-generated method stub
52
53 }
54
55 @Override
56 public void mousePressed(MouseEvent e) {
57 // TODO Auto-generated method stub
58
59 }
60
61 @Override
62 public void mouseReleased(MouseEvent e) {
63 // TODO Auto-generated method stub
64
65 }
66
67 }