Adol  
日历
<2024年5月>
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678
统计
  • 随笔 - 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    0x0f000x44440x0f000x4444 },// 长条
 14            0x66000x66000x66000x6600 },// 正方块
 15            0x04e00x04640x00e40x04c4 },// 三角
 16            0x08e00x06440x00e20x044c },// 弯折一下,1、3,1左
 17            0x02e00x04460x00e80x0c44 },// 弯折一下,1、3,1右
 18            0x04620x006c0x04620x006c },// 弯折两下,1、2、1,1左上;1右下
 19            0x02640x00c60x02640x00c6 } // 弯折两下,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(422010)); // 网格布局
327        jp2.setLayout(new GridLayout(422010)); // 网格布局
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(10303030);
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(130130500450);
431        setLayout(new GridLayout(125030));
432        rp = new RightPanel();
433        lsc = new LeftShowCanvas(rp);
434        bl = new Block(lsc);
435        rp.setSize(80400);
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}
posted on 2009-07-29 23:39 Adol 阅读(1070) 评论(0)  编辑  收藏

只有注册用户登录后才能发表评论。


网站导航:
 
 
Copyright © Adol Powered by: 博客园 模板提供:沪江博客