天天看点

JAVA游戏编程之三----j2se 手机游戏入门开发--俄罗斯方块_1

作者:雷神

声明:本人发表的代码全部可以用来学习,如果需要作商业用途,请及时与作者联系。

本例为J2SE游戏开发的经典游戏--俄罗斯方块,

方向键 上下左右ASDW2468都可以游戏,0更换方块,1显示隐藏网格!game over 5键重新开始,*退出游戏

游戏图片:

工程文件如附件所示,地址如下:方块1

  1. package code;  
  2. import java.awt.*;  
  3. //import java.awt.BorderLayout;  
  4. import java.awt.Canvas;  
  5. import java.awt.event.*;  
  6. import javax.swing.*;  
  7. import java.util.Random;  
  8. /** *//**  
  9.  * 俄罗斯方块  
  10.  * 高雷  
  11.  * 2007年11月30日  
  12.  */ 
  13. public class Tetris extends Canvas implements Runnable   
  14. ...{  
  15.     private Random rand;  
  16.     private Thread thread;  
  17.     private Graphics    gb;  
  18.     private Image        buffer;  
  19.     private Image         gameOverImg;                    //游戏结束  
  20.     private static final int s_width      = 240;  
  21.     private static final int s_height     = 320;  
  22.     private static final int s_box_w      = 16;  
  23.     private static final int s_box_h      = 16;  
  24.     private static final int s_box_w_sum     = 10;        //操作区域宽 格子数  
  25.     private static final int s_box_h_sum     = 20;        //操作区域高 格子数  
  26.     private static final int s_line_between_x = s_box_w * s_box_w_sum;//分割线x位置  
  27.     public static final int  UP     = -1;  
  28.     public static final int  DOWN     = -2;  
  29.     public static final int  LEFT     = -3;  
  30.     public static final int  RIGHT     = -4;  
  31.     public static final int  init_x         = 3;        //当前方块初始化坐标X  
  32.     public static final int  init_y         = 0;        //当前方块初始化坐标y  
  33.     public static int     s_box_x                = init_x;    //当前方块坐标X  
  34.     public static int     s_box_y                = init_y;    //当前方块坐标Y  
  35.     private static int    level                = 1;        //等级  
  36.     private static int    success                = 0;        //得分  
  37.     private static long goDownDelayTime[]    = //1800;    //下降延迟时间  
  38.     ...{  
  39.         1000,    900,    800,    700,  
  40.         600,    500,    400,  
  41.         300,    200,    100 
  42.     };  
  43.     private static int    level_up            = (int)(goDownDelayTime[0]-goDownDelayTime[level]);        //升级成绩  
  44.     private static boolean isShowReseau        = true;        //是否现实网格  
  45.     private static short s_next_box            = 0;        //下一个方块编号  
  46.     private static short boxColor;                        //当前box的颜色  
  47.     private static final Color gameBG        = new Color( 0x333333 );    //游戏区域背景颜色  
  48.     private static final Color gameColor[]    = new Color[]  
  49.         new Color( 0x444444 ),    //网格颜色  
  50.         new Color( 0xEEEEEE ),    //方块颜色  
  51.         new Color( 0xEE0000 ),  
  52.         new Color( 0x00EE00 ),  
  53.         new Color( 0x0000EE ),  
  54.         new Color( 0xEE00EE ),  
  55.         new Color( 0xEEEE00 ),  
  56.         new Color( 0x00EEEE )  
  57.     private static final short box_sum[][] = new short[][]    //所有方块图形  
  58.         ...{ 0x0660, 0x0660, 0x0660, 0x0660 },  
  59.         ...{ 0x2222, 0x00F0, 0x2222, 0x00F0 },  
  60.         ...{ 0x0264, 0x0630, 0x0264, 0x0630 },  
  61.         ...{ 0x0462, 0x0360, 0x0462, 0x0360 },  
  62.         ...{ 0x02E0, 0x4460, 0x0740, 0x0622 },  
  63.         ...{ 0x0E20, 0x2260, 0x0470, 0x0644 },  
  64.         ...{ 0x0464, 0x00E4, 0x04C4, 0x04E0 }  
  65.     private static short next_box[] = new short[]...{ 0x0660, 0x0660, 0x0660, 0x0660 };   
  66.     private static short box[]          = new short[]...{ 0x0660, 0x0660, 0x0660, 0x0660 };  
  67.     private static short map[][];        //地图  
  68.     private static short box_state  = 0;//当前BOX的状态//旋转方向  
  69.     private static short matrix[][] =    //定义矩阵用来计算出box_sum的方块  
  70.         ...{ 0x1000, 0x0100, 0x0010, 0x0001 },  
  71.         ...{ 0x2000, 0x0200, 0x0020, 0x0002 },  
  72.         ...{ 0x4000, 0x0400, 0x0040, 0x0004 },  
  73.         ...{ (short)0x8000, 0x0800, 0x0080, 0x0008 }  
  74.     public Tetris()  
  75.         rand = new Random( System.currentTimeMillis() );  
  76.         try 
  77.         ...{  
  78.             gameOverImg = Toolkit.getDefaultToolkit().getImage("src/pics/laser.png");  
  79.         }catch(Exception e)...{}  
  80.         setSize( s_width, s_height );    //设置画布  
  81.         initGame();                        //游戏初始化  
  82.         thread  = new Thread(this);  
  83.         thread.start();  
  84.     }  
  85.     private void initGame()  
  86.         level        = 1;                //等级  
  87.         success        = 0;                //得分  
  88.         map     = new short[s_box_h_sum][s_box_w_sum];  
  89.         setNextBox();                    //设置下一个BOX  
  90.         setBox();                        //将下一个BOX设置成当前BOX  
  91.         setGameOver( false );            //恢复游戏  
  92.     private void setBox()                //将next_box设置成当前可控制box  
  93.         box_state         = 0;                                        //box 状态  
  94.         s_box_x            = init_x;                                    //当前方块坐标X  
  95.         s_box_y            = init_y;                                    //当前方块坐标Y  
  96.         boxColor        = s_next_box;                                //设置当前BOX颜色  
  97.         System.arraycopy( next_box, 0, box, 0, next_box.length );    //box = next_box  
  98.         goDownPreTime     = System.currentTimeMillis();                //设置好当前BOX后 计时  
  99.         setNextBox();                                                //设置下一个BOX  
  100.         if( !isCanMove() )  
  101.             setGameOver( true );  
  102.         }  
  103.     public static boolean isGameOver = false;  
  104.     public static long updatas     = 0;  
  105.     public static long fps         = 0;  
  106.     private long     startTime, beginTime, endTime;  
  107.     private long     delay         = 25;  
  108.     private long     upTime         = 25;  
  109.     public void run()   
  110.         while ( true )   
  111.             try 
  112.             ...{  
  113.                 beginTime = System.currentTimeMillis();  
  114.                 updatas++;  
  115.                 updata( updatas );  
  116.                 repaint();  
  117.                 endTime = System.currentTimeMillis();  
  118.                 upTime  = endTime-beginTime;  
  119.                 if( upTime<delay )  
  120.                 ...{  
  121.                     fps = 1000/delay;  
  122.                     thread.sleep(delay-upTime);  
  123.                 }  
  124.                 else 
  125.                     fps = 1000/upTime;  
  126.             }catch(Exception e)...{ }  
  127.     void setGameOver( boolean _isGameOver )  
  128.         isGameOver = _isGameOver;  
  129.     public void updata( long updatas )  
  130.     public void update(Graphics g)   
  131.         paint(g);  
  132.     public static int     offx     = 2;  
  133.     public static int     offy     = 2;  
  134.     public void paint(Graphics g)  
  135.             if( buffer == null )  
  136.                 buffer = createImage( s_width, s_height );    //设置画布缓冲区  
  137.                 gb = buffer.getGraphics();                    //得到绘图设备  
  138.             }  
  139. //            gb.translate( offx, offy );  
  140.             gb.setColor( new Color( 0x0 ) );                //初始化 画布颜色  
  141.             gb.setClip ( 0, 0, s_width, s_height);            //初始化 画布区域  
  142.             gb.fillRect( 0, 0, s_width, s_height);            //初始化 画布填充  
  143.             paintReseau( gb );                                //绘制网格  
  144.             paintNextBox( gb );                                //绘制下一BOX  
  145.             paintMap( gb );                                    //绘制地图上不可以动BOX  
  146.             paintBox( gb, s_box_x, s_box_y );                //绘制当前可控制BOX  
  147.             gb.setColor( new Color( 0xFF3333 ) );                            //分割线颜色  
  148.             gb.drawLine( s_line_between_x, 0, s_line_between_x, s_height );    //分割线  
  149.             gb.drawString( "FPS:"+fps,             s_line_between_x+10,10 );    //祯数  
  150.             gb.drawString( "等级:"+level,         s_line_between_x+10,30 );    //等级  
  151.             gb.drawString( "得分:"+success,         s_line_between_x+10,50 );    //分数  
  152.             if( isGameOver )  
  153.                 gb.drawImage( gameOverImg, (getWidth()-offx-gameOverImg.getWidth(null))/2, (getHeight()-gameOverImg.getHeight(null))/2 , null );  
  154. //            gb.translate( -offx, -offy );  
  155.         catch(Exception e)  
  156.         ...{   
  157.             System.out.println("err at paint.e====="+e);  
  158.         g.drawImage( buffer, offx, offy, null);                    //将画布缓冲区绘制到屏幕//偏移 (2,2)  
  159.     private void paintReseau( Graphics g )                    //绘制网格  
  160.         g.setColor( gameBG );  
  161.         g.fillRect( 0, 0, s_line_between_x, s_height );  
  162.         if( isShowReseau )  
  163.             g.setColor( gameColor[0] );  
  164.             for( int i=0; i<s_line_between_x/s_box_w; i++ )    // |  
  165.                 g.drawLine( i*s_box_h, 0, i*s_box_h, s_height );  
  166.             for( int j=0; j<s_height/s_box_h; j++ )            // -  
  167.                 g.drawLine( 0, j*s_box_w, s_line_between_x, j*s_box_w );  
  168.     private void paintBox( Graphics g, int off_x, int off_y )  
  169.         for( int i=0; i<4; i++ )        //行  
  170.             for( int j=0; j<4; j++ )    //列  
  171.                 if( (box[box_state] & matrix[i][j]) == matrix[i][j] )  
  172.                     g.setColor( gameColor[ boxColor ] );  
  173.                     g.fillRect( (off_x+j)*s_box_w, (off_y+i)*s_box_h, s_box_w, s_box_h );  
  174.                     g.setColor( gameBG );  
  175.                     g.drawRect( (off_x+j)*s_box_w+1, (off_y+i)*s_box_h+1, s_box_w-2, s_box_h-2 );  
  176.         goDown();                        //BOX是否下降  
  177.     private void paintNextBox( Graphics g )  
  178.         int off_x = s_line_between_x+( s_width - s_line_between_x - 4*s_box_w )/2;  
  179.         int off_y = s_height/2;  
  180.         g.translate( off_x, off_y );  
  181.         g.fillRect( 0, 0, 4*s_box_w, 4*s_box_h );  
  182.         if( isShowReseau )                //显示格式  
  183.             for( int i=0; i<5; i++ )    // |  
  184.                 g.drawLine( i*s_box_h, 0, i*s_box_h, 4*s_box_h );  
  185.             for( int j=0; j<5; j++ )    // -  
  186.                 g.drawLine( 0, j*s_box_w, 4*s_box_w, j*s_box_w );  
  187.                 if( (next_box[0] & matrix[i][j]) == matrix[i][j] )  
  188.                     g.setColor( gameColor[ s_next_box ] );  
  189.                     g.fillRect( j*s_box_w, i*s_box_h, s_box_w, s_box_h );  
  190.                     g.drawRect( j*s_box_w+1, i*s_box_h+1, s_box_w-2, s_box_h-2 );  
  191.         g.translate( -off_x, -off_y );  
  192.     private long goDownPreTime     = 0;    //上次下降时间  
  193.     private long currTime         = 0;    //当前时间  
  194.     private void goDown()                //当前BOX下降  
  195.         if( isGameOver )    //游戏结束  
  196.             return;  
  197.         //isKeyDown按了向下移动就需要检查 不需要时间  
  198.         if( isKeyDown==1 || System.currentTimeMillis() - goDownPreTime >= goDownDelayTime[level] )  
  199.             s_box_y++;  
  200.             goDownPreTime = System.currentTimeMillis();  
  201.             if( !isCanMove() )  
  202.                 isKeyDown = 0;    //没有按下  
  203.                 s_box_y--;  
  204.                 setMap();        //将BOX放进map   
  205.                 setBox();        //新的BOX  
  206.     private void setMap()  
  207.                 if( ( box[box_state] & matrix[i][j] ) == matrix[i][j] )    //是格子  
  208.                     map[s_box_y+i][s_box_x+j] = boxColor;  
  209.         //检测是否可以消去一行  
  210.         int line_success = 0;  
  211.         for( int i=0; i<s_box_h_sum; i++ )        //行  
  212.             if( isFullLine( i ) )                //这行可以消去  
  213.                 setNullLine( i );                //设置第i行为空  
  214.                 setGoDownMap( i );                //地图第i行以上的向下移动一行  
  215.                 line_success++;  
  216.         success += line_success*line_success;    //设置得分  
  217.         level_up = (int)(goDownDelayTime[0]-goDownDelayTime[level]);  
  218.         if( success >= level_up )                //设置升级  
  219.             level %= goDownDelayTime.length;  
  220.             level ++;  
  221.     private void paintMap( Graphics g )  
  222.             for( int j=0; j<s_box_w_sum; j++ )    //列  
  223.                 if( map[i][j] > 0 )                //是格子//绘制格子  
  224.                     g.setColor( gameColor[ map[i][j] ] );  
  225.                     g.fillRect( j*s_box_w, i*s_box_h, s_box_w, s_box_h );      
  226.     private boolean isFullLine(int line)    //是否一行已经满了  
  227.         for( int j=0; j<s_box_w_sum; j++ )    //列  
  228.             if( map[line][j] <= 0 )  
  229.                 return false;  
  230.         return true;  
  231.     private void  setNullLine( int line )    //设置地图上的这一行 空  
  232.             map[line][j] = 0;  
  233.         }      
  234.     private void setGoDownMap( int line )    //设置地图line以上的每行都向下移动一行  
  235.         for( int i=line; i>0; i-- )            //行  
  236.                 map[i][j] = map[i-1][j];     //向下移动一行  
  237.     private boolean isCanMove()  
  238.                     if( s_box_x+j < 0 )                //左边界检测  
  239.                     ...{  
  240.                         System.out.println( "left s_box_x="+s_box_x+" matrix["+i+"]["+j+"]="+matrix[i][j]);  
  241.                         return false;  
  242.                     }  
  243.                     if( s_box_x+j > s_box_w_sum-1 )    //右边界检测  
  244.                         System.out.println( "right s_box_x="+s_box_x+" matrix["+i+"]["+j+"]="+matrix[i][j]);  
  245.                     if( s_box_y+i > s_box_h_sum-1 )    //下边界检测  
  246.                         System.out.println( "down s_box_y="+s_box_y+" matrix["+i+"]["+j+"]="+matrix[i][j]);  
  247.                     //地图格子检测  
  248.                     if( map[s_box_y+i][s_box_x+j] > 0 )  
  249.     private short isKeyDown = 0;    //0没有按下,1按下,2抬起  
  250.     public boolean keyDown(Event evt, int key)  
  251.         key = getKeyCode( key );  
  252.         switch( key )  
  253.             case UP:                //顺时针旋转  
  254.                 isKeyDown = 0;        //0没有按下  
  255.                 box_state ++;  
  256.                 box_state %= 4;  
  257.                 if( !isCanMove() )  
  258.                     box_state --;  
  259.                     if( box_state<0 )  
  260.                         box_state = 3;  
  261.             break;  
  262.             case DOWN:                //向下移动  
  263.                 if( isKeyDown == 2 )  
  264.                     isKeyDown = 1;  
  265.                 if( isKeyDown == 1 )  
  266.                     s_box_y ++;   
  267.                     if( !isCanMove() )  
  268.                         s_box_y --;  
  269.             case LEFT:                //向左移动BOX  
  270.                 s_box_x --;  
  271.                     s_box_x ++;      
  272.             case RIGHT:                //向右移动BOX  
  273.                 s_box_x ++;  
  274.                     s_box_x --;  
  275.             case 53:                //数字5键  
  276.                 if( isGameOver )    //游戏结束  
  277.                     initGame();        //重新游戏  
  278.             case 42:  
  279.                     System.exit(0);    //退出游戏  
  280.             case 48:  
  281.                 setBox();            //新的BOX  
  282.             case 49:                //是否显示网格  
  283.                 isShowReseau = !isShowReseau;  
  284.         repaint();                    //重新绘制屏幕  
  285.     public void setNextBox()  
  286.         s_next_box = (short)rand.nextInt( box_sum.length );  
  287.         System.arraycopy( box_sum[s_next_box], 0, next_box, 0, next_box.length );  
  288.         s_next_box++;  
  289.     private int getKeyCode( int key )  
  290.         System.out.println( "key="+key );  
  291.             case 1004:     // up  
  292.             case 119:     // w  
  293.             case 87:     // W  
  294.             case 50:     // 2  
  295.             return UP;  
  296.             case 1005:     // down  
  297.             case 115:     // s  
  298.             case 83:     // S  
  299.             case 56:     // 8  
  300.             return DOWN;  
  301.             case 1006:     // left  
  302.             case 97:     // a  
  303.             case 65:     // A  
  304.             case 52:     // 4  
  305.             return LEFT;  
  306.             case 1007:     // right  
  307.             case 100:     // d  
  308.             case 68:     // D  
  309.             case 54:     // 6  
  310.             return RIGHT;  
  311.             default:  
  312.             return key;  
  313.     public boolean keyUp(Event evt, int key)   
  314.         isKeyDown = 2;    //释放按键  
  315. //    public boolean mouseDown(Event evt, int x, int y)  
  316. //    {  
  317. //        try  
  318. //        {  
  319. ////            System.out.println( "x="+x+" y="+y );  
  320. //        }catch( Exception e){e.printStackTrace();}  
  321. ////        this.repaint();  
  322. //        return true;  
  323. //    }  
  324. //    public boolean mouseMove(Event evt, int x, int y)  
  325. //            //System.out.println( "x="+x+" y="+y );  
  326.     public static void main(String[] args)   
  327.         JFrame frame = new JFrame("俄罗斯方块 北京|雷神 QQ:38929568");  
  328.         final Tetris dc = new Tetris();  
  329.         frame.getContentPane().add(dc, BorderLayout.CENTER);  
  330. //        JButton button = new JButton("刷新");  
  331. //        button.addActionListener(new ActionListener()   
  332. //            public void actionPerformed(ActionEvent e)   
  333. //            {  
  334. //                dc.repaint();  
  335. //            }  
  336. //        });  
  337. //        frame.getContentPane().add(button, BorderLayout.SOUTH);  
  338.         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
  339.         frame.setSize(dc.s_width+10, dc.s_height+30);  
  340.         frame.setVisible(true);