天天看點

JAVA遊戲程式設計之三----j2se 手機遊戲入門開發--俄羅斯方塊_1

作者:雷神

QQ:38929568

QQ群:28048051JAVA遊戲程式設計(滿) 28047782(滿) 50761834(新開)

聲明:本人發表的代碼全部可以用來學習,如果需要作商業用途,請及時與作者聯系。

本例為J2SE遊戲開發的經典遊戲--俄羅斯方塊,

方向鍵 上下左右ASDW2468都可以遊戲,0更換方塊,1顯示隐藏網格!game over 5鍵重新開始,*退出遊戲

遊戲圖檔:

<a target="_blank" href="http://blog.51cto.com/attachment/201105/165654855.jpg"></a>

代碼如下:

package code;  

import java.awt.*;  

//import java.awt.BorderLayout;  

import java.awt.Canvas;  

import java.awt.event.*;  

import javax.swing.*;  

import java.util.Random;  

/** *//**  

 * 俄羅斯方塊  

 * 高雷  

 * 2007年11月30日  

 */ 

public class Tetris extends Canvas implements Runnable   

...{  

    private Random rand;  

    private Thread thread;  

    private Graphics    gb;  

    private Image        buffer;  

    private Image         gameOverImg;                    //遊戲結束  

    private static final int s_width      = 240;  

    private static final int s_height     = 320;  

    private static final int s_box_w      = 16;  

    private static final int s_box_h      = 16;  

    private static final int s_box_w_sum     = 10;        //操作區域寬 格子數  

    private static final int s_box_h_sum     = 20;        //操作區域高 格子數  

    private static final int s_line_between_x = s_box_w * s_box_w_sum;//分割線x位置  

    public static final int  UP     = -1;  

    public static final int  DOWN     = -2;  

    public static final int  LEFT     = -3;  

    public static final int  RIGHT     = -4;  

    public static final int  init_x         = 3;        //目前方塊初始化坐标X  

    public static final int  init_y         = 0;        //目前方塊初始化坐标y  

    public static int     s_box_x                = init_x;    //目前方塊坐标X  

    public static int     s_box_y                = init_y;    //目前方塊坐标Y  

    private static int    level                = 1;        //等級  

    private static int    success                = 0;        //得分  

    private static long goDownDelayTime[]    = //1800;    //下降延遲時間  

    ...{  

        1000,    900,    800,    700,  

        600,    500,    400,  

        300,    200,    100 

    };  

    private static int    level_up            = (int)(goDownDelayTime[0]-goDownDelayTime[level]);        //更新成績  

    private static boolean isShowReseau        = true;        //是否現實網格  

    private static short s_next_box            = 0;        //下一個方塊編号  

    private static short boxColor;                        //目前box的顔色  

    private static final Color gameBG        = new Color( 0x333333 );    //遊戲區域背景顔色  

    private static final Color gameColor[]    = new Color[]  

        new Color( 0x444444 ),    //網格顔色  

        new Color( 0xEEEEEE ),    //方塊顔色  

        new Color( 0xEE0000 ),  

        new Color( 0x00EE00 ),  

        new Color( 0x0000EE ),  

        new Color( 0xEE00EE ),  

        new Color( 0xEEEE00 ),  

        new Color( 0x00EEEE )  

    private static final short box_sum[][] = new short[][]    //所有方塊圖形  

        ...{ 0x0660, 0x0660, 0x0660, 0x0660 },  

        ...{ 0x2222, 0x00F0, 0x2222, 0x00F0 },  

        ...{ 0x0264, 0x0630, 0x0264, 0x0630 },  

        ...{ 0x0462, 0x0360, 0x0462, 0x0360 },  

        ...{ 0x02E0, 0x4460, 0x0740, 0x0622 },  

        ...{ 0x0E20, 0x2260, 0x0470, 0x0644 },  

        ...{ 0x0464, 0x00E4, 0x04C4, 0x04E0 }  

    private static short next_box[] = new short[]...{ 0x0660, 0x0660, 0x0660, 0x0660 };   

    private static short box[]          = new short[]...{ 0x0660, 0x0660, 0x0660, 0x0660 };  

    private static short map[][];        //地圖  

    private static short box_state  = 0;//目前BOX的狀态//旋轉方向  

    private static short matrix[][] =    //定義矩陣用來計算出box_sum的方塊  

        ...{ 0x1000, 0x0100, 0x0010, 0x0001 },  

        ...{ 0x2000, 0x0200, 0x0020, 0x0002 },  

        ...{ 0x4000, 0x0400, 0x0040, 0x0004 },  

        ...{ (short)0x8000, 0x0800, 0x0080, 0x0008 }  

    public Tetris()  

        rand = new Random( System.currentTimeMillis() );  

        try 

        ...{  

            gameOverImg = Toolkit.getDefaultToolkit().getImage("src/pics/laser.png");  

        }catch(Exception e)...{}  

        setSize( s_width, s_height );    //設定畫布  

        initGame();                        //遊戲初始化  

        thread  = new Thread(this);  

        thread.start();  

    }  

    private void initGame()  

        level        = 1;                //等級  

        success        = 0;                //得分  

        map     = new short[s_box_h_sum][s_box_w_sum];  

        setNextBox();                    //設定下一個BOX  

        setBox();                        //将下一個BOX設定成目前BOX  

        setGameOver( false );            //恢複遊戲  

    private void setBox()                //将next_box設定成目前可控制box  

        box_state         = 0;                                        //box 狀态  

        s_box_x            = init_x;                                    //目前方塊坐标X  

        s_box_y            = init_y;                                    //目前方塊坐标Y  

        boxColor        = s_next_box;                                //設定目前BOX顔色  

        System.arraycopy( next_box, 0, box, 0, next_box.length );    //box = next_box  

        goDownPreTime     = System.currentTimeMillis();                //設定好目前BOX後 計時  

        setNextBox();                                                //設定下一個BOX  

        if( !isCanMove() )  

            setGameOver( true );  

        }  

    public static boolean isGameOver = false;  

    public static long updatas     = 0;  

    public static long fps         = 0;  

    private long     startTime, beginTime, endTime;  

    private long     delay         = 25;  

    private long     upTime         = 25;  

    public void run()   

        while ( true )   

            try 

            ...{  

                beginTime = System.currentTimeMillis();  

                updatas++;  

                updata( updatas );  

                repaint();  

                endTime = System.currentTimeMillis();  

                upTime  = endTime-beginTime;  

                if( upTime&lt;delay )  

                ...{  

                    fps = 1000/delay;  

                    thread.sleep(delay-upTime);  

                }  

                else 

                    fps = 1000/upTime;  

            }catch(Exception e)...{ }  

    void setGameOver( boolean _isGameOver )  

        isGameOver = _isGameOver;  

    public void updata( long updatas )  

    public void update(Graphics g)   

        paint(g);  

    public static int     offx     = 2;  

    public static int     offy     = 2;  

    public void paint(Graphics g)  

            if( buffer == null )  

                buffer = createImage( s_width, s_height );    //設定畫布緩沖區  

                gb = buffer.getGraphics();                    //得到繪圖裝置  

            }  

//            gb.translate( offx, offy );  

            gb.setColor( new Color( 0x0 ) );                //初始化 畫布顔色  

            gb.setClip ( 0, 0, s_width, s_height);            //初始化 畫布區域  

            gb.fillRect( 0, 0, s_width, s_height);            //初始化 畫布填充  

            paintReseau( gb );                                //繪制網格  

            paintNextBox( gb );                                //繪制下一BOX  

            paintMap( gb );                                    //繪制地圖上不可以動BOX  

            paintBox( gb, s_box_x, s_box_y );                //繪制目前可控制BOX  

            gb.setColor( new Color( 0xFF3333 ) );                            //分割線顔色  

            gb.drawLine( s_line_between_x, 0, s_line_between_x, s_height );    //分割線  

            gb.drawString( "FPS:"+fps,             s_line_between_x+10,10 );    //祯數  

            gb.drawString( "等級:"+level,         s_line_between_x+10,30 );    //等級  

            gb.drawString( "得分:"+success,         s_line_between_x+10,50 );    //分數  

            if( isGameOver )  

                gb.drawImage( gameOverImg, (getWidth()-offx-gameOverImg.getWidth(null))/2, (getHeight()-gameOverImg.getHeight(null))/2 , null );  

//            gb.translate( -offx, -offy );  

        catch(Exception e)  

        ...{   

            System.out.println("err at paint.e====="+e);  

        g.drawImage( buffer, offx, offy, null);                    //将畫布緩沖區繪制到螢幕//偏移 (2,2)  

    private void paintReseau( Graphics g )                    //繪制網格  

        g.setColor( gameBG );  

        g.fillRect( 0, 0, s_line_between_x, s_height );  

        if( isShowReseau )  

            g.setColor( gameColor[0] );  

            for( int i=0; i&lt;s_line_between_x/s_box_w; i++ )    // |  

                g.drawLine( i*s_box_h, 0, i*s_box_h, s_height );  

            for( int j=0; j&lt;s_height/s_box_h; j++ )            // -  

                g.drawLine( 0, j*s_box_w, s_line_between_x, j*s_box_w );  

    private void paintBox( Graphics g, int off_x, int off_y )  

        for( int i=0; i&lt;4; i++ )        //行  

            for( int j=0; j&lt;4; j++ )    //列  

                if( (box[box_state] &amp; matrix[i][j]) == matrix[i][j] )  

                    g.setColor( gameColor[ boxColor ] );  

                    g.fillRect( (off_x+j)*s_box_w, (off_y+i)*s_box_h, s_box_w, s_box_h );  

                    g.setColor( gameBG );  

                    g.drawRect( (off_x+j)*s_box_w+1, (off_y+i)*s_box_h+1, s_box_w-2, s_box_h-2 );  

        goDown();                        //BOX是否下降  

    private void paintNextBox( Graphics g )  

        int off_x = s_line_between_x+( s_width - s_line_between_x - 4*s_box_w )/2;  

        int off_y = s_height/2;  

        g.translate( off_x, off_y );  

        g.fillRect( 0, 0, 4*s_box_w, 4*s_box_h );  

        if( isShowReseau )                //顯示格式  

            for( int i=0; i&lt;5; i++ )    // |  

                g.drawLine( i*s_box_h, 0, i*s_box_h, 4*s_box_h );  

            for( int j=0; j&lt;5; j++ )    // -  

                g.drawLine( 0, j*s_box_w, 4*s_box_w, j*s_box_w );  

                if( (next_box[0] &amp; matrix[i][j]) == matrix[i][j] )  

                    g.setColor( gameColor[ s_next_box ] );  

                    g.fillRect( j*s_box_w, i*s_box_h, s_box_w, s_box_h );  

                    g.drawRect( j*s_box_w+1, i*s_box_h+1, s_box_w-2, s_box_h-2 );  

        g.translate( -off_x, -off_y );  

    private long goDownPreTime     = 0;    //上次下降時間  

    private long currTime         = 0;    //目前時間  

    private void goDown()                //目前BOX下降  

        if( isGameOver )    //遊戲結束  

            return;  

        //isKeyDown按了向下移動就需要檢查 不需要時間  

        if( isKeyDown==1 || System.currentTimeMillis() - goDownPreTime &gt;= goDownDelayTime[level] )  

            s_box_y++;  

            goDownPreTime = System.currentTimeMillis();  

            if( !isCanMove() )  

                isKeyDown = 0;    //沒有按下  

                s_box_y--;  

                setMap();        //将BOX放進map   

                setBox();        //新的BOX  

    private void setMap()  

                if( ( box[box_state] &amp; matrix[i][j] ) == matrix[i][j] )    //是格子  

                    map[s_box_y+i][s_box_x+j] = boxColor;  

        //檢測是否可以消去一行  

        int line_success = 0;  

        for( int i=0; i&lt;s_box_h_sum; i++ )        //行  

            if( isFullLine( i ) )                //這行可以消去  

                setNullLine( i );                //設定第i行為空  

                setGoDownMap( i );                //地圖第i行以上的向下移動一行  

                line_success++;  

        success += line_success*line_success;    //設定得分  

        level_up = (int)(goDownDelayTime[0]-goDownDelayTime[level]);  

        if( success &gt;= level_up )                //設定更新  

            level %= goDownDelayTime.length;  

            level ++;  

    private void paintMap( Graphics g )  

            for( int j=0; j&lt;s_box_w_sum; j++ )    //列  

                if( map[i][j] &gt; 0 )                //是格子//繪制格子  

                    g.setColor( gameColor[ map[i][j] ] );  

                    g.fillRect( j*s_box_w, i*s_box_h, s_box_w, s_box_h );      

    private boolean isFullLine(int line)    //是否一行已經滿了  

        for( int j=0; j&lt;s_box_w_sum; j++ )    //列  

            if( map[line][j] &lt;= 0 )  

                return false;  

        return true;  

    private void  setNullLine( int line )    //設定地圖上的這一行 空  

            map[line][j] = 0;  

        }      

    private void setGoDownMap( int line )    //設定地圖line以上的每行都向下移動一行  

        for( int i=line; i&gt;0; i-- )            //行  

                map[i][j] = map[i-1][j];     //向下移動一行  

    private boolean isCanMove()  

                    if( s_box_x+j &lt; 0 )                //左邊界檢測  

                    ...{  

                        System.out.println( "left s_box_x="+s_box_x+" matrix["+i+"]["+j+"]="+matrix[i][j]);  

                        return false;  

                    }  

                    if( s_box_x+j &gt; s_box_w_sum-1 )    //右邊界檢測  

                        System.out.println( "right s_box_x="+s_box_x+" matrix["+i+"]["+j+"]="+matrix[i][j]);  

                    if( s_box_y+i &gt; s_box_h_sum-1 )    //下邊界檢測  

                        System.out.println( "down s_box_y="+s_box_y+" matrix["+i+"]["+j+"]="+matrix[i][j]);  

                    //地圖格子檢測  

                    if( map[s_box_y+i][s_box_x+j] &gt; 0 )  

    private short isKeyDown = 0;    //0沒有按下,1按下,2擡起  

    public boolean keyDown(Event evt, int key)  

        key = getKeyCode( key );  

        switch( key )  

            case UP:                //順時針旋轉  

                isKeyDown = 0;        //0沒有按下  

                box_state ++;  

                box_state %= 4;  

                if( !isCanMove() )  

                    box_state --;  

                    if( box_state&lt;0 )  

                        box_state = 3;  

            break;  

            case DOWN:                //向下移動  

                if( isKeyDown == 2 )  

                    isKeyDown = 1;  

                if( isKeyDown == 1 )  

                    s_box_y ++;   

                    if( !isCanMove() )  

                        s_box_y --;  

            case LEFT:                //向左移動BOX  

                s_box_x --;  

                    s_box_x ++;      

            case RIGHT:                //向右移動BOX  

                s_box_x ++;  

                    s_box_x --;  

            case 53:                //數字5鍵  

                if( isGameOver )    //遊戲結束  

                    initGame();        //重新遊戲  

            case 42:  

                    System.exit(0);    //退出遊戲  

            case 48:  

                setBox();            //新的BOX  

            case 49:                //是否顯示網格  

                isShowReseau = !isShowReseau;  

        repaint();                    //重新繪制螢幕  

    public void setNextBox()  

        s_next_box = (short)rand.nextInt( box_sum.length );  

        System.arraycopy( box_sum[s_next_box], 0, next_box, 0, next_box.length );  

        s_next_box++;  

    private int getKeyCode( int key )  

        System.out.println( "key="+key );  

            case 1004:     // up  

            case 119:     // w  

            case 87:     // W  

            case 50:     // 2  

            return UP;  

            case 1005:     // down  

            case 115:     // s  

            case 83:     // S  

            case 56:     // 8  

            return DOWN;  

            case 1006:     // left  

            case 97:     // a  

            case 65:     // A  

            case 52:     // 4  

            return LEFT;  

            case 1007:     // right  

            case 100:     // d  

            case 68:     // D  

            case 54:     // 6  

            return RIGHT;  

            default:  

            return key;  

    public boolean keyUp(Event evt, int key)   

        isKeyDown = 2;    //釋放按鍵  

//    public boolean mouseDown(Event evt, int x, int y)  

//    {  

//        try  

//        {  

////            System.out.println( "x="+x+" y="+y );  

//        }catch( Exception e){e.printStackTrace();}  

////        this.repaint();  

//        return true;  

//    }  

//    public boolean mouseMove(Event evt, int x, int y)  

//            //System.out.println( "x="+x+" y="+y );  

    public static void main(String[] args)   

        JFrame frame = new JFrame("俄羅斯方塊 北京|雷神 QQ:38929568");  

        final Tetris dc = new Tetris();  

        frame.getContentPane().add(dc, BorderLayout.CENTER);  

//        JButton button = new JButton("重新整理");  

//        button.addActionListener(new ActionListener()   

//            public void actionPerformed(ActionEvent e)   

//            {  

//                dc.repaint();  

//            }  

//        });  

//        frame.getContentPane().add(button, BorderLayout.SOUTH);  

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  

        frame.setSize(dc.s_width+10, dc.s_height+30);  

        frame.setVisible(true);  

<a href="http://down.51cto.com/data/2358281" target="_blank">附件:http://down.51cto.com/data/2358281</a>

本文轉自 kome2000 51CTO部落格,原文連結:http://blog.51cto.com/kome2000/578533