日歷
| 日 | 一 | 二 | 三 | 四 | 五 | 六 |
---|
31 | 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 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
|
統(tǒng)計
- 隨筆 - 2
- 文章 - 6
- 評論 - 5
- 引用 - 0
導(dǎo)航
常用鏈接
留言簿(1)
隨筆檔案
文章檔案
搜索
最新評論

閱讀排行榜
評論排行榜
|
最近在學(xué)習(xí)JAVA,就學(xué)參考學(xué)著寫了一個俄羅斯方塊,代碼有詳細注釋,這里就不多做說明了。
可以用鍵盤,空格控制,或者用界面上的按鈕。
1 import java.awt.*;
2 import java.awt.event.*;
3 import javax.swing.*;
4 import javax.swing.event.*;
5
6 class Block implements Runnable// 方塊類
7  {
8 static final int type = 7, state = 4;
9
10 static final int[][] patten = { // 16進制代表每種方塊
11 { 0x0f00, 0x4444, 0x0f00, 0x4444 },// 長條
12 { 0x6600, 0x6600, 0x6600, 0x6600 },// 正方塊
13 { 0x04e0, 0x0464, 0x00e4, 0x04c4 },// 三角
14 { 0x08e0, 0x0644, 0x00e2, 0x044c },// 彎折一下,1、3,1左
15 { 0x02e0, 0x0446, 0x00e8, 0x0c44 },// 彎折一下,1、3,1右
16 { 0x0462, 0x006c, 0x0462, 0x006c },// 彎折兩下,1、2、1,1左上;1右下
17 { 0x0264, 0x00c6, 0x0264, 0x00c6 } // 彎折兩下,1、2、1,1右上;1左下
18 };
19
20 private int blockType = -1; // 方塊類型,7種,大小范圍0-6
21
22 private int blockState;// 方塊狀態(tài),4種,大小范圍0-3
23
24 private int row, col; // 方塊所在的行數(shù),列數(shù)
25
26 private int oldRow, oldCol; // 記錄方塊變化前所在的行數(shù),列數(shù)
27
28 private int oldType = -1, oldState; // 記錄方塊變化前的類型和狀態(tài)
29
30 private int isfall = 1; // 標記若畫,畫成什么顏色的,
31
32 // 1表示可以下落,畫為紅色;0表示不可下落,畫為藍色
33
34 private boolean end = false;// 結(jié)束標記,為true時表示結(jié)束
35
36 LeftShowCanvas lsc;
37
38 public Block(LeftShowCanvas lsc)
39 {
40 this.lsc = lsc;
41 row = 0;
42 col = 3;
43 oldRow = row;
44 oldCol = col;
45 }
46
47 public void reInit() // 一個方塊無法下落后,重新初始化
48 {
49 blockType = -1;
50 isfall = 1;
51 }
52
53 public void reInitRowCol() // 初始化方塊起始點
54 {
55 row = 0;
56 col = 3;
57 }
58
59 public void run() // 下落線程
60 {
61 lsc.requestFocusInWindow(); // 獲得焦點
62 while (!end)
63 {
64 int blocktype = (int) (Math.random() * 100) % 7;
65 drawBlock(blocktype);
66 do
67 {
68 try
69 {
70 Thread.sleep(500); // 控制下落速度
71 } catch (InterruptedException e)
72 {
73
74 }
75 } while (fallMove()); // 下落
76 for (int j = 0; j < lsc.maxcols; j++)
77 // 判斷是否結(jié)束
78 if (lsc.unitState[3][j] == 2)
79 end = true;
80 }
81 }
82
83 public synchronized void drawBlock(int blockType) // 畫方塊
84 {
85 if (this.blockType != blockType)
86 blockState = (int) (Math.random() * 100) % 4; // 狀態(tài)
87 this.blockType = blockType; // 樣式
88 if (!isMove(3)) // 判斷是否能畫
89 {
90 this.blockType = oldType;
91 this.blockState = oldState;
92 return;
93 }
94 int comIndex = 0x8000;
95 if (this.oldType != -1)
96 {
97 for (int i = oldRow; i < oldRow + 4; i++)
98 for (int j = oldCol; j < oldCol + 4; j++)
99 {
100 if ((patten[oldType][oldState] & comIndex) != 0
101 && lsc.unitState[i][j] == 1)
102 //lsc.drawUnit(i, j, 0); // 先還原
103 lsc.unitState[i][j]=0;//將狀態(tài)記錄改變,用于畫下張圖
104 comIndex = comIndex >> 1;
105 }
106 }
107 comIndex = 0x8000;
108 for (int i = row; i < row + 4; i++)
109 for (int j = col; j < col + 4; j++)
110 {
111 if ((patten[blockType][blockState] & comIndex) != 0)
112 {
113 if (isfall == 1)
114 //lsc.drawUnit(i, j, 1); // 再畫,畫為RED
115 lsc.unitState[i][j]=1; //將狀態(tài)記錄改變
116 else if (isfall == 0)
117 {
118 //lsc.drawUnit(i, j, 2); // 無法下落,畫為BLUE
119 lsc.unitState[i][j]=2;//將狀態(tài)記錄改變,用于畫下張圖
120 lsc.deleteFullLine(i); // 判斷此行是否可以消
121 }
122 }
123 comIndex = comIndex >> 1;
124 }
125
126 Image image; //創(chuàng)建緩沖圖片,利用雙緩沖消除閃爍,畫的下個狀態(tài)圖
127 image=lsc.createImage(lsc.getWidth(),lsc.getHeight());
128 Graphics g=image.getGraphics();
129 lsc.paint(g);
130 g.drawImage(image, 0, 0, lsc);
131
132 if (isfall == 0) // 無法下落,先判斷是否能消行,再重新初始化
133 {
134 // lsc.deleteFullLine(row,col);
135 reInit();
136 reInitRowCol();
137 }
138 oldRow = row;
139 oldCol = col;
140 oldType = blockType;
141 oldState = blockState;
142 }
143
144 public void leftTurn() // 旋轉(zhuǎn),左轉(zhuǎn)
145 {
146 if (this.blockType != -1)
147 {
148 blockState = (blockState + 1) % 4;
149 if (isMove(3))
150 drawBlock(blockType);
151 else
152 blockState = (blockState + 3) % 4;
153 }
154 }
155
156 public void leftMove() // 左移
157 {
158 if (this.blockType != -1 && isMove(0))
159 {
160 col -= 1;
161 drawBlock(blockType);
162 }
163 }
164
165 public void rightMove() // 右移
166 {
167 if (this.blockType != -1 && isMove(1))
168 {
169 col += 1;
170 drawBlock(blockType);
171 }
172 }
173
174 public boolean fallMove() // 下移
175 {
176 if (this.blockType != -1)
177 {
178 if (isMove(2))
179 {
180 row += 1;
181 drawBlock(blockType);
182 return true;
183 } else
184 {
185 isfall = 0;
186 drawBlock(blockType);
187 return false;
188 }
189 }
190 return false;
191 }
192
193 public synchronized boolean isMove(int tag) // 左 0 ,右 1 ,下 2 ,旋轉(zhuǎn) 3
194 {
195 int comIndex = 0x8000;
196 for (int i = row; i < row + 4; i++)
197 for (int j = col; j < col + 4; j++)
198 {
199 if ((patten[blockType][blockState] & comIndex) != 0)
200 {
201 if (tag == 0 && (j == 0 || lsc.unitState[i][j - 1] == 2))// 是否能左移
202 return false;
203 else if (tag == 1 && // 是否能右移
204 (j == lsc.maxcols - 1 || lsc.unitState[i][j + 1] == 2))
205 return false;
206 else if (tag == 2 && // 是否能下移
207 (i == lsc.maxrows - 1 || lsc.unitState[i + 1][j] == 2))
208 return false;
209 else if (tag == 3 && // 是否能旋轉(zhuǎn)
210 (i > lsc.maxrows - 1 || j < 0
211 || j > lsc.maxcols - 1 || lsc.unitState[i][j] == 2))
212 return false;
213 }
214 comIndex = comIndex >> 1;
215 }
216 return true;
217 }
218 }
219
220 class LeftShowCanvas extends Canvas
221  {
222 int maxrows, maxcols; // 畫布最大行數(shù),列數(shù)
223
224 int unitSize; // 單元格的大小,小正方格
225
226 int[][] unitState; // 每個小方格的狀態(tài) 0、1、2表示
227
228 RightPanel rp;
229
230 int score;
231
232 public LeftShowCanvas(RightPanel rp)
233 {
234 this.rp = rp;
235 score = Integer.valueOf(rp.jtf.getText());
236 maxrows = 20;
237 maxcols = 10;
238 unitSize = 20;
239 unitState = new int[maxrows][maxcols];
240 initCanvas();
241 }
242
243 public void initCanvas() // 初始化,畫布方格
244 {
245 for (int i = 0; i < maxrows; i++)
246 for (int j = 0; j < maxcols; j++)
247 unitState[i][j] = 0;
248 }
249
250 public void paint(Graphics g)
251 {
252 for (int i = 0; i < maxrows; i++)
253 {
254 for (int j = 0; j < maxcols; j++)
255 drawUnit(i, j, unitState[i][j]); // 畫方格
256 if (i == 3)
257 {
258 g.setColor(Color.RED);
259 g.drawLine(0, (i + 1) * (unitSize + 1) - 1, maxcols
260 * (unitSize + 1) - 1, (i + 1) * (unitSize + 1) - 1);
261 }
262 }
263 }
264
265 public void drawUnit(int row, int col, int tag) // 畫方格
266 {
267 unitState[row][col] = tag; // 記錄狀態(tài)
268 Graphics g = getGraphics();
269 switch (tag)
270 {
271 case 0: // 初始黑色
272 g.setColor(Color.BLACK);
273 break;
274 case 1: // 方格黑色
275 g.setColor(Color.RED);
276 break;
277 case 2:
278 g.setColor(Color.BLUE);
279 break;
280 }
281 g.fillRect(col * (unitSize + 1), row * (unitSize + 1), unitSize,
282 unitSize);
283 }
284
285 public void deleteFullLine(int row) // 判斷此行是否可以消,同時可消就消行
286 {
287 for (int j = 0; j < maxcols; j++)
288 if (unitState[row][j] != 2)
289 return;
290
291 for (int i = row; i > 3; i--)
292 // 到此即為可消,將上面的移下消此行
293 for (int j = 0; j < maxcols; j++)
294 //drawUnit(i, j, unitState[i - 1][j]);
295 unitState[i][j]=unitState[i-1][j];//將狀態(tài)記錄改變,用于畫下張圖
296 score++;
297 rp.jtf.setText(String.valueOf(score));
298 }
299 }
300
301 class RightPanel extends JPanel
302  {
303 JButton[] jbt = new JButton[7];
304
305 JButton[] jbt2 = new JButton[4];
306
307 JButton jbt3;
308
309 JTextField jtf;
310
311 JLabel jlb;
312
313 MyJPanel jp1, jp2;
314
315 public RightPanel()
316 {
317 jbt[0] = new JButton("長條");
318 jbt[1] = new JButton("方塊");
319 jbt[2] = new JButton("三角");
320 jbt[3] = new JButton("左三");
321 jbt[4] = new JButton("右三");
322 jbt[5] = new JButton("左二");
323 jbt[6] = new JButton("右二");
324 jbt2[0] = new JButton("左移");
325 jbt2[1] = new JButton("右移");
326 jbt2[2] = new JButton("下移");
327 jbt2[3] = new JButton("翻轉(zhuǎn)");
328
329 jbt3 = new JButton("開始");
330 jtf = new JTextField("0", 5);
331 jlb = new JLabel("得分", JLabel.CENTER);
332
333 jp1 = new MyJPanel(); // 左邊的上面板
334 jp2 = new MyJPanel(); // 左邊的下面板
335 jp1.setLayout(new GridLayout(4, 2, 20, 10)); // 網(wǎng)格布局
336 jp2.setLayout(new GridLayout(4, 2, 20, 10)); // 網(wǎng)格布局
337 this.setLayout(new BorderLayout()); // 邊界布局
338 for (int i = 0; i < 7; i++)
339 jp1.add(jbt[i]);
340
341 jp1.add(jbt3);
342
343 for (int i = 0; i < 4; i++)
344 jp2.add(jbt2[i]);
345
346 jp2.add(jlb);
347 jp2.add(jtf);
348
349 this.add(jp1, "North");
350 this.add(jp2, "Center");
351 }
352 }
353
354 // 重寫MyPanel類,使Panel的四周留空間
355 class MyJPanel extends JPanel
356  {
357 public Insets getInsets()
358 {
359 return new Insets(10, 30, 30, 30);
360 }
361 }
362
363 class MyActionListener implements ActionListener
364  {
365 RightPanel rp;
366
367 Block bl;
368
369 LeftShowCanvas lsc;
370
371 public MyActionListener(RightPanel rp, Block bl, LeftShowCanvas lsc)
372 {
373 this.rp = rp;
374 this.bl = bl;
375 this.lsc = lsc;
376 }
377
378 public void actionPerformed(ActionEvent e)
379 {
380 if (e.getSource().equals(rp.jbt3))
381 {
382 // 這樣子則按幾次開始按鈕就創(chuàng)建幾個相同的線程,控制著相同的數(shù)據(jù)
383 Thread th = new Thread(bl);
384 th.start();
385 }
386 for (int i = 0; i < Block.type; i++)
387 if (e.getSource().equals(rp.jbt[i])) // 看是畫哪個
388 {
389 bl.reInitRowCol();
390 bl.drawBlock(i);
391 lsc.requestFocusInWindow(); // 獲得焦點
392 return;
393 }
394 if (e.getSource().equals(rp.jbt2[0]))
395 bl.leftMove();
396 else if (e.getSource().equals(rp.jbt2[1]))
397 bl.rightMove();
398 else if (e.getSource().equals(rp.jbt2[2]))
399 bl.fallMove();
400 else if (e.getSource().equals(rp.jbt2[3]))
401 bl.leftTurn();
402 lsc.requestFocusInWindow(); // 獲得焦點
403 }
404 }
405
406 class MyKeyAdapter extends KeyAdapter
407  {
408 Block bl;
409
410 public MyKeyAdapter(Block bl)
411 {
412 this.bl = bl;
413 }
414
415 public void keyPressed(KeyEvent e)
416 {
417 if (e.getKeyCode() == KeyEvent.VK_LEFT)
418 bl.leftMove();
419 else if (e.getKeyCode() == KeyEvent.VK_RIGHT)
420 bl.rightMove();
421 else if (e.getKeyCode() == KeyEvent.VK_DOWN)
422 bl.fallMove();
423 else if (e.getKeyCode() == KeyEvent.VK_SPACE)
424 bl.leftTurn();
425 }
426 }
427
428 public class FinalElsBlock extends JFrame
429  {
430 Block bl;
431
432 LeftShowCanvas lsc;
433
434 RightPanel rp;
435
436 public FinalElsBlock()
437 {
438 super("ELSBlock Study");
439 setBounds(130, 130, 500, 450);
440 setLayout(new GridLayout(1, 2, 50, 30));
441 rp = new RightPanel();
442 lsc = new LeftShowCanvas(rp);
443 bl = new Block(lsc);
444 rp.setSize(80, 400);
445 for (int i = 0; i < 7; i++)
446 // 為每個按鈕添加消息監(jiān)聽
447 rp.jbt[i].addActionListener(new MyActionListener(rp, bl, lsc));
448 rp.jbt3.addActionListener(new MyActionListener(rp, bl, lsc));
449 for (int i = 0; i < 4; i++)
450 rp.jbt2[i].addActionListener(new MyActionListener(rp, bl, lsc));
451 lsc.addKeyListener(new MyKeyAdapter(bl));
452 this.add(lsc);
453 this.add(rp);
454 this.addWindowListener(new WindowAdapter()
455 {
456 public void windowClosing(WindowEvent e)
457 {
458 dispose();
459 System.exit(0);
460 }
461 });
462 setVisible(true);
463 }
464
465 public static void main(String[] args)
466 {
467 new FinalElsBlock();
468 }
469 }
|