日历
| 日 | 一 | 二 | 三 | 四 | 五 | 六 |
---|
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 | 8 | 9 |
|
统计
- 随笔 - 2
- 文章 - 6
- 评论 - 5
- 引用 - 0
导航
常用链接
留言簿(1)
随笔档案
文章档案
搜索
最新评论
![](/images/xml.gif)
阅读排行榜
评论排行榜
|
最近在学习JAVA,就学参考学着写了一个俄罗斯方块,代码有详细注释,这里就不多做说明了。
可以用键盘,空格控制,或者用界面上的按钮。
1 import java.awt.*;
2 import java.awt.event.*;
3 import javax.swing.*;
4 import javax.swing.event.*;
5![](/Images/OutliningIndicators/None.gif)
6 class Block implements Runnable// 方块类
7![](/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](/Images/OutliningIndicators/ContractedBlock.gif) {
8 static final int type = 7, state = 4;
9![](/Images/OutliningIndicators/InBlock.gif)
10![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) static final int[][] patten = { // 16进制代表每种方块
11![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { 0x0f00, 0x4444, 0x0f00, 0x4444 },// 长条
12![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { 0x6600, 0x6600, 0x6600, 0x6600 },// 正方块
13![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { 0x04e0, 0x0464, 0x00e4, 0x04c4 },// 三角
14![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { 0x08e0, 0x0644, 0x00e2, 0x044c },// 弯折一下,1、3,1左
15![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { 0x02e0, 0x0446, 0x00e8, 0x0c44 },// 弯折一下,1、3,1右
16![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { 0x0462, 0x006c, 0x0462, 0x006c },// 弯折两下,1、2、1,1左上;1右下
17![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) { 0x0264, 0x00c6, 0x0264, 0x00c6 } // 弯折两下,1、2、1,1右上;1左下
18 };
19![](/Images/OutliningIndicators/InBlock.gif)
20 private int blockType = -1; // 方块类型,7种,大小范围0-6
21![](/Images/OutliningIndicators/InBlock.gif)
22 private int blockState;// 方块状态,4种,大小范围0-3
23![](/Images/OutliningIndicators/InBlock.gif)
24 private int row, col; // 方块所在的行数,列数
25![](/Images/OutliningIndicators/InBlock.gif)
26 private int oldRow, oldCol; // 记录方块变化前所在的行数,列数
27![](/Images/OutliningIndicators/InBlock.gif)
28 private int oldType = -1, oldState; // 记录方块变化前的类型和状态
29![](/Images/OutliningIndicators/InBlock.gif)
30 private int isfall = 1; // 标记若画,画成什么颜色的,
31![](/Images/OutliningIndicators/InBlock.gif)
32 // 1表示可以下落,画为红色;0表示不可下落,画为蓝色
33![](/Images/OutliningIndicators/InBlock.gif)
34 private boolean end = false;// 结束标记,为true时表示结束
35![](/Images/OutliningIndicators/InBlock.gif)
36 LeftShowCanvas lsc;
37![](/Images/OutliningIndicators/InBlock.gif)
38 public Block(LeftShowCanvas lsc)
39![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
40 this.lsc = lsc;
41 row = 0;
42 col = 3;
43 oldRow = row;
44 oldCol = col;
45 }
46![](/Images/OutliningIndicators/InBlock.gif)
47 public void reInit() // 一个方块无法下落后,重新初始化
48![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
49 blockType = -1;
50 isfall = 1;
51 }
52![](/Images/OutliningIndicators/InBlock.gif)
53 public void reInitRowCol() // 初始化方块起始点
54![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
55 row = 0;
56 col = 3;
57 }
58![](/Images/OutliningIndicators/InBlock.gif)
59 public void run() // 下落线程
60![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
61 lsc.requestFocusInWindow(); // 获得焦点
62 while (!end)
63![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
64 int blocktype = (int) (Math.random() * 100) % 7;
65 drawBlock(blocktype);
66 do
67![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
68 try
69![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
70 Thread.sleep(500); // 控制下落速度
71 } catch (InterruptedException e)
72![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
73![](/Images/OutliningIndicators/InBlock.gif)
74 }
75 } while (fallMove()); // 下落
76 for (int j = 0; j < lsc.maxcols; j++)
77 // 判断是否结束
78 if (lsc.unitState[3][j] == 2)
79 end = true;
80 }
81 }
82![](/Images/OutliningIndicators/InBlock.gif)
83 public synchronized void drawBlock(int blockType) // 画方块
84![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
85 if (this.blockType != blockType)
86 blockState = (int) (Math.random() * 100) % 4; // 状态
87 this.blockType = blockType; // 样式
88 if (!isMove(3)) // 判断是否能画
89![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
90 this.blockType = oldType;
91 this.blockState = oldState;
92 return;
93 }
94 int comIndex = 0x8000;
95 if (this.oldType != -1)
96![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
97 for (int i = oldRow; i < oldRow + 4; i++)
98 for (int j = oldCol; j < oldCol + 4; j++)
99![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
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;//将状态记录改变,用于画下张图
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![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
111 if ((patten[blockType][blockState] & comIndex) != 0)
112![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
113 if (isfall == 1)
114 //lsc.drawUnit(i, j, 1); // 再画,画为RED
115 lsc.unitState[i][j]=1; //将状态记录改变
116 else if (isfall == 0)
117![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
118 //lsc.drawUnit(i, j, 2); // 无法下落,画为BLUE
119 lsc.unitState[i][j]=2;//将状态记录改变,用于画下张图
120 lsc.deleteFullLine(i); // 判断此行是否可以消
121 }
122 }
123 comIndex = comIndex >> 1;
124 }
125
126 Image image; //创建缓冲图片,利用双缓冲消除闪烁,画的下个状态图
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![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
134 // lsc.deleteFullLine(row,col);
135 reInit();
136 reInitRowCol();
137 }
138 oldRow = row;
139 oldCol = col;
140 oldType = blockType;
141 oldState = blockState;
142 }
143![](/Images/OutliningIndicators/InBlock.gif)
144 public void leftTurn() // 旋转,左转
145![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
146 if (this.blockType != -1)
147![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
148 blockState = (blockState + 1) % 4;
149 if (isMove(3))
150 drawBlock(blockType);
151 else
152 blockState = (blockState + 3) % 4;
153 }
154 }
155![](/Images/OutliningIndicators/InBlock.gif)
156 public void leftMove() // 左移
157![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
158 if (this.blockType != -1 && isMove(0))
159![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
160 col -= 1;
161 drawBlock(blockType);
162 }
163 }
164![](/Images/OutliningIndicators/InBlock.gif)
165 public void rightMove() // 右移
166![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
167 if (this.blockType != -1 && isMove(1))
168![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
169 col += 1;
170 drawBlock(blockType);
171 }
172 }
173![](/Images/OutliningIndicators/InBlock.gif)
174 public boolean fallMove() // 下移
175![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
176 if (this.blockType != -1)
177![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
178 if (isMove(2))
179![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
180 row += 1;
181 drawBlock(blockType);
182 return true;
183 } else
184![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
185 isfall = 0;
186 drawBlock(blockType);
187 return false;
188 }
189 }
190 return false;
191 }
192![](/Images/OutliningIndicators/InBlock.gif)
193 public synchronized boolean isMove(int tag) // 左 0 ,右 1 ,下 2 ,旋转 3
194![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
195 int comIndex = 0x8000;
196 for (int i = row; i < row + 4; i++)
197 for (int j = col; j < col + 4; j++)
198![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
199 if ((patten[blockType][blockState] & comIndex) != 0)
200![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
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 && // 是否能旋转
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![](/Images/OutliningIndicators/None.gif)
220 class LeftShowCanvas extends Canvas
221![](/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](/Images/OutliningIndicators/ContractedBlock.gif) {
222 int maxrows, maxcols; // 画布最大行数,列数
223![](/Images/OutliningIndicators/InBlock.gif)
224 int unitSize; // 单元格的大小,小正方格
225![](/Images/OutliningIndicators/InBlock.gif)
226 int[][] unitState; // 每个小方格的状态 0、1、2表示
227![](/Images/OutliningIndicators/InBlock.gif)
228 RightPanel rp;
229![](/Images/OutliningIndicators/InBlock.gif)
230 int score;
231![](/Images/OutliningIndicators/InBlock.gif)
232 public LeftShowCanvas(RightPanel rp)
233![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
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![](/Images/OutliningIndicators/InBlock.gif)
243 public void initCanvas() // 初始化,画布方格
244![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
245 for (int i = 0; i < maxrows; i++)
246 for (int j = 0; j < maxcols; j++)
247 unitState[i][j] = 0;
248 }
249![](/Images/OutliningIndicators/InBlock.gif)
250 public void paint(Graphics g)
251![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
252 for (int i = 0; i < maxrows; i++)
253![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
254 for (int j = 0; j < maxcols; j++)
255 drawUnit(i, j, unitState[i][j]); // 画方格
256 if (i == 3)
257![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
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![](/Images/OutliningIndicators/InBlock.gif)
265 public void drawUnit(int row, int col, int tag) // 画方格
266![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
267 unitState[row][col] = tag; // 记录状态
268 Graphics g = getGraphics();
269 switch (tag)
270![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
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![](/Images/OutliningIndicators/InBlock.gif)
285 public void deleteFullLine(int row) // 判断此行是否可以消,同时可消就消行
286![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
287 for (int j = 0; j < maxcols; j++)
288 if (unitState[row][j] != 2)
289 return;
290![](/Images/OutliningIndicators/InBlock.gif)
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];//将状态记录改变,用于画下张图
296 score++;
297 rp.jtf.setText(String.valueOf(score));
298 }
299 }
300![](/Images/OutliningIndicators/None.gif)
301 class RightPanel extends JPanel
302![](/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](/Images/OutliningIndicators/ContractedBlock.gif) {
303 JButton[] jbt = new JButton[7];
304![](/Images/OutliningIndicators/InBlock.gif)
305 JButton[] jbt2 = new JButton[4];
306![](/Images/OutliningIndicators/InBlock.gif)
307 JButton jbt3;
308![](/Images/OutliningIndicators/InBlock.gif)
309 JTextField jtf;
310![](/Images/OutliningIndicators/InBlock.gif)
311 JLabel jlb;
312![](/Images/OutliningIndicators/InBlock.gif)
313 MyJPanel jp1, jp2;
314![](/Images/OutliningIndicators/InBlock.gif)
315 public RightPanel()
316![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
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("翻转");
328![](/Images/OutliningIndicators/InBlock.gif)
329 jbt3 = new JButton("开始");
330 jtf = new JTextField("0", 5);
331 jlb = new JLabel("得分", JLabel.CENTER);
332![](/Images/OutliningIndicators/InBlock.gif)
333 jp1 = new MyJPanel(); // 左边的上面板
334 jp2 = new MyJPanel(); // 左边的下面板
335 jp1.setLayout(new GridLayout(4, 2, 20, 10)); // 网格布局
336 jp2.setLayout(new GridLayout(4, 2, 20, 10)); // 网格布局
337 this.setLayout(new BorderLayout()); // 边界布局
338 for (int i = 0; i < 7; i++)
339 jp1.add(jbt[i]);
340![](/Images/OutliningIndicators/InBlock.gif)
341 jp1.add(jbt3);
342![](/Images/OutliningIndicators/InBlock.gif)
343 for (int i = 0; i < 4; i++)
344 jp2.add(jbt2[i]);
345![](/Images/OutliningIndicators/InBlock.gif)
346 jp2.add(jlb);
347 jp2.add(jtf);
348![](/Images/OutliningIndicators/InBlock.gif)
349 this.add(jp1, "North");
350 this.add(jp2, "Center");
351 }
352 }
353![](/Images/OutliningIndicators/None.gif)
354 // 重写MyPanel类,使Panel的四周留空间
355 class MyJPanel extends JPanel
356![](/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](/Images/OutliningIndicators/ContractedBlock.gif) {
357 public Insets getInsets()
358![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
359 return new Insets(10, 30, 30, 30);
360 }
361 }
362![](/Images/OutliningIndicators/None.gif)
363 class MyActionListener implements ActionListener
364![](/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](/Images/OutliningIndicators/ContractedBlock.gif) {
365 RightPanel rp;
366![](/Images/OutliningIndicators/InBlock.gif)
367 Block bl;
368![](/Images/OutliningIndicators/InBlock.gif)
369 LeftShowCanvas lsc;
370![](/Images/OutliningIndicators/InBlock.gif)
371 public MyActionListener(RightPanel rp, Block bl, LeftShowCanvas lsc)
372![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
373 this.rp = rp;
374 this.bl = bl;
375 this.lsc = lsc;
376 }
377![](/Images/OutliningIndicators/InBlock.gif)
378 public void actionPerformed(ActionEvent e)
379![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
380 if (e.getSource().equals(rp.jbt3))
381![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
382 // 这样子则按几次开始按钮就创建几个相同的线程,控制着相同的数据
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![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
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![](/Images/OutliningIndicators/None.gif)
406 class MyKeyAdapter extends KeyAdapter
407![](/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](/Images/OutliningIndicators/ContractedBlock.gif) {
408 Block bl;
409![](/Images/OutliningIndicators/InBlock.gif)
410 public MyKeyAdapter(Block bl)
411![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
412 this.bl = bl;
413 }
414![](/Images/OutliningIndicators/InBlock.gif)
415 public void keyPressed(KeyEvent e)
416![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
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![](/Images/OutliningIndicators/None.gif)
428 public class FinalElsBlock extends JFrame
429![](/Images/OutliningIndicators/ExpandedBlockStart.gif) ![](/Images/OutliningIndicators/ContractedBlock.gif) {
430 Block bl;
431![](/Images/OutliningIndicators/InBlock.gif)
432 LeftShowCanvas lsc;
433![](/Images/OutliningIndicators/InBlock.gif)
434 RightPanel rp;
435![](/Images/OutliningIndicators/InBlock.gif)
436 public FinalElsBlock()
437![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
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 // 为每个按钮添加消息监听
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![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
456 public void windowClosing(WindowEvent e)
457![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
458 dispose();
459 System.exit(0);
460 }
461 });
462 setVisible(true);
463 }
464![](/Images/OutliningIndicators/InBlock.gif)
465 public static void main(String[] args)
466![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif) {
467 new FinalElsBlock();
468 }
469 }
|