日历
| 日 | 一 | 二 | 三 | 四 | 五 | 六 |
---|
27 | 28 | 29 | 30 | 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 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|
统计
- 随笔 - 2
- 文章 - 6
- 评论 - 5
- 引用 - 0
导航
常用链接
留言簿(1)
随笔档案
文章档案
搜索
最新评论
阅读排行榜
评论排行榜
|
最近在学习JAVA,就学参考学着写了一个俄罗斯方块,代码有详细注释,这里就不多做说明了。
可以用键盘,空格控制,或者用界面上的按钮。
1package game3;
2
3import java.awt.*;
4import java.awt.event.*;
5import javax.swing.*;
6import javax.swing.event.*;
7
8class Block implements Runnable// 方块类
9{
10 static final int type = 7, state = 4;
11
12 static final int[][] patten = { // 16进制代表每种方块
13 { 0x0f00, 0x4444, 0x0f00, 0x4444 },// 长条
14 { 0x6600, 0x6600, 0x6600, 0x6600 },// 正方块
15 { 0x04e0, 0x0464, 0x00e4, 0x04c4 },// 三角
16 { 0x08e0, 0x0644, 0x00e2, 0x044c },// 弯折一下,1、3,1左
17 { 0x02e0, 0x0446, 0x00e8, 0x0c44 },// 弯折一下,1、3,1右
18 { 0x0462, 0x006c, 0x0462, 0x006c },// 弯折两下,1、2、1,1左上;1右下
19 { 0x0264, 0x00c6, 0x0264, 0x00c6 } // 弯折两下,1、2、1,1右上;1左下
20 };
21
22 private int blockType = -1; // 方块类型,7种,大小范围0-6
23
24 private int blockState;// 方块状态,4种,大小范围0-3
25
26 private int row, col; // 方块所在的行数,列数
27
28 private int oldRow, oldCol; // 记录方块变化前所在的行数,列数
29
30 private int oldType = -1, oldState; // 记录方块变化前的类型和状态
31
32 private int isfall = 1; // 标记若画,画成什么颜色的,
33
34 // 1表示可以下落,画为红色;0表示不可下落,画为蓝色
35
36 private boolean end = false;// 结束标记,为true时表示结束
37
38 LeftShowCanvas lsc;
39
40 public Block(LeftShowCanvas lsc)
41 {
42 this.lsc = lsc;
43 row = 0;
44 col = 3;
45 oldRow = row;
46 oldCol = col;
47 }
48
49 public void reInit() // 一个方块无法下落后,重新初始化
50 {
51 blockType = -1;
52 isfall = 1;
53 }
54
55 public void reInitRowCol() // 初始化方块起始点
56 {
57 row = 0;
58 col = 3;
59 }
60
61 public void run() // 下落线程
62 {
63 lsc.requestFocusInWindow(); // 获得焦点
64 while (!end)
65 {
66 int blocktype = (int) (Math.random() * 100) % 7;
67 drawBlock(blocktype);
68 do
69 {
70 try
71 {
72 Thread.sleep(500); // 控制下落速度
73 } catch (InterruptedException e)
74 {
75
76 }
77 } while (fallMove()); // 下落
78 for (int j = 0; j < lsc.maxcols; j++)
79 // 判断是否结束
80 if (lsc.unitState[3][j] == 2)
81 end = true;
82 }
83 }
84
85 public synchronized void drawBlock(int blockType) // 画方块
86 {
87 if (this.blockType != blockType)
88 blockState = (int) (Math.random() * 100) % 4; // 状态
89 this.blockType = blockType; // 样式
90 if (!isMove(3)) // 判断是否能画
91 {
92 this.blockType = oldType;
93 this.blockState = oldState;
94 return;
95 }
96 int comIndex = 0x8000;
97 if (this.oldType != -1)
98 {
99 for (int i = oldRow; i < oldRow + 4; i++)
100 for (int j = oldCol; j < oldCol + 4; j++)
101 {
102 if ((patten[oldType][oldState] & comIndex) != 0
103 && lsc.unitState[i][j] == 1)
104 lsc.drawUnit(i, j, 0); // 先还原
105 comIndex = comIndex >> 1;
106 }
107 }
108 comIndex = 0x8000;
109 for (int i = row; i < row + 4; i++)
110 for (int j = col; j < col + 4; j++)
111 {
112 if ((patten[blockType][blockState] & comIndex) != 0)
113 {
114 if (isfall == 1)
115 lsc.drawUnit(i, j, 1); // 再画,画为RED
116 else if (isfall == 0)
117 {
118 lsc.drawUnit(i, j, 2); // 无法下落,画为BLUE
119 lsc.deleteFullLine(i); // 判断此行是否可以消
120 }
121 }
122 comIndex = comIndex >> 1;
123 }
124 if (isfall == 0) // 无法下落,先判断是否能消行,再重新初始化
125 {
126 // lsc.deleteFullLine(row,col);
127 reInit();
128 reInitRowCol();
129 }
130 oldRow = row;
131 oldCol = col;
132 oldType = blockType;
133 oldState = blockState;
134 }
135
136 public void leftTurn() // 旋转,左转
137 {
138 if (this.blockType != -1)
139 {
140 blockState = (blockState + 1) % 4;
141 if (isMove(3))
142 drawBlock(blockType);
143 else
144 blockState = (blockState + 3) % 4;
145 }
146 }
147
148 public void leftMove() // 左移
149 {
150 if (this.blockType != -1 && isMove(0))
151 {
152 col -= 1;
153 drawBlock(blockType);
154 }
155 }
156
157 public void rightMove() // 右移
158 {
159 if (this.blockType != -1 && isMove(1))
160 {
161 col += 1;
162 drawBlock(blockType);
163 }
164 }
165
166 public boolean fallMove() // 下移
167 {
168 if (this.blockType != -1)
169 {
170 if (isMove(2))
171 {
172 row += 1;
173 drawBlock(blockType);
174 return true;
175 } else
176 {
177 isfall = 0;
178 drawBlock(blockType);
179 return false;
180 }
181 }
182 return false;
183 }
184
185 public synchronized boolean isMove(int tag) // 左 0 ,右 1 ,下 2 ,旋转 3
186 {
187 int comIndex = 0x8000;
188 for (int i = row; i < row + 4; i++)
189 for (int j = col; j < col + 4; j++)
190 {
191 if ((patten[blockType][blockState] & comIndex) != 0)
192 {
193 if (tag == 0 && (j == 0 || lsc.unitState[i][j - 1] == 2))// 是否能左移
194 return false;
195 else if (tag == 1 && // 是否能右移
196 (j == lsc.maxcols - 1 || lsc.unitState[i][j + 1] == 2))
197 return false;
198 else if (tag == 2 && // 是否能下移
199 (i == lsc.maxrows - 1 || lsc.unitState[i + 1][j] == 2))
200 return false;
201 else if (tag == 3 && // 是否能旋转
202 (i > lsc.maxrows - 1 || j < 0
203 || j > lsc.maxcols - 1 || lsc.unitState[i][j] == 2))
204 return false;
205 }
206 comIndex = comIndex >> 1;
207 }
208 return true;
209 }
210}
211
212class LeftShowCanvas extends Canvas
213{
214 int maxrows, maxcols; // 画布最大行数,列数
215
216 int unitSize; // 单元格的大小,小正方格
217
218 int[][] unitState; // 每个小方格的状态 0、1、2表示
219
220 RightPanel rp;
221
222 int score;
223
224 public LeftShowCanvas(RightPanel rp)
225 {
226 this.rp = rp;
227 score = Integer.valueOf(rp.jtf.getText());
228 maxrows = 20;
229 maxcols = 10;
230 unitSize = 20;
231 unitState = new int[maxrows][maxcols];
232 initCanvas();
233 }
234
235 public void initCanvas() // 初始化,画布方格
236 {
237 for (int i = 0; i < maxrows; i++)
238 for (int j = 0; j < maxcols; j++)
239 unitState[i][j] = 0;
240 }
241
242 public void paint(Graphics g)
243 {
244 for (int i = 0; i < maxrows; i++)
245 {
246 for (int j = 0; j < maxcols; j++)
247 drawUnit(i, j, unitState[i][j]); // 画方格
248 if (i == 3)
249 {
250 g.setColor(Color.RED);
251 g.drawLine(0, (i + 1) * (unitSize + 1) - 1, maxcols
252 * (unitSize + 1) - 1, (i + 1) * (unitSize + 1) - 1);
253 }
254 }
255 }
256
257 public void drawUnit(int row, int col, int tag) // 画方格
258 {
259 unitState[row][col] = tag; // 记录状态
260 Graphics g = getGraphics();
261 switch (tag)
262 {
263 case 0: // 初始黑色
264 g.setColor(Color.BLACK);
265 break;
266 case 1: // 方格黑色
267 g.setColor(Color.RED);
268 break;
269 case 2:
270 g.setColor(Color.BLUE);
271 break;
272 }
273 g.fillRect(col * (unitSize + 1), row * (unitSize + 1), unitSize,
274 unitSize);
275 }
276
277 public void deleteFullLine(int row) // 判断此行是否可以消,同时可消就消行
278 {
279 for (int j = 0; j < maxcols; j++)
280 if (unitState[row][j] != 2)
281 return;
282
283 for (int i = row; i > 3; i--)
284 // 到此即为可消,将上面的移下消此行
285 for (int j = 0; j < maxcols; j++)
286 drawUnit(i, j, unitState[i - 1][j]);
287 score++;
288 rp.jtf.setText(String.valueOf(score));
289 }
290}
291
292class RightPanel extends JPanel
293{
294 JButton[] jbt = new JButton[7];
295
296 JButton[] jbt2 = new JButton[4];
297
298 JButton jbt3;
299
300 JTextField jtf;
301
302 JLabel jlb;
303
304 MyJPanel jp1, jp2;
305
306 public RightPanel()
307 {
308 jbt[0] = new JButton("长条");
309 jbt[1] = new JButton("方块");
310 jbt[2] = new JButton("三角");
311 jbt[3] = new JButton("左三");
312 jbt[4] = new JButton("右三");
313 jbt[5] = new JButton("左二");
314 jbt[6] = new JButton("右二");
315 jbt2[0] = new JButton("左移");
316 jbt2[1] = new JButton("右移");
317 jbt2[2] = new JButton("下移");
318 jbt2[3] = new JButton("翻转");
319
320 jbt3 = new JButton("开始");
321 jtf = new JTextField("0", 5);
322 jlb = new JLabel("得分", JLabel.CENTER);
323
324 jp1 = new MyJPanel(); // 左边的上面板
325 jp2 = new MyJPanel(); // 左边的下面板
326 jp1.setLayout(new GridLayout(4, 2, 20, 10)); // 网格布局
327 jp2.setLayout(new GridLayout(4, 2, 20, 10)); // 网格布局
328 this.setLayout(new BorderLayout()); // 边界布局
329 for (int i = 0; i < 7; i++)
330 jp1.add(jbt[i]);
331
332 jp1.add(jbt3);
333
334 for (int i = 0; i < 4; i++)
335 jp2.add(jbt2[i]);
336
337 jp2.add(jlb);
338 jp2.add(jtf);
339
340 this.add(jp1, "North");
341 this.add(jp2, "Center");
342 }
343}
344
345// 重写MyPanel类,使Panel的四周留空间
346class MyJPanel extends JPanel
347{
348 public Insets getInsets()
349 {
350 return new Insets(10, 30, 30, 30);
351 }
352}
353
354class MyActionListener implements ActionListener
355{
356 RightPanel rp;
357
358 Block bl;
359
360 LeftShowCanvas lsc;
361
362 public MyActionListener(RightPanel rp, Block bl, LeftShowCanvas lsc)
363 {
364 this.rp = rp;
365 this.bl = bl;
366 this.lsc = lsc;
367 }
368
369 public void actionPerformed(ActionEvent e)
370 {
371 if (e.getSource().equals(rp.jbt3))
372 {
373 // 这样子则按几次开始按钮就创建几个相同的线程,控制着相同的数据
374 Thread th = new Thread(bl);
375 th.start();
376 }
377 for (int i = 0; i < Block.type; i++)
378 if (e.getSource().equals(rp.jbt[i])) // 看是画哪个
379 {
380 bl.reInitRowCol();
381 bl.drawBlock(i);
382 lsc.requestFocusInWindow(); // 获得焦点
383 return;
384 }
385 if (e.getSource().equals(rp.jbt2[0]))
386 bl.leftMove();
387 else if (e.getSource().equals(rp.jbt2[1]))
388 bl.rightMove();
389 else if (e.getSource().equals(rp.jbt2[2]))
390 bl.fallMove();
391 else if (e.getSource().equals(rp.jbt2[3]))
392 bl.leftTurn();
393 lsc.requestFocusInWindow(); // 获得焦点
394 }
395}
396
397class MyKeyAdapter extends KeyAdapter
398{
399 Block bl;
400
401 public MyKeyAdapter(Block bl)
402 {
403 this.bl = bl;
404 }
405
406 public void keyPressed(KeyEvent e)
407 {
408 if (e.getKeyCode() == KeyEvent.VK_LEFT)
409 bl.leftMove();
410 else if (e.getKeyCode() == KeyEvent.VK_RIGHT)
411 bl.rightMove();
412 else if (e.getKeyCode() == KeyEvent.VK_DOWN)
413 bl.fallMove();
414 else if (e.getKeyCode() == KeyEvent.VK_SPACE)
415 bl.leftTurn();
416 }
417}
418
419public class FinalElsBlock extends JFrame
420{
421 Block bl;
422
423 LeftShowCanvas lsc;
424
425 RightPanel rp;
426
427 public FinalElsBlock()
428 {
429 super("ELSBlock Study");
430 setBounds(130, 130, 500, 450);
431 setLayout(new GridLayout(1, 2, 50, 30));
432 rp = new RightPanel();
433 lsc = new LeftShowCanvas(rp);
434 bl = new Block(lsc);
435 rp.setSize(80, 400);
436 for (int i = 0; i < 7; i++)
437 // 为每个按钮添加消息监听
438 rp.jbt[i].addActionListener(new MyActionListener(rp, bl, lsc));
439 rp.jbt3.addActionListener(new MyActionListener(rp, bl, lsc));
440 for (int i = 0; i < 4; i++)
441 rp.jbt2[i].addActionListener(new MyActionListener(rp, bl, lsc));
442 lsc.addKeyListener(new MyKeyAdapter(bl));
443 this.add(lsc);
444 this.add(rp);
445 this.addWindowListener(new WindowAdapter()
446 {
447 public void windowClosing(WindowEvent e)
448 {
449 dispose();
450 System.exit(0);
451 }
452 });
453 setVisible(true);
454 }
455
456 public static void main(String[] args)
457 {
458 new FinalElsBlock();
459 }
460}
|