作者:雷神
QQ:38929568
QQ群:28048051JAVA游戏编程(满) 28047782(满) 50761834(忙)  31572546(新)
手机游戏开发职业群51871468(,非从事手机开发者勿进!欢迎测试策划美工程序)

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

本例为J2SE游戏开发的经典游戏--俄罗斯方块,手机移植版本176*220屏幕手机可用!
记录函数在主midlet类!

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

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

游戏图片:

JAVA游戏编程之三----j2me 手机游戏入门开发--俄罗斯方块_3_增加成绩记录_手机游戏

cGame176x220.java 主要绘图类

  1. package code;  
  2.  
  3. //import java.awt.*;  
  4. //import java.awt.Canvas;  
  5. //import java.awt.event.*;  
  6. //import javax.swing.*;  
  7. import java.util.Random;  
  8. import javax.microedition.lcdui.*;            //写界面所需要的包  
  9. /** *//**  
  10.  * 俄罗斯方块  
  11.  * 高雷  
  12.  * 2007年11月30日  
  13.  */ 
  14. public class cGame176x220 extends Canvas implements Runnable   
  15. ...{  
  16.     private Random rand;  
  17.     private Thread thread;  
  18.     private Graphics    gb;  
  19.     private Image        buffer;  
  20.     private Image         gameOverImg;                    //游戏结束  
  21.     private static final int s_width      = 176;  
  22.     private static final int s_height     = 220;  
  23.     private static final int s_box_w      = 12;  
  24.     private static final int s_box_h      = 12;  
  25.     private static final int s_box_w_sum     = 10;        //操作区域宽 格子数  
  26.     private static final int s_box_h_sum     = 18;        //操作区域高 格子数  
  27.     private static final int offx     = 0;                //  
  28.     private static final int offy     = -(s_height-s_box_h_sum*s_box_h);//控制区偏移  
  29.     private static final int s_line_between_x = s_box_w * s_box_w_sum;//分割线x位置  
  30.  
  31.     public static final int  UP     = -1;  
  32.     public static final int  DOWN     = -2;  
  33.     public static final int  LEFT     = -3;  
  34.     public static final int  RIGHT     = -4;  
  35.       
  36.     public static final int  init_x         = 3;        //当前方块初始化坐标X  
  37.     public static final int  init_y         = 0;        //当前方块初始化坐标y  
  38.       
  39.     public static int     s_box_x                = init_x;    //当前方块坐标X  
  40.     public static int     s_box_y                = init_y;    //当前方块坐标Y  
  41.     private static int    level                = 1;        //等级  
  42.     private static int    success                = 0;        //得分  
  43.     private static long goDownDelayTime[]    = //1800;    //下降延迟时间  
  44.     ...{  
  45.         1000,    900,    800,    700,  
  46.         600,    500,    400,  
  47.         300,    200,    100 
  48.     };  
  49.     private static int    level_up            = (int)(goDownDelayTime[0]-goDownDelayTime[level]);        //升级成绩  
  50.     private static boolean isShowReseau        = true;        //是否现实网格  
  51.     private static short s_next_box            = 0;        //下一个方块编号  
  52.     private static short boxColor;                        //当前box的颜色  
  53. //    private static final Color gameBG        = new Color( 0x333333 );    //游戏区域背景颜色  
  54.     private static final int gameBG            = 0x333333;    //游戏区域背景颜色  
  55. //    private static final Color gameColor[]    = new Color[]  
  56.     private static final int gameColor[]    = new int[]  
  57.     ...{  
  58.         0x444444,    //new Color( 0x444444 ),    //网格颜色  
  59.         0xEEEEEE,    //new Color( 0xEEEEEE ),    //方块颜色  
  60.         0xEE0000,    //new Color( 0xEE0000 ),  
  61.         0x00EE00,    //new Color( 0x00EE00 ),  
  62.         0x0000EE,    //new Color( 0x0000EE ),  
  63.         0xEE00EE,    //new Color( 0xEE00EE ),  
  64.         0xEEEE00,    //new Color( 0xEEEE00 ),  
  65.         0x00EEEE     //new Color( 0x00EEEE )  
  66.     };  
  67.     private static final short box_sum[][] = new short[][]    //所有方块图形  
  68.     ...{  
  69.         ...{ 0x06600x06600x06600x0660 },  
  70.         ...{ 0x22220x00F00x22220x00F0 },  
  71.         ...{ 0x02640x06300x02640x0630 },  
  72.         ...{ 0x04620x03600x04620x0360 },  
  73.         ...{ 0x02E00x44600x07400x0622 },  
  74.         ...{ 0x0E200x22600x04700x0644 },  
  75.         ...{ 0x04640x00E40x04C40x04E0 }  
  76.     };  
  77.  
  78.     private static short next_box[] = new short[]...{ 0x06600x06600x06600x0660 };   
  79.     private static short box[]          = new short[]...{ 0x06600x06600x06600x0660 };  
  80.     private static short map[][];        //地图  
  81.     private static short box_state  = 0;//当前BOX的状态//旋转方向  
  82.     private static short matrix[][] =    //定义矩阵用来计算出box_sum的方块  
  83.     ...{  
  84.         ...{ 0x10000x01000x00100x0001 },  
  85.         ...{ 0x20000x02000x00200x0002 },  
  86.         ...{ 0x40000x04000x00400x0004 },  
  87.         ...{ (short)0x80000x08000x00800x0008 }  
  88.     };  
  89.  
  90.     public cGame176x220()  
  91.     ...{  
  92.         setFullScreenMode(true);        //设置游戏为全屏幕模式,该函数只能在支持midp2.0的手机上使用  
  93. //        s_width = getWidth();            //得到屏幕尺寸     宽  
  94. //        s_height= getHeight();            //得到屏幕尺寸     高  
  95.         rand = new Random( System.currentTimeMillis() );  
  96.         try 
  97.         ...{  
  98.             //gameOverImg = Toolkit.getDefaultToolkit().getImage("src/pics/laser.png");  
  99.             gameOverImg = Image.createImage("/pics/laser.png");  
  100.         }catch(Exception e)...{}  
  101.         //setSize( s_width, s_height );    //设置画布  
  102.         initGame();                        //游戏初始化  
  103.         thread  = new Thread(this);  
  104.         thread.start();  
  105.     }  
  106.       
  107.     private void initGame()  
  108.     ...{  
  109.         level        = 1;                //等级  
  110.         success        = 0;                //得分  
  111.         map     = new short[s_box_h_sum][s_box_w_sum];  
  112.         setNextBox();                    //设置下一个BOX  
  113.         setBox();                        //将下一个BOX设置成当前BOX  
  114.         setGameOver( false );            //恢复游戏  
  115.     }  
  116.       
  117.     private void setBox()                //将next_box设置成当前可控制box  
  118.     ...{  
  119.         box_state         = 0;                                        //box 状态  
  120.         s_box_x            = init_x;                                    //当前方块坐标X  
  121.         s_box_y            = init_y;                                    //当前方块坐标Y  
  122.         boxColor        = s_next_box;                                //设置当前BOX颜色  
  123.         System.arraycopy( next_box, 0, box, 0, next_box.length );    //box = next_box  
  124.         goDownPreTime     = System.currentTimeMillis();                //设置好当前BOX后 计时  
  125.         setNextBox();                                                //设置下一个BOX  
  126.         if( !isCanMove() )  
  127.         ...{  
  128.             setGameOver( true );  
  129.         }  
  130.     }  
  131.  
  132.     public static boolean isGameOver = false;  
  133.     public static long updatas     = 0;  
  134.     public static long fps         = 0;  
  135.     private long     startTime, beginTime, endTime;  
  136.     private long     delay         = 25;  
  137.     private long     upTime         = 25;  
  138.     public void run()   
  139.     ...{  
  140.         while ( true )   
  141.         ...{  
  142.             try 
  143.             ...{  
  144.                 beginTime = System.currentTimeMillis();  
  145.                 updatas++;  
  146.                 updata( updatas );  
  147.                 repaint();  
  148.                 endTime = System.currentTimeMillis();  
  149.                 upTime  = endTime-beginTime;  
  150.                 if( upTime<delay )  
  151.                 ...{  
  152.                     fps = 1000/delay;  
  153.                     thread.sleep(delay-upTime);  
  154.                 }  
  155.                 else 
  156.                     fps = 1000/upTime;  
  157.             }catch(Exception e)...{ }  
  158.         }  
  159.     }  
  160.     void setGameOver( boolean _isGameOver )  
  161.     ...{  
  162.         isGameOver = _isGameOver;  
  163.         if( isGameOver )  
  164.         ...{  
  165.             setRecord( successSort() );  
  166.         }  
  167.     }  
  168.     public void updata( long updatas )  
  169.     ...{  
  170.  
  171.     }  
  172.     public void update(Graphics g)   
  173.     ...{  
  174.         paint(g);  
  175.     }  
  176.     public void paint(Graphics g)  
  177.     ...{  
  178.         try 
  179.         ...{  
  180.             if( buffer == null )  
  181.             ...{  
  182.                 buffer = Image.createImage( s_width, s_height );    //设置画布缓冲区  
  183.                 gb = buffer.getGraphics();                    //得到绘图设备  
  184.             }  
  185. //            gb.translate( offx, offy );  
  186. //            gb.setColor( new Color( 0x0 ) );                //初始化 画布颜色  
  187.             gb.setColor( 0x0 );                                //初始化 画布颜色  
  188.             gb.setClip ( 00, s_width, s_height);            //初始化 画布区域  
  189.             gb.fillRect( 00, s_width, s_height);            //初始化 画布填充  
  190.             paintReseau( gb );                                //绘制网格  
  191.             paintNextBox( gb );                                //绘制下一BOX  
  192.             paintMap( gb );                                    //绘制地图上不可以动BOX  
  193.             paintBox( gb, s_box_x, s_box_y );                //绘制当前可控制BOX  
  194. //            gb.setColor( new Color( 0xFF3333 ) );            //分割线颜色  
  195.             gb.setColor( 0xFF3333 );                        //分割线颜色  
  196.             gb.drawLine( s_line_between_x, 0, s_line_between_x, s_height );    //分割线  
  197. //            gb.drawString( "FPS:"+fps,             s_line_between_x+10,10 );    //祯数  
  198. //            gb.drawString( "等级:"+level,         s_line_between_x+10,30 );    //等级  
  199. //            gb.drawString( "得分:"+success,         s_line_between_x+10,50 );    //分数  
  200.             gb.drawString( "FPS:"+fps,             s_line_between_x+1010, g.TOP|g.LEFT );//祯数  
  201.             gb.drawString( "级:"+level,         s_line_between_x+1030, g.TOP|g.LEFT );//等级  
  202.             gb.drawString( "分:"+success,         s_line_between_x+1050, g.TOP|g.LEFT );//分数  
  203.             if( isGameOver )  
  204.             ...{  
  205. //                gb.drawImage( gameOverImg, (getWidth()-offx-gameOverImg.getWidth(null))/2, (getHeight()-gameOverImg.getHeight(null))/2 , null );  
  206. //                gb.drawImage( gameOverImg,    s_width>>1, s_height>>1, g.HCENTER|g.VCENTER );  
  207.                 paintRecord( gb );  
  208.             }  
  209. //            gb.translate( -offx, -offy );  
  210.         }  
  211.         catch(Exception e)  
  212.         ...{   
  213.             System.out.println("err at paint.e====="+e);  
  214.         }  
  215. //        g.drawImage( buffer, offx, offy, null);                //将画布缓冲区绘制到屏幕//偏移 (2,2)  
  216.         g.drawImage( buffer, offx, offy, 0);                //将画布缓冲区绘制到屏幕//偏移 (2,2)  
  217.     }  
  218.       
  219.     private void paintReseau( Graphics g )                    //绘制网格  
  220.     ...{  
  221.         g.setColor( gameBG );  
  222.         g.fillRect( 00, s_line_between_x, s_height );  
  223.         if( isShowReseau )  
  224.         ...{  
  225.             g.setColor( gameColor[0] );  
  226.             forint i=0; i<s_line_between_x/s_box_w; i++ )    // |  
  227.             ...{  
  228.                 g.drawLine( i*s_box_h, 0, i*s_box_h, s_height );  
  229.             }  
  230.             forint j=0; j<s_height/s_box_h; j++ )            // -  
  231.             ...{  
  232.                 g.drawLine( 0, j*s_box_w, s_line_between_x, j*s_box_w );  
  233.             }  
  234.         }  
  235.     }  
  236.     private void paintBox( Graphics g, int off_x, int off_y )  
  237.     ...{  
  238.         forint i=0; i<4; i++ )        //行  
  239.         ...{  
  240.             forint j=0; j<4; j++ )    //列  
  241.             ...{  
  242.                 if( (box[box_state] & matrix[i][j]) == matrix[i][j] )  
  243.                 ...{  
  244.                     g.setColor( gameColor[ boxColor ] );  
  245.                     g.fillRect( (off_x+j)*s_box_w, (off_y+i)*s_box_h, s_box_w, s_box_h );  
  246.  
  247.                     g.setColor( gameBG );  
  248.                     g.drawRect( (off_x+j)*s_box_w+1, (off_y+i)*s_box_h+1, s_box_w-2, s_box_h-2 );  
  249.                 }  
  250.             }  
  251.         }  
  252.         goDown();                        //BOX是否下降  
  253.     }  
  254.     private void paintNextBox( Graphics g )  
  255.     ...{  
  256.         int off_x = s_line_between_x+( s_width - s_line_between_x - 4*s_box_w )/2;  
  257.         int off_y = s_height/2;  
  258.           
  259.         g.translate( off_x, off_y );  
  260.         g.setColor( gameBG );  
  261.         g.fillRect( 004*s_box_w, 4*s_box_h );  
  262.           
  263.         if( isShowReseau )                //显示格式  
  264.         ...{  
  265.             g.setColor( gameColor[0] );  
  266.             forint i=0; i<5; i++ )    // |  
  267.             ...{  
  268.                 g.drawLine( i*s_box_h, 0, i*s_box_h, 4*s_box_h );  
  269.             }  
  270.             forint j=0; j<5; j++ )    // -  
  271.             ...{  
  272.                 g.drawLine( 0, j*s_box_w, 4*s_box_w, j*s_box_w );  
  273.             }  
  274.         }  
  275.         forint i=0; i<4; i++ )        //行  
  276.         ...{  
  277.             forint j=0; j<4; j++ )    //列  
  278.             ...{  
  279.                 if( (next_box[0] & matrix[i][j]) == matrix[i][j] )  
  280.                 ...{  
  281.                     g.setColor( gameColor[ s_next_box ] );  
  282.                     g.fillRect( j*s_box_w, i*s_box_h, s_box_w, s_box_h );  
  283.  
  284.                     g.setColor( gameBG );  
  285.                     g.drawRect( j*s_box_w+1, i*s_box_h+1, s_box_w-2, s_box_h-2 );  
  286.                 }  
  287.             }  
  288.         }  
  289.         g.translate( -off_x, -off_y );  
  290.     }  
  291.  
  292.     private long goDownPreTime     = 0;    //上次下降时间  
  293.     private long currTime         = 0;    //当前时间  
  294.     private void goDown()                //当前BOX下降  
  295.     ...{  
  296.         if( isGameOver )    //游戏结束  
  297.             return;  
  298.         //isKeyDown按了向下移动就需要检查 不需要时间  
  299.         if( isKeyDown==1 || System.currentTimeMillis() - goDownPreTime >= goDownDelayTime[level] )  
  300.         ...{  
  301.             s_box_y++;  
  302.             goDownPreTime = System.currentTimeMillis();  
  303.             if( !isCanMove() )  
  304.             ...{  
  305.                 isKeyDown = 0;    //没有按下  
  306.                 s_box_y--;  
  307.                 setMap();        //将BOX放进map   
  308.                 setBox();        //新的BOX  
  309.             }  
  310.         }  
  311.     }  
  312.       
  313.     private void setMap()  
  314.     ...{  
  315.         forint i=0; i<4; i++ )        //行  
  316.         ...{  
  317.             forint j=0; j<4; j++ )    //列  
  318.             ...{  
  319.                 if( ( box[box_state] & matrix[i][j] ) == matrix[i][j] )    //是格子  
  320.                 ...{  
  321.                     map[s_box_y+i][s_box_x+j] = boxColor;  
  322.                 }  
  323.             }  
  324.         }  
  325.         //检测是否可以消去一行  
  326.         int line_success = 0;  
  327.         forint i=0; i<s_box_h_sum; i++ )        //行  
  328.         ...{  
  329.             if( isFullLine( i ) )                //这行可以消去  
  330.             ...{  
  331.                 setNullLine( i );                //设置第i行为空  
  332.                 setGoDownMap( i );                //地图第i行以上的向下移动一行  
  333.                 line_success++;  
  334.             }  
  335.         }  
  336.         success += line_success*line_success;    //设置得分  
  337.         level_up = (int)(goDownDelayTime[0]-goDownDelayTime[level]);  
  338.         if( success >= level_up )                //设置升级  
  339.         ...{  
  340.             level %= goDownDelayTime.length;  
  341.             level ++;  
  342.         }  
  343.     }  
  344.  
  345.     private void paintMap( Graphics g )  
  346.     ...{  
  347.         forint i=0; i<s_box_h_sum; i++ )        //行  
  348.         ...{  
  349.             forint j=0; j<s_box_w_sum; j++ )    //列  
  350.             ...{  
  351.                 if( map[i][j] > 0 )                //是格子//绘制格子  
  352.                 ...{  
  353.                     g.setColor( gameColor[ map[i][j] ] );  
  354.                     g.fillRect( j*s_box_w, i*s_box_h, s_box_w, s_box_h );      
  355.                       
  356.                     g.setColor( gameBG );  
  357.                     g.drawRect( j*s_box_w+1, i*s_box_h+1, s_box_w-2, s_box_h-2 );  
  358.                 }  
  359.             }  
  360.         }  
  361.     }  
  362.  
  363.     private int successSort()    //成绩排序  
  364.     ...{  
  365.         forint i=0; i<Tetris.recoreMax; i++ )  
  366.         ...{  
  367.             if( success >= Tetris.success[i] )  
  368.                 return i;  
  369.         }  
  370.         return Tetris.recoreMax;  
  371.     }  
  372.     private static int successPlace = 0;    //名次   
  373.     private void setRecord(int num)    //设置记录  
  374.     ...{  
  375.         successPlace = num;  
  376.         System.out.println("successPlace="+successPlace);  
  377.         forint i=Tetris.recoreMax-1; i>=0; i-- )  
  378.         ...{  
  379.             if( i==num )  
  380.             ...{  
  381.                 Tetris.success [i] = success;  
  382.                 Tetris.dateTime[i] = Tetris.getDate();  
  383.             }else 
  384.             ...{  
  385.                 Tetris.success [i] = Tetris.success [i-1];  
  386.                 Tetris.dateTime[i] = Tetris.dateTime[i-1];  
  387.             }  
  388.         }  
  389.      }  
  390.     /////////绘制成绩列表////////////  
  391.     private static final int w1     = 45;    //名次 后分隔线  
  392.     private static final int w2     = 85;    //成绩 后分隔线  
  393.     private static final int font_h = 16;    //字体高度  
  394.     private void paintRecord( Graphics g )        //绘制记录  
  395.     ...{  
  396.         g.setColor( gameBG );  
  397.         g.fillRect( 00, s_width, s_height );  
  398.         g.setColor( gameColor[1] );                //白×××  
  399.         g.drawString("名次",5,2,g.TOP|g.LEFT);  
  400.         g.drawString("成绩",w1,2,g.TOP|g.LEFT);  
  401.         g.drawString("日期",w2,2,g.TOP|g.LEFT);  
  402.         g.setColor( gameColor[0] );                //网格色  
  403.         g.drawLine(w1,0,w1,s_height);  
  404.         g.drawLine(w2,0,w2,s_height);  
  405.           
  406.         for(int i=1; i<=Tetris.recoreMax; i++ )  
  407.         ...{  
  408.             if( i == successPlace+1 )  
  409.                 g.setColor( gameColor[2] );        //红色  
  410.             else 
  411.                 g.setColor( gameColor[1] );        //白色  
  412.             g.drawString(""+i,5,font_h*i,g.TOP|g.LEFT);  
  413.             g.drawString(""+Tetris.success [i-1],w1, font_h*i, g.TOP|g.LEFT);  
  414.             g.drawString(""+Tetris.dateTime[i-1],w2, font_h*i, g.TOP|g.LEFT);  
  415.             g.setColor( gameColor[0] );            //网格色  
  416.             g.drawLine(0,font_h*i,s_width,16*i);  
  417.         }  
  418.         g.setColor( gameColor[6] );                //×××  
  419.         g.drawString("5:Replay",s_width>>1,s_height-font_h*2, g.TOP|g.HCENTER);  
  420.         g.drawString("*:Exit",    s_width>>1,s_height-font_h*1, g.TOP|g.HCENTER);  
  421.     }  
  422.       
  423.     private boolean isFullLine(int line)    //是否一行已经满了  
  424.     ...{  
  425.         forint j=0; j<s_box_w_sum; j++ )    //列  
  426.         ...{  
  427.             if( map[line][j] <= 0 )  
  428.             ...{  
  429.                 return false;  
  430.             }  
  431.         }  
  432.         return true;  
  433.     }  
  434.       
  435.     private void  setNullLine( int line )    //设置地图上的这一行 空  
  436.     ...{  
  437.         forint j=0; j<s_box_w_sum; j++ )    //列  
  438.         ...{  
  439.             map[line][j] = 0;  
  440.         }      
  441.     }  
  442.     private void setGoDownMap( int line )    //设置地图line以上的每行都向下移动一行  
  443.     ...{  
  444.         forint i=line; i>0; i-- )            //行  
  445.         ...{  
  446.             forint j=0; j<s_box_w_sum; j++ )    //列  
  447.             ...{  
  448.                 map[i][j] = map[i-1][j];     //向下移动一行  
  449.             }  
  450.         }  
  451.     }  
  452.     private static          int act_off_x     = 0;    //方块在左右边界旋转的时候调整方块位置的偏移  
  453.     private static final int act_move     = 0;  
  454.     private static final int act_transfiguration = 1;  
  455.     private boolean isCanMove()  
  456.     ...{  
  457.         return isCanMove( act_move );  
  458.     }  
  459.     private boolean isCanMove( int act )  
  460.     ...{  
  461.         forint i=0; i<4; i++ )        //行  
  462.         ...{  
  463.             forint j=0; j<4; j++ )    //列  
  464.             ...{  
  465.                 if( ( box[box_state] & matrix[i][j] ) == matrix[i][j] )    //是格子  
  466.                 ...{  
  467.                     if( s_box_x+j < 0 )                    //左边界检测  
  468.                     ...{  
  469.                         if( act == act_transfiguration )//左边界检测失败 调整 BOX 位置右移动 最多2格  
  470.                         ...{  
  471.                             act_off_x=1;  
  472.                             s_box_x ++;  
  473.                             if( isCanMove() )  
  474.                             ...{  
  475.                                 return true;  
  476.                             }  
  477.                             else 
  478.                             ...{  
  479.                                 act_off_x=2;  
  480.                                 s_box_x ++;  
  481.                                 if( isCanMove() )  
  482.                                 ...{  
  483.                                     return true;  
  484.                                 }  
  485.                                 else 
  486.                                 ...{  
  487.                                     act_off_x = 0;  
  488.                                 }  
  489.                             }  
  490.                         }  
  491.                         System.out.println( "left s_box_x="+s_box_x+" matrix["+i+"]["+j+"]="+matrix[i][j]);  
  492.                         return false;  
  493.                     }  
  494.                     if( s_box_x+j > s_box_w_sum-1 )    //右边界检测  
  495.                     ...{  
  496.                         if( act == act_transfiguration )//右边界检测失败 调整 BOX 位置左移动 最多1格  
  497.                         ...{  
  498.                             act_off_x = -1;  
  499.                             s_box_x --;  
  500.                             if( isCanMove() )  
  501.                             ...{  
  502.                                 return true;  
  503.                             }  
  504.                             else 
  505.                             ...{  
  506.                                 act_off_x = 0;  
  507.                             }  
  508.                         }  
  509.                         System.out.println( "right s_box_x="+s_box_x+" matrix["+i+"]["+j+"]="+matrix[i][j]);  
  510.                         return false;  
  511.                     }  
  512.                     if( s_box_y+i > s_box_h_sum-1 )    //下边界检测  
  513.                     ...{  
  514.                         System.out.println( "down s_box_y="+s_box_y+" matrix["+i+"]["+j+"]="+matrix[i][j]);  
  515.                         return false;  
  516.                     }  
  517.                     if( map[s_box_y+i][s_box_x+j] > 0 )    //地图格子检测  
  518.                     ...{  
  519.                         System.out.println( "map s_box_y="+s_box_y+" matrix["+i+"]["+j+"]="+matrix[i][j]);  
  520.                         return false;  
  521.                     }  
  522.                 }  
  523.             }  
  524.         }  
  525.         return true;  
  526.     }  
  527.     private short isKeyDown = 0;    //0没有按下,1按下,2抬起  
  528. //    public boolean keyDown(Event evt, int key)  
  529.     public void keyPressed( int key )  
  530.     ...{  
  531.         key = getKeyCode( key );  
  532.         switch( key )  
  533.         ...{  
  534.             case UP:                //顺时针旋转  
  535.                 isKeyDown = 0;        //0没有按下  
  536.                 box_state ++;  
  537.                 box_state %= 4;  
  538. //                s_box_x -= act_off_x;    //恢复偏移中心到未偏移前//不恢复的好1  
  539.                 if( !isCanMove( act_transfiguration ) )  
  540.                 ...{  
  541.                     box_state --;  
  542.                     if( box_state<0 )  
  543.                         box_state = 3;  
  544.                 }  
  545.             break;  
  546.             case DOWN:                //向下移动  
  547.                 act_off_x = 0;        //恢复BOX旋转位置偏移为0  
  548.                 if( isKeyDown == 2 )  
  549.                     isKeyDown = 1;  
  550.                 if( isKeyDown == 1 )  
  551.                 ...{  
  552.                     s_box_y ++;   
  553.                     if( !isCanMove() )  
  554.                         s_box_y --;  
  555.                 }  
  556.             break;  
  557.             case LEFT:                //向左移动BOX  
  558.                 act_off_x = 0;        //恢复BOX旋转位置偏移为0  
  559.                 isKeyDown = 0;        //0没有按下  
  560.                 s_box_x --;  
  561.                 if( !isCanMove() )  
  562.                     s_box_x ++;      
  563.             break;  
  564.             case RIGHT:                //向右移动BOX  
  565.                 act_off_x = 0;        //恢复BOX旋转位置偏移为0  
  566.                 isKeyDown = 0;        //0没有按下  
  567.                 s_box_x ++;  
  568.                 if( !isCanMove() )  
  569.                     s_box_x --;  
  570.             break;  
  571.             case 53:                //数字5键  
  572.                 if( isGameOver )    //游戏结束  
  573.                     initGame();        //重新游戏  
  574.             break;  
  575.             case 42:  
  576.                 if( isGameOver )    //游戏结束  
  577. //                    System.exit(0);    //退出游戏  
  578.                     Tetris.s_midlet.destroyApp(true);  
  579.             break;  
  580.             case 48:  
  581.                 setBox();            //新的BOX  
  582.             break;  
  583.             case 49:                //是否显示网格  
  584.                 isShowReseau = !isShowReseau;  
  585.             break;  
  586.         }  
  587.         repaint();                    //重新绘制屏幕  
  588. //        return true;  
  589.     }  
  590.     public void keyRepeated( int key )  
  591.     ...{  
  592.         keyPressed( key );  
  593.     }  
  594.     public void setNextBox()  
  595.     ...{  
  596.         s_next_box = (short)rand.nextInt( box_sum.length );  
  597.         System.arraycopy( box_sum[s_next_box], 0, next_box, 0, next_box.length );  
  598.         s_next_box++;  
  599.     }  
  600.  
  601.     public int getKeyCode( int key )  
  602.     ...{  
  603.         System.out.println( "key="+key );  
  604.         switch( key )  
  605.         ...{  
  606.             case 1004:     // up  
  607.             case 119:     // w  
  608.             case 87:     // W  
  609.             case 50:     // 2  
  610.             return UP;  
  611.  
  612.             case 1005:     // down  
  613.             case 115:     // s  
  614.             case 83:     // S  
  615.             case 56:     // 8  
  616.             return DOWN;  
  617.  
  618.             case 1006:     // left  
  619.             case 97:     // a  
  620.             case 65:     // A  
  621.             case 52:     // 4  
  622.             return LEFT;  
  623.  
  624.             case 1007:     // right  
  625.             case 100:     // d  
  626.             case 68:     // D  
  627.             case 54:     // 6  
  628.             return RIGHT;  
  629.             default:  
  630.             return key;  
  631.         }  
  632.     }  
  633. //    public boolean keyUp(Event evt, int key)   
  634.     public void keyReleased( int key )   
  635.     ...{  
  636.         isKeyDown = 2;    //释放按键  
  637. //        return true;  
  638.     }  
  639. //    public boolean mouseDown(Event evt, int x, int y)  
  640. //    {  
  641. //        try  
  642. //        {  
  643. ////            System.out.println( "x="+x+" y="+y );  
  644. //        }catch( Exception e){e.printStackTrace();}  
  645. ////        this.repaint();  
  646. //        return true;  
  647. //    }  
  648. //    public boolean mouseMove(Event evt, int x, int y)  
  649. //    {  
  650. //        try  
  651. //        {  
  652. //            //System.out.println( "x="+x+" y="+y );  
  653. //        }catch( Exception e){e.printStackTrace();}  
  654. //        return true;  
  655. //    }  
  656. //    public static void main(String[] args)   
  657. //    {  
  658. //        JFrame frame = new JFrame("俄罗斯方块 北京|雷神 QQ:38929568");  
  659. //        final cGame dc = new cGame();  
  660. //        frame.getContentPane().add(dc, BorderLayout.CENTER);  
  661. //  
  662. ////        JButton button = new JButton("刷新");  
  663. ////        button.addActionListener(new ActionListener()   
  664. ////        {  
  665. ////            public void actionPerformed(ActionEvent e)   
  666. ////            {  
  667. ////                dc.repaint();  
  668. ////            }  
  669. ////        });  
  670. ////        frame.getContentPane().add(button, BorderLayout.SOUTH);  
  671. //        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
  672. //        frame.setSize(dc.s_width+10, dc.s_height+30);  
  673. //        frame.setVisible(true);  
  674. //    }  

Tetris.java 主MIDlet 类

  1. package code;  
  2. ///////////////////////////////////////////////////////////////////////////////////////////////////  
  3. /** *//**  
  4.  * 俄罗斯方块  
  5.  * 高雷  
  6.  * 2007年11月30日  
  7.  */ 
  8. ///////////////////////////////////////////////////////////////////////////////////////////////////  
  9. import javax.microedition.midlet.*;    //j2me MIDlet程序必须继承MIDlet类,所以要引入此包  
  10. import javax.microedition.lcdui.*;    //Display这个类所在包  
  11.  
  12. import javax.microedition.rms.*;  
  13. import java.io.*;  
  14. import java.util.*;  
  15. import java.util.Calendar;  
  16. import java.util.Date;  
  17. ///////////////////////////////////////////////////////////////////////////////////////////////////  
  18.  
  19. public class Tetris extends MIDlet   
  20. ...{  
  21.     static Tetris s_midlet;    //MIDlet类的静态对象,方便实用 MIDlet类方法  
  22.     static Display s_display = null;//用来显示 Canvas  
  23.     static cGame176x220 s_game = null;        //Canvas类对象,主要实现游戏的类  
  24.       
  25.     public Tetris()  
  26.     ...{  
  27.         s_midlet = this;  
  28.     }  
  29.       
  30.     /** *//**  
  31.      * 程序开始 系统会调用这个函数  
  32.      * 也有些手机 可以把程序初始化部分放到构造函数里,这连个地方应视手机的不同而定!  
  33.      */ 
  34.     public void startApp()               
  35.     ...{  
  36.         ReadData();  
  37.         if (s_display == null)   
  38.         ...{  
  39.             s_display = Display.getDisplay(this);//创建Display对象,参数是MIDlet类对象,也就是我们当前写的这个Minesweeper类  
  40.         }  
  41.  
  42.         if (s_game == null)   
  43.         ...{  
  44.             s_game = new cGame176x220();                //创建 Canvas对象  
  45.             s_display.setCurrent(s_game);        //把Canvas对象设置成当前显示  
  46.         }   
  47.         else   
  48.         ...{  
  49.             s_display.setCurrent(s_game);  
  50.         }  
  51.     }  
  52.  
  53.     /** *//**  
  54.      * 程序暂停 系统会自动调用这个函数,不是所有手机都支持,  
  55.      * 手机在接到中断,如 来电,来短信时候会调用这个函数,这个函数 通常是空的!  
  56.      */ 
  57.     public void pauseApp()           
  58.     ...{  
  59.           
  60.     }  
  61.  
  62.     /** *//**  
  63.      * 程序关闭 系统会调用这个函数,如果希望关闭程序的时候保存数据,可在这个函数里添加保存数据的方法  
  64.      * 比如游戏进行中,按了关机键,程序就会调用这个函数,也可以在程序中调用这个函数来结束游戏!  
  65.      */ 
  66.     public void destroyApp(boolean unconditional)   
  67.     ...{  
  68.         WriteData();  
  69.         notifyDestroyed();  
  70.     }  
  71.       
  72.  
  73.     static Calendar    cal        = Calendar.getInstance();  
  74.     static Date        date    = null;  
  75.     public static String getDate()  
  76.     ...{  
  77.         date = new Date( System.currentTimeMillis() );  
  78.         cal.setTime( date );  
  79.         return "" +( cal.get( Calendar.MONTH ) + 1 )+"月"+cal.get( Calendar.DAY_OF_MONTH )+"日"+cal.get( Calendar.YEAR );  
  80.     }  
  81.     public static String getTime()  
  82.     ...{  
  83.         date = new Date( System.currentTimeMillis() );  
  84.         cal.setTime( date );  
  85.         return "_" + cal.get( Calendar.HOUR_OF_DAY ) + "_" + cal.get( Calendar.MINUTE ) + "_" 
  86.                 + cal.get( Calendar.SECOND );  
  87.     }  
  88.       
  89.     public static final String         gameName     = "Tetris";  
  90.     public static final int            recoreMax     = 8;  
  91.     public static         int[]        success     = new int[recoreMax];  
  92.     public static         String[]    dateTime    = new String[recoreMax];  
  93.     /** *//**  
  94.     * 读取存档记录  
  95.     */ 
  96.     public void ReadData()  
  97.     ...{  
  98.         String rmsName = gameName;  
  99.         try 
  100.         ...{  
  101.             RecordStore rs = RecordStore.openRecordStore(rmsName, false);    //人物数据  
  102.             //<读取人物数据>  
  103.             byte[] data = rs.getRecord(1);  
  104.             ByteArrayInputStream bais = new ByteArrayInputStream(data);  
  105.             DataInputStream in = new DataInputStream(bais);  
  106.             for(int i=0; i<success.length; i++ )  
  107.             ...{  
  108.                 success    [i] = in.readInt();                    //分数  
  109.                 dateTime[i] = in.readUTF();                    //日期  
  110.             }  
  111. //----------------2.0--------------              
  112.             int k;  
  113.             k = in.readInt(); // 11备用  
  114.             k = in.readInt(); // 12备用  
  115.             //</读取人物数据>  
  116.         }  
  117.         catch (Exception e)    ...{  }//新建档案  
  118.     }  
  119.     /** *//**  
  120.     * 写记录  
  121.     */ 
  122.     public void WriteData()  
  123.     ...{  
  124.         String rmsName = gameName;  
  125.         try 
  126.         ...{  
  127.             RecordStore rs = RecordStore.openRecordStore(rmsName, true); //如不存在数据库,则创建  
  128.             //<写人物数据>  
  129.             ByteArrayOutputStream baos = new ByteArrayOutputStream();  
  130.             DataOutputStream out = new DataOutputStream(baos);  
  131.             for(int i=0; i<success.length; i++ )  
  132.             ...{  
  133.                 out.writeInt( success    [i] );             // 分数  
  134.                 out.writeUTF( dateTime    [i] );             // 日期  
  135.             }  
  136. //            ----------------2.0--------------              
  137.             out.writeInt(0); //11 预留  
  138.             out.writeInt(0); //12 预留  
  139.               
  140.             byte[] data = baos.toByteArray(); //转换成byte数组  
  141.             if (rs.getNumRecords() != 0)//已经有记录存在  
  142.                 rs.setRecord(1, data, 0, data.length);  
  143.             else 
  144.                 rs.addRecord(data, 0, data.length);  
  145.  
  146.             out.close();  
  147.             baos.close();  
  148.             rs.closeRecordStore();  
  149.             //</写人物数据>  
  150.         }  
  151.         catch (Exception e2)...{}  
  152.     }