java版俄罗斯方块

Posted 何处不相逢

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java版俄罗斯方块相关的知识,希望对你有一定的参考价值。

http://www.blogjava.net/evapocket/archive/2009/08/12/ElsBlock.html

俄罗斯方块:

  1 package com.nick.game;
  2 
  3 import java.awt.*;
  4 import java.awt.event.*;
  5 import javax.swing.*;
  6 import javax.swing.event.*;
  7 
  8 class 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                         lsc.unitState[i][j]=0;//将状态记录改变,用于画下张图
106                     comIndex = comIndex >> 1;
107                 }
108         }
109         comIndex = 0x8000;
110         for (int i = row; i < row + 4; i++)
111             for (int j = col; j < col + 4; j++)
112             {
113                 if ((patten[blockType][blockState] & comIndex) != 0)
114                 {
115                     if (isfall == 1)
116                         //lsc.drawUnit(i, j, 1); // 再画,画为RED
117                         lsc.unitState[i][j]=1; //将状态记录改变
118                     else if (isfall == 0)
119                     {
120                         //lsc.drawUnit(i, j, 2); // 无法下落,画为BLUE
121                         lsc.unitState[i][j]=2;//将状态记录改变,用于画下张图
122                         lsc.deleteFullLine(i); // 判断此行是否可以消
123                     }
124                 }
125                 comIndex = comIndex >> 1;
126             }
127 
128         Image image; //创建缓冲图片,利用双缓冲消除闪烁,画的下个状态图
129         image=lsc.createImage(lsc.getWidth(),lsc.getHeight());
130         Graphics g=image.getGraphics();
131         lsc.paint(g);
132         g.drawImage(image, 0, 0, lsc);
133 
134         if (isfall == 0) // 无法下落,先判断是否能消行,再重新初始化
135         {
136             // lsc.deleteFullLine(row,col);
137             reInit();
138             reInitRowCol();
139         }
140         oldRow = row;
141         oldCol = col;
142         oldType = blockType;
143         oldState = blockState;
144     }
145 
146     public void leftTurn() // 旋转,左转
147     {
148         if (this.blockType != -1)
149         {
150             blockState = (blockState + 1) % 4;
151             if (isMove(3))
152                 drawBlock(blockType);
153             else
154                 blockState = (blockState + 3) % 4;
155         }
156     }
157 
158     public void leftMove() // 左移
159     {
160         if (this.blockType != -1 && isMove(0))
161         {
162             col -= 1;
163             drawBlock(blockType);
164         }
165     }
166 
167     public void rightMove() // 右移
168     {
169         if (this.blockType != -1 && isMove(1))
170         {
171             col += 1;
172             drawBlock(blockType);
173         }
174     }
175 
176     public boolean fallMove() // 下移
177     {
178         if (this.blockType != -1)
179         {
180             if (isMove(2))
181             {
182                 row += 1;
183                 drawBlock(blockType);
184                 return true;
185             } else
186             {
187                 isfall = 0;
188                 drawBlock(blockType);
189                 return false;
190             }
191         }
192         return false;
193     }
194 
195     public synchronized boolean isMove(int tag) // 左 0 ,右 1 ,下 2 ,旋转 3
196     {
197         int comIndex = 0x8000;
198         for (int i = row; i < row + 4; i++)
199             for (int j = col; j < col + 4; j++)
200             {
201                 if ((patten[blockType][blockState] & comIndex) != 0)
202                 {
203                     if (tag == 0 && (j == 0 || lsc.unitState[i][j - 1] == 2))// 是否能左移
204                         return false;
205                     else if (tag == 1 && // 是否能右移
206                             (j == lsc.maxcols - 1 || lsc.unitState[i][j + 1] == 2))
207                         return false;
208                     else if (tag == 2 && // 是否能下移
209                             (i == lsc.maxrows - 1 || lsc.unitState[i + 1][j] == 2))
210                         return false;
211                     else if (tag == 3 && // 是否能旋转
212                             (i > lsc.maxrows - 1 || j < 0
213                                     || j > lsc.maxcols - 1 || lsc.unitState[i][j] == 2))
214                         return false;
215                 }
216                 comIndex = comIndex >> 1;
217             }
218         return true;
219     }
220 }
221 
222 class LeftShowCanvas extends Canvas
223 {
224     int maxrows, maxcols; // 画布最大行数,列数
225 
226     int unitSize; // 单元格的大小,小正方格
227 
228     int[][] unitState; // 每个小方格的状态 0、1、2表示
229 
230     RightPanel rp;
231 
232     int score;
233 
234     public LeftShowCanvas(RightPanel rp)
235     {
236         this.rp = rp;
237         score = Integer.valueOf(rp.jtf.getText());
238         maxrows = 20;
239         maxcols = 10;
240         unitSize = 20;
241         unitState = new int[maxrows][maxcols];
242         initCanvas();
243     }
244 
245     public void initCanvas() // 初始化,画布方格
246     {
247         for (int i = 0; i < maxrows; i++)
248             for (int j = 0; j < maxcols; j++)
249                 unitState[i][j] = 0;
250     }
251 
252     public void paint(Graphics g)
253     {
254         for (int i = 0; i < maxrows; i++)
255         {
256             for (int j = 0; j < maxcols; j++)
257                 drawUnit(i, j, unitState[i][j]); // 画方格
258             if (i == 3)
259             {
260                 g.setColor(Color.RED);
261                 g.drawLine(0, (i + 1) * (unitSize + 1) - 1, maxcols
262                         * (unitSize + 1) - 1, (i + 1) * (unitSize + 1) - 1);
263             }
264         }
265     }
266 
267     public void drawUnit(int row, int col, int tag) // 画方格
268     {
269         unitState[row][col] = tag; // 记录状态
270         Graphics g = getGraphics();
271         switch (tag)
272         {
273             case 0: // 初始黑色
274                 g.setColor(Color.BLACK);
275                 break;
276             case 1: // 方格黑色
277                 g.setColor(Color.RED);
278                 break;
279             case 2:
280                 g.setColor(Color.BLUE);
281                 break;
282         }
283         g.fillRect(col * (unitSize + 1), row * (unitSize + 1), unitSize,
284                 unitSize);
285     }
286 
287     public void deleteFullLine(int row) // 判断此行是否可以消,同时可消就消行
288     {
289         for (int j = 0; j < maxcols; j++)
290             if (unitState[row][j] != 2)
291                 return;
292 
293         for (int i = row; i > 3; i--)
294             // 到此即为可消,将上面的移下消此行
295             for (int j = 0; j < maxcols; j++)
296                 //drawUnit(i, j, unitState[i - 1][j]);
297                 unitState[i][j]=unitState[i-1][j];//将状态记录改变,用于画下张图
298         score++;
299         rp.jtf.setText(String.valueOf(score));
300     }
301 }
302 
303 class RightPanel extends JPanel
304 {
305     JButton[] jbt = new JButton[7];
306 
307     JButton[] jbt2 = new JButton[4];
308 
309     JButton jbt3;
310 
311     JTextField jtf;
312 
313     JLabel jlb;
314 
315     MyJPanel jp1, jp2;
316 
317     public RightPanel()
318     {
319         jbt[0] = new JButton("长条");
320         jbt[1] = new JButton("方块");
321         jbt[2] = new JButton("三角");
322         jbt[3] = new JButton("左三");
323         jbt[4] = new JButton("右三");
324         jbt[5] = new JButton("左二");
325         jbt[6] = new JButton("右二");
326         jbt2[0] = new JButton("左移");
327         jbt2[1] = new JButton("右移");
328         jbt2[2] = new JButton("下移");
329         jbt2[3] = new JButton("翻转");
330 
331         jbt3 = new JButton("开始");
332         jtf = new JTextField("0", 5);
333         jlb = new JLabel("得分", JLabel.CENTER);
334 
335         jp1 = new MyJPanel(); // 左边的上面板
336         jp2 = new MyJPanel(); // 左边的下面板
337         jp1.setLayout(new GridLayout(4, 2, 20, 10)); // 网格布局
338         jp2.setLayout(new GridLayout(4, 2, 20, 10)); // 网格布局
339         this.setLayout(new BorderLayout()); // 边界布局
340         for (int i = 0; i < 7; i++)
341             jp1.add(jbt[i]);
342 
343         jp1.add(jbt3);
344 
345         for (int i = 0; i < 4; i++)
346             jp2.add(jbt2[i]);
347 
348         jp2.add(jlb);
349         jp2.add(jtf);
350 
351         this.add(jp1, "North");
352         this.add(jp2, "Center");
353     }
354 }
355 
356 // 重写MyPanel类,使Panel的四周留空间
357 class MyJPanel extends JPanel
358 {
359     public Insets getInsets()
360     {
361         return new Insets(10, 30, 30, 30);
362     }
363 }
364 
365 class MyActionListener implements ActionListener
366 {
367     RightPanel rp;
368 
369     Block bl;
370 
371     LeftShowCanvas lsc;
372 
373     public MyActionListener(RightPanel rp, Block bl, LeftShowCanvas lsc)
374     {
375         this.rp = rp;
376         this.bl = bl;
377         this.lsc = lsc;
378     }
379 
380     public void actionPerformed(ActionEvent e)
381     {
382         if (e.getSource().equals(rp.jbt3))
383         {
384             // 这样子则按几次开始按钮就创建几个相同的线程,控制着相同的数据
385             Thread th = new Thread(bl);
386             th.start();
387         }
388         for (int i = 0; i < Block.type; i++)
389             if (e.getSource().equals(rp.jbt[i])) // 看是画哪个
390             {
391                 bl.reInitRowCol();
392                 bl.drawBlock(i);
393                 lsc.requestFocusInWindow(); // 获得焦点
394                 return;
395             }
396         if (e.getSource().equals(rp.jbt2[0]))
397             bl.leftMove();
398         else if (e.getSource().equals(rp.jbt2[1]))
399             bl.rightMove();
400         else if (e.getSource().equals(rp.jbt2[2]))
401             bl.fallMove();
402         else if (e.getSource().equals(rp.jbt2[3]))
403             bl.leftTurn();
404         lsc.requestFocusInWindow(); // 获得焦点
405     }
406 }
407 
408 class MyKeyAdapter extends KeyAdapter
409 {
410     Block bl;
411 
412     public MyKeyAdapter(Block bl)
413     {
414         this.bl = bl;
415     }
416 
417     public void keyPress

以上是关于java版俄罗斯方块的主要内容,如果未能解决你的问题,请参考以下文章

《游戏学习》Java版俄罗斯方块小游戏源码实战

java的俄罗斯方块代码

求用JAVA编写俄罗斯方块游戏的源代码

DirectX 12 版 俄罗斯方块

C++俄罗斯方块

java写俄罗斯方块啥水平