Adol  
          日歷
          <2015年1月>
          28293031123
          45678910
          11121314151617
          18192021222324
          25262728293031
          1234567
          統計
          • 隨筆 - 2
          • 文章 - 6
          • 評論 - 5
          • 引用 - 0

          導航

          常用鏈接

          留言簿(1)

          隨筆檔案

          文章檔案

          搜索

          •  

          最新評論

          閱讀排行榜

          評論排行榜

           
          最近在學習JAVA,就學參考學著寫了一個俄羅斯方塊,代碼有詳細注釋,這里就不多做說明了。
          可以用鍵盤,空格控制,或者用界面上的按鈕。

            1import java.awt.*;
            2import java.awt.event.*;
            3import javax.swing.*;
            4import javax.swing.event.*;
            5
            6class Block implements Runnable// 方塊類
            7{
            8    static final int type = 7, state = 4;
            9
           10    static final int[][] patten = // 16進制代表每種方塊
           11    0x0f000x44440x0f000x4444 },// 長條
           12            0x66000x66000x66000x6600 },// 正方塊
           13            0x04e00x04640x00e40x04c4 },// 三角
           14            0x08e00x06440x00e20x044c },// 彎折一下,1、3,1左
           15            0x02e00x04460x00e80x0c44 },// 彎折一下,1、3,1右
           16            0x04620x006c0x04620x006c },// 彎折兩下,1、2、1,1左上;1右下
           17            0x02640x00c60x02640x00c6 } // 彎折兩下,1、2、1,1右上;1左下
           18    }
          ;
           19
           20    private int blockType = -1// 方塊類型,7種,大小范圍0-6
           21
           22    private int blockState;// 方塊狀態,4種,大小范圍0-3
           23
           24    private int row, col; // 方塊所在的行數,列數
           25
           26    private int oldRow, oldCol; // 記錄方塊變化前所在的行數,列數
           27
           28    private int oldType = -1, oldState; // 記錄方塊變化前的類型和狀態
           29
           30    private int isfall = 1// 標記若畫,畫成什么顏色的,
           31
           32    // 1表示可以下落,畫為紅色;0表示不可下落,畫為藍色
           33
           34    private boolean end = false;// 結束標記,為true時表示結束
           35
           36    LeftShowCanvas lsc;
           37
           38    public Block(LeftShowCanvas lsc)
           39    {
           40        this.lsc = lsc;
           41        row = 0;
           42        col = 3;
           43        oldRow = row;
           44        oldCol = col;
           45    }

           46
           47    public void reInit() // 一個方塊無法下落后,重新初始化
           48    {
           49        blockType = -1;
           50        isfall = 1;
           51    }

           52
           53    public void reInitRowCol() // 初始化方塊起始點
           54    {
           55        row = 0;
           56        col = 3;
           57    }

           58
           59    public void run() // 下落線程
           60    {
           61        lsc.requestFocusInWindow(); // 獲得焦點
           62        while (!end)
           63        {
           64            int blocktype = (int) (Math.random() * 100% 7;
           65            drawBlock(blocktype);
           66            do
           67            {
           68                try
           69                {
           70                    Thread.sleep(500); // 控制下落速度
           71                }
           catch (InterruptedException e)
           72                {
           73
           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
           83    public synchronized void drawBlock(int blockType) // 畫方塊
           84    {
           85        if (this.blockType != blockType)
           86            blockState = (int) (Math.random() * 100% 4// 狀態
           87        this.blockType = blockType; // 樣式
           88        if (!isMove(3)) // 判斷是否能畫
           89        {
           90            this.blockType = oldType;
           91            this.blockState = oldState;
           92            return;
           93        }

           94        int comIndex = 0x8000;
           95        if (this.oldType != -1)
           96        {
           97            for (int i = oldRow; i < oldRow + 4; i++)
           98                for (int j = oldCol; j < oldCol + 4; j++)
           99                {
          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            {
          111                if ((patten[blockType][blockState] & comIndex) != 0)
          112                {
          113                    if (isfall == 1)
          114                        //lsc.drawUnit(i, j, 1); // 再畫,畫為RED
          115                        lsc.unitState[i][j]=1//將狀態記錄改變
          116                    else if (isfall == 0)
          117                    {
          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, 00, lsc);
          131            
          132        if (isfall == 0// 無法下落,先判斷是否能消行,再重新初始化
          133        {
          134            // lsc.deleteFullLine(row,col);
          135            reInit();
          136            reInitRowCol();
          137        }

          138        oldRow = row;
          139        oldCol = col;
          140        oldType = blockType;
          141        oldState = blockState;
          142    }

          143
          144    public void leftTurn() // 旋轉,左轉
          145    {
          146        if (this.blockType != -1)
          147        {
          148            blockState = (blockState + 1% 4;
          149            if (isMove(3))
          150                drawBlock(blockType);
          151            else
          152                blockState = (blockState + 3% 4;
          153        }

          154    }

          155
          156    public void leftMove() // 左移
          157    {
          158        if (this.blockType != -1 && isMove(0))
          159        {
          160            col -= 1;
          161            drawBlock(blockType);
          162        }

          163    }

          164
          165    public void rightMove() // 右移
          166    {
          167        if (this.blockType != -1 && isMove(1))
          168        {
          169            col += 1;
          170            drawBlock(blockType);
          171        }

          172    }

          173
          174    public boolean fallMove() // 下移
          175    {
          176        if (this.blockType != -1)
          177        {
          178            if (isMove(2))
          179            {
          180                row += 1;
          181                drawBlock(blockType);
          182                return true;
          183            }
           else
          184            {
          185                isfall = 0;
          186                drawBlock(blockType);
          187                return false;
          188            }

          189        }

          190        return false;
          191    }

          192
          193    public synchronized boolean isMove(int tag) // 左 0 ,右 1 ,下 2 ,旋轉 3
          194    {
          195        int comIndex = 0x8000;
          196        for (int i = row; i < row + 4; i++)
          197            for (int j = col; j < col + 4; j++)
          198            {
          199                if ((patten[blockType][blockState] & comIndex) != 0)
          200                {
          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
          220class LeftShowCanvas extends Canvas
          221{
          222    int maxrows, maxcols; // 畫布最大行數,列數
          223
          224    int unitSize; // 單元格的大小,小正方格
          225
          226    int[][] unitState; // 每個小方格的狀態 0、1、2表示
          227
          228    RightPanel rp;
          229
          230    int score;
          231
          232    public LeftShowCanvas(RightPanel rp)
          233    {
          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
          243    public void initCanvas() // 初始化,畫布方格
          244    {
          245        for (int i = 0; i < maxrows; i++)
          246            for (int j = 0; j < maxcols; j++)
          247                unitState[i][j] = 0;
          248    }

          249
          250    public void paint(Graphics g)
          251    {
          252        for (int i = 0; i < maxrows; i++)
          253        {
          254            for (int j = 0; j < maxcols; j++)
          255                drawUnit(i, j, unitState[i][j]); // 畫方格
          256            if (i == 3)
          257            {
          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
          265    public void drawUnit(int row, int col, int tag) // 畫方格
          266    {
          267        unitState[row][col] = tag; // 記錄狀態
          268        Graphics g = getGraphics();
          269        switch (tag)
          270        {
          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
          285    public void deleteFullLine(int row) // 判斷此行是否可以消,同時可消就消行
          286    {
          287        for (int j = 0; j < maxcols; j++)
          288            if (unitState[row][j] != 2)
          289                return;
          290
          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
          301class RightPanel extends JPanel
          302{
          303    JButton[] jbt = new JButton[7];
          304
          305    JButton[] jbt2 = new JButton[4];
          306
          307    JButton jbt3;
          308
          309    JTextField jtf;
          310
          311    JLabel jlb;
          312
          313    MyJPanel jp1, jp2;
          314
          315    public RightPanel()
          316    {
          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
          329        jbt3 = new JButton("開始");
          330        jtf = new JTextField("0"5);
          331        jlb = new JLabel("得分", JLabel.CENTER);
          332
          333        jp1 = new MyJPanel(); // 左邊的上面板
          334        jp2 = new MyJPanel(); // 左邊的下面板
          335        jp1.setLayout(new GridLayout(422010)); // 網格布局
          336        jp2.setLayout(new GridLayout(422010)); // 網格布局
          337        this.setLayout(new BorderLayout()); // 邊界布局
          338        for (int i = 0; i < 7; i++)
          339            jp1.add(jbt[i]);
          340
          341        jp1.add(jbt3);
          342
          343        for (int i = 0; i < 4; i++)
          344            jp2.add(jbt2[i]);
          345
          346        jp2.add(jlb);
          347        jp2.add(jtf);
          348
          349        this.add(jp1, "North");
          350        this.add(jp2, "Center");
          351    }

          352}

          353
          354// 重寫MyPanel類,使Panel的四周留空間
          355class MyJPanel extends JPanel
          356{
          357    public Insets getInsets()
          358    {
          359        return new Insets(10303030);
          360    }

          361}

          362
          363class MyActionListener implements ActionListener
          364{
          365    RightPanel rp;
          366
          367    Block bl;
          368
          369    LeftShowCanvas lsc;
          370
          371    public MyActionListener(RightPanel rp, Block bl, LeftShowCanvas lsc)
          372    {
          373        this.rp = rp;
          374        this.bl = bl;
          375        this.lsc = lsc;
          376    }

          377
          378    public void actionPerformed(ActionEvent e)
          379    {
          380        if (e.getSource().equals(rp.jbt3))
          381        {
          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            {
          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
          406class MyKeyAdapter extends KeyAdapter
          407{
          408    Block bl;
          409
          410    public MyKeyAdapter(Block bl)
          411    {
          412        this.bl = bl;
          413    }

          414
          415    public void keyPressed(KeyEvent e)
          416    {
          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
          428public class FinalElsBlock extends JFrame
          429{
          430    Block bl;
          431
          432    LeftShowCanvas lsc;
          433
          434    RightPanel rp;
          435
          436    public FinalElsBlock()
          437    {
          438        super("ELSBlock Study");
          439        setBounds(130130500450);
          440        setLayout(new GridLayout(125030));
          441        rp = new RightPanel();
          442        lsc = new LeftShowCanvas(rp);
          443        bl = new Block(lsc);
          444        rp.setSize(80400);
          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        {
          456            public void windowClosing(WindowEvent e)
          457            {
          458                dispose();
          459                System.exit(0);
          460            }

          461        }
          );
          462        setVisible(true);
          463    }

          464
          465    public static void main(String[] args)
          466    {
          467        new FinalElsBlock();
          468    }

          469}
          posted on 2009-08-12 23:08 Adol 閱讀(45585) 評論(5)  編輯  收藏
          評論:
          • # 下落預測方塊代碼  1094229563@qq.com Posted @ 2014-11-10 21:17
            樓主你好,我也在學習java俄羅斯方塊游戲開發,現在想增加下落預測方塊,帶陰影(方塊還沒落下時,有個影子落在已經落好的方塊上),這個陰影方塊的代碼怎么也不會做,望樓主不吝賜教  回復  更多評論   

          • # re: 一個用JAVA寫的俄羅斯方塊(基本僅代碼&代碼附詳細解釋)  zuidaima Posted @ 2015-01-04 22:36
            俄羅斯方塊游戲源代碼下載:http://zuidaima.com/share/k%E4%BF%84%E7%BD%97%E6%96%AF%E6%96%B9%E5%9D%97-p1-s1.htm  回復  更多評論   

          • # re: 一個用JAVA寫的俄羅斯方塊(基本僅代碼&代碼附詳細解釋)  ewqt Posted @ 2016-02-14 15:24
            sdfwegfwegf  回復  更多評論   

          • # re: 一個用JAVA寫的俄羅斯方塊(基本僅代碼&代碼附詳細解釋)  陌上花開 Posted @ 2016-06-14 10:09
            好像連main方法都沒有啊 怎么運行  回復  更多評論   

          • # re: 一個用JAVA寫的俄羅斯方塊(基本僅代碼&代碼附詳細解釋)[未登錄]  gary Posted @ 2016-08-11 23:50
            @陌上花開 倒數5行啊  回復  更多評論   


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


          網站導航:
           
           
          Copyright © Adol Powered by: 博客園 模板提供:滬江博客
          主站蜘蛛池模板: 聊城市| 桃江县| 房产| 崇信县| 习水县| 贵定县| 迁安市| 从江县| 昭苏县| 兰西县| 双流县| 教育| 黔南| 阿图什市| 泰安市| 眉山市| 伊宁市| 平利县| 曲靖市| 莎车县| 嵩明县| 湖南省| 无棣县| 陵水| 宣威市| 海安县| 呈贡县| 三明市| 黔西县| 黄梅县| 青海省| 遂昌县| 新兴县| 锡林浩特市| 岳普湖县| 长阳| 宜城市| 锡林郭勒盟| 波密县| 蛟河市| 禄丰县|