Adol  
          日歷
          <2025年6月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          293012345
          統計
          • 隨筆 - 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 閱讀(1106) 評論(0)  編輯  收藏

          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
           
          Copyright © Adol Powered by: 博客園 模板提供:滬江博客
          主站蜘蛛池模板: 秀山| 肇源县| 郯城县| 海阳市| 双牌县| 灵寿县| 古蔺县| 丹凤县| 左权县| 湘阴县| 绵竹市| 怀安县| 乳山市| 崇州市| 茂名市| 元阳县| 修文县| 龙川县| 子长县| 隆德县| 邢台市| 永昌县| 湘潭市| 象山县| 黄陵县| 利津县| 深水埗区| 齐齐哈尔市| 瓦房店市| 金阳县| 延吉市| 平利县| 磴口县| 临桂县| 无极县| 南昌市| 涟源市| 小金县| 宜兰县| 阜康市| 定结县|