本文實例為大家分享了java實現俄羅斯方塊的具體代碼,供大家參考,具體內容如下
俄羅斯方塊設計思想
俄羅斯方塊都從小玩到大吧,什么規則大家都知道了吧,以前感覺那玩意賊好玩,但是就是老贏不了,現在學會了自己寫一個天天練!
鍵盤操作:
左鍵:左移; 右鍵:右移;
上鍵:變換造型 下鍵:加速下掉(沒毛病吧,沒有繼續整)
任意一行的方塊滿格,這一行就消除,消除一行方塊得10分,目前小主我還沒有設置關卡,各位喜歡的寶寶們可以自己設置關卡哦;
那么那些方塊的造型到底從哪里來的呢,那就是我們自己設計的,常見的幾種造型就是:i型,t型,l型,田字格型等等吧,自己個加唄!
那么到底咋整的咧?其實啊就是一個4*4的數組,當然了你開心設計n*n也可以,你牛皮你說了算!
那么下面舉了一個例子,用來告訴你們為啥你們看見的造型可以變換的原因就是這樣提前設計好,0為空,1為填充格,這樣你就可以在你的游戲里面凹造型了!
算了:直接放圖先看代碼運行結果吧:
喜歡嗎?喜歡就直接做吧,可能代碼寫的不夠好,請各位大神多多包涵,我回頭也會多總結,會不斷更新代碼的;
gamepanel類:游戲界面類,整個方塊掉落和顯示,游戲的邏輯斯洛都在這個類里面實現;
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
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
|
package tetris; import java.awt.graphics; import java.awt.event.actionevent; import java.awt.event.actionlistener; import java.awt.event.keyevent; import java.awt.event.keylistener; import java.util.random; import javax.swing.joptionpane; import javax.swing.jpanel; import javax.swing.timer; public class gamepanel extends jpanel implements keylistener{ private int maprow = 21 ; private int mapcol = 12 ; private int mapgame[][] = new int [maprow][mapcol]; //開辟一個二維數組空間,用來存放我們的地圖信息 private timer timer; private int score = 0 ; //記錄成績 random random = new random(); private int curshapetype = - 1 ; private int curshapestate = - 1 ; //設置當前的形狀類型和當前的形狀狀態 private int nextshapetype = - 1 ; private int nextshapestate = - 1 ; //設置下一次出現的方塊組的類型和狀態 private int posx = 0 ; private int posy = 0 ; private final int shapes[][][] = new int [][][]{ //t字形按逆時針的順序存儲 { { 0 , 1 , 0 , 0 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }, { 0 , 1 , 0 , 0 , 1 , 1 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 }, { 1 , 1 , 1 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }, { 0 , 1 , 0 , 0 , 0 , 1 , 1 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 } }, //i字形按逆時針的順序存儲 { { 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }, { 0 , 1 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 1 , 0 , 0 }, { 0 , 0 , 0 , 0 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }, { 0 , 1 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 1 , 0 , 0 } }, //倒z形按逆時針的順序存儲 { { 0 , 1 , 1 , 0 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }, { 1 , 0 , 0 , 0 , 1 , 1 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 }, { 0 , 1 , 1 , 0 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }, { 1 , 0 , 0 , 0 , 1 , 1 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 } }, //z形按逆時針的順序存儲 { { 1 , 1 , 0 , 0 , 0 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }, { 0 , 1 , 0 , 0 , 1 , 1 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }, { 1 , 1 , 0 , 0 , 0 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }, { 0 , 1 , 0 , 0 , 1 , 1 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } }, //j字形按逆時針的順序存儲 { { 0 , 1 , 0 , 0 , 0 , 1 , 0 , 0 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 }, { 1 , 1 , 1 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }, { 1 , 1 , 0 , 0 , 1 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }, { 1 , 0 , 0 , 0 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } }, //l字形按逆時針的順序存儲 { { 1 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 }, { 0 , 0 , 1 , 0 , 1 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }, { 1 , 1 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 }, { 1 , 1 , 1 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } }, //田字形按逆時針的順序存儲 { { 1 , 1 , 0 , 0 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }, { 1 , 1 , 0 , 0 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }, { 1 , 1 , 0 , 0 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }, { 1 , 1 , 0 , 0 , 1 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } } }; private int rowrect = 4 ; private int colrect = 4 ; //這里我們把存儲的圖像看成是一個4*4的二維數組,雖然在上面我們采用一維數組來存儲,但實際還是要看成二維數組來實現 private int rectwidth = 10 ; public gamepanel() //構造函數----創建好地圖 { createrect(); initmap(); //初始化這個地圖 setwall(); //設置墻 // createrect(); timer = new timer( 500 , new timerlistener()); timer.start(); } class timerlistener implements actionlistener{ public void actionperformed(actionevent e) { movedown(); } } public void setwall() //第0列和第11列都是墻,第20行也是墻 { for ( int i = 0 ; i < maprow; i++) //先畫列 { mapgame[i][ 0 ] = 2 ; mapgame[i][ 11 ] = 2 ; } for ( int j = 1 ; j < mapcol- 1 ; j++) //畫最后一行 { mapgame[ 20 ][j] = 2 ; } } public void initmap() //初始化這個地圖,墻的id是2,空格的id是0,方塊的id是1 { for ( int i = 0 ; i < maprow; i++) { for ( int j = 0 ; j < mapcol; j++) { mapgame[i][j] = 0 ; } } } public void createrect() //創建方塊---如果當前的方塊類型和狀態都存在就設置下一次的,如果不存在就設置當前的并且設置下一次的狀態和類型 { if (curshapetype == - 1 && curshapestate == - 1 ) //當前的方塊狀態都為1,表示游戲才開始 { curshapetype = random.nextint(shapes.length); curshapestate = random.nextint(shapes[ 0 ].length); } else { curshapetype = nextshapetype; curshapestate = nextshapestate; } nextshapetype = random.nextint(shapes.length); nextshapestate = random.nextint(shapes[ 0 ].length); posx = 0 ; posy = 1 ; //墻的左上角創建方塊 if (gameover(posx,posy,curshapetype,curshapestate)) { joptionpane.showconfirmdialog( null , "游戲結束!" , "提示" , joptionpane.ok_option); system.exit( 0 ); } } public boolean gameover( int x, int y, int shapetype, int shapestate) //判斷游戲是否結束 { if (isornomove(x,y,shapetype,shapestate)) { return false ; } return true ; } public boolean isornomove( int x, int y, int shapetype, int shapestate) //判斷當前的這個圖形是否可以移動,這里重點強調x,y的坐標是指4*4的二維數組(描述圖形的那個數組)的左上角目標 { for ( int i = 0 ; i < rowrect ; i++) { for ( int j = 0 ; j < colrect; j++) { if (shapes[shapetype][shapestate][i*colrect+j] == 1 && mapgame[x+i][y+j] == 1 || shapes[shapetype][shapestate][i*colrect+j] == 1 && mapgame[x+i][y+j] == 2 ) { return false ; } } } return true ; } public void turn() //旋轉 { int temp = curshapestate; curshapestate = (curshapestate+ 1 ) % shapes[ 0 ].length; if (isornomove(posx,posy,curshapetype,curshapestate)) { } else { curshapestate = temp; } repaint(); } public void movedown() //向下移動 { if (isornomove(posx+ 1 ,posy,curshapetype,curshapestate)) { posx++; } else { addtomap(); //將此行固定在地圖中 checkline(); createrect(); //重新創建一個新的方塊 } repaint(); } public void moveleft() //向左移動 { if (isornomove(posx,posy- 1 ,curshapetype,curshapestate)) { posy--; } repaint(); } public void moveright() //向右移動 { if (isornomove(posx,posy+ 1 ,curshapetype,curshapestate)) { posy++; } repaint(); } public void addtomap() //固定掉下來的這一圖像到地圖中 { for ( int i = 0 ; i < rowrect; i++) { for ( int j = 0 ; j < colrect; j++) { if (shapes[curshapetype][curshapestate][i*colrect+j] == 1 ) { mapgame[posx+i][posy+j] = shapes[curshapetype][curshapestate][i*colrect+j]; } } } } public void checkline() //檢查一下這些行中是否有滿行的 { int count = 0 ; for ( int i = maprow- 2 ; i >= 0 ; i--) { count = 0 ; for ( int j = 1 ; j < mapcol- 1 ; j++) { if (mapgame[i][j] == 1 ) { count++; } else break ; } if (count >= mapcol- 2 ) { for ( int k = i; k > 0 ; k--) { for ( int p = 1 ; p < mapcol- 1 ; p++) { mapgame[k][p] = mapgame[k- 1 ][p]; } } score += 10 ; i++; } } } public void paint(graphics g) //重新繪制窗口 { super .paint(g); for ( int i = 0 ; i < rowrect; i++) //繪制正在下落的方塊 { for ( int j = 0 ; j < colrect; j++) { if (shapes[curshapetype][curshapestate][i*colrect+j] == 1 ) { g.fillrect((posy+j+ 1 )*rectwidth, (posx+i+ 1 )*rectwidth, rectwidth, rectwidth); } } } for ( int i = 0 ; i < maprow; i++) //繪制地圖上面已經固定好的方塊信息 { for ( int j = 0 ; j < mapcol; j++) { if (mapgame[i][j] == 2 ) //畫墻 { g.drawrect((j+ 1 )*rectwidth, (i+ 1 )*rectwidth, rectwidth, rectwidth); } if (mapgame[i][j] == 1 ) //畫小方格 { g.fillrect((j+ 1 )*rectwidth, (i+ 1 )*rectwidth, rectwidth, rectwidth); } } } g.drawstring( "score = " + score, 225 , 15 ); g.drawstring( "下一個方塊:" , 225 , 50 ); for ( int i = 0 ; i < rowrect; i++) { for ( int j = 0 ; j < colrect; j++) { if (shapes[nextshapetype][nextshapestate][i*colrect+j] == 1 ) { g.fillrect( 225 +(j*rectwidth), 100 +(i*rectwidth), rectwidth, rectwidth); } } } } public void newgame() //游戲重新開始 { score = 0 ; initmap(); setwall(); createrect(); repaint(); } public void stopgame() //游戲暫停 { timer.stop(); } public void continuegame() { timer.start(); } @override public void keytyped(keyevent e) { } @override public void keypressed(keyevent e) { switch (e.getkeycode()) { case keyevent.vk_up: //上----旋轉 turn(); break ; case keyevent.vk_down: //下----向下移動 movedown(); break ; case keyevent.vk_left: //左----向左移動 moveleft(); break ; case keyevent.vk_right: //右----向右移動 moveright(); break ; } } @override public void keyreleased(keyevent e) { // todo auto-generated method stub } } |
gameframe類:整個游戲的進入口,好吧,說白了就是有main()函數的類,這個類里面實現游戲界面的一些設計,你可以理解為一個小小小小的ui;
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
|
package tetris; import java.awt.event.actionevent; import java.awt.event.actionlistener; import javax.swing.jframe; import javax.swing.jmenu; import javax.swing.jmenubar; import javax.swing.jmenuitem; import javax.swing.joptionpane; public class gameframe extends jframe implements actionlistener{ private int widthframe = 500 ; private int heightframe = 600 ; private jmenu menuone = new jmenu( "游戲" ); //創建一個菜單 private jmenuitem newgame = menuone.add( "重新開始" ); //創建一個內置菜單選項 private jmenuitem exitgame = menuone.add( "游戲退出" ); private jmenuitem stopgame = menuone.add( "游戲暫停" ); private jmenuitem goongame = menuone.add( "游戲繼續" ); private jmenu menutwo = new jmenu( "幫助" ); //創建第二個菜單 private jmenuitem aboutgame = menutwo.add( "關于游戲" ); gamepanel gamepanel = new gamepanel(); public gameframe() //構造函數 { addkeylistener(gamepanel); newgame.addactionlistener( this ); exitgame.addactionlistener( this ); stopgame.addactionlistener( this ); goongame.addactionlistener( this ); aboutgame.addactionlistener( this ); this .add(gamepanel); jmenubar menu = new jmenubar(); menu.add(menuone); menu.add(menutwo); this .setjmenubar(menu); this .settitle( "俄羅斯方塊" ); this .setbounds( 50 , 10 , widthframe, heightframe); this .setvisible( true ); this .setdefaultcloseoperation(jframe.exit_on_close); } public void actionperformed(actionevent e) { if (e.getsource() == newgame) //游戲重新開始 { gamepanel.newgame(); } if (e.getsource() == exitgame) //游戲退出 { system.exit( 0 ); } if (e.getsource() == stopgame) //游戲暫停 { gamepanel.stopgame(); } if (e.getsource() == goongame) //游戲繼續 { gamepanel.continuegame(); } if (e.getsource() == aboutgame) //關于游戲信息 { joptionpane.showmessagedialog( null , "左右鍵移動,向上建旋轉" , "提示" , joptionpane.ok_option); } } public static void main(string[] args) { new gameframe(); } } |
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:https://blog.csdn.net/angry_youth/article/details/74619096