之前的游戏代码中都未加声音,不少网友在做别业设计时要求增加声音,其实声音还是比较好做的!但手机真机上可能会有不同的问题,但在模拟器上一般都没什么问题,所以真机上的问题就具体问题具体分析吧!这里给出一个很简单的声音应用。

在原 俄罗斯方块_3的代码基础上增加一个声音类!

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

示例代码如下

 
  
  1. view plaincopy to clipboardprint?  
  2. package code;     
  3.     
  4. import java.io.*;     
  5. import javax.microedition.media.Manager;     
  6. import javax.microedition.media.MediaException;     
  7. import javax.microedition.media.Player;     
  8.     
  9. public class Sound     
  10. {     
  11.     public static Player            m_sounds;     
  12.     public static int               m_currentSoundID        = -1;     
  13.     public static boolean           s_sound_bg_On           = false;     
  14.     
  15.     private static final String SOUND_FILENAME  ="/pics/newmsg.wav";        //0.背景声音     
  16.     
  17.          
  18.     public static final void initSound()     
  19.     {     
  20.         if( m_sounds != null )     
  21.             return;     
  22.         try    
  23.         {     
  24.             DataInputStream dis= new DataInputStream("".getClass().getResourceAsStream(SOUND_FILENAME));     
  25.             byte[] soundBuffer = new byte[dis.available()];     
  26.             dis.read( soundBuffer );     
  27.             InputStream is = new ByteArrayInputStream(soundBuffer);     
  28.             m_sounds = Manager.createPlayer(is, "audio/x-wav" );     
  29.             m_sounds.realize();     
  30.             m_sounds.prefetch();     
  31.         }catch( Exception e )     
  32.         {     
  33.             e.printStackTrace();     
  34.         }     
  35.     }     
  36.     public static void playSound( int soundID )     
  37.     {     
  38.         playSound( soundID, 1 );     
  39.     }     
  40.     public static void playSound( int soundID, int loopCount )     
  41.     {     
  42.         try    
  43.         {     
  44.             if( m_sounds == null )     
  45.                 return;     
  46.             if( m_sounds.getState() == javax.microedition.media.Player.STARTED )     
  47.                 return;     
  48.             m_currentSoundID = soundID;     
  49.             m_sounds.setMediaTime( 0 );     
  50.             m_sounds.setLoopCount( loopCount );     
  51.             m_sounds.start();     
  52.             Thread.sleep( 50 ); // maybe this can help for sound problems     
  53.         }catch( Exception e )     
  54.         {     
  55.             e.printStackTrace();     
  56.         }     
  57.     }     
  58.     
  59.     private static void stopSound() throws Exception     
  60.     {     
  61.         try    
  62.         {     
  63.             if( m_sounds == null )     
  64.                 return;     
  65.             if( m_sounds.getState() == javax.microedition.media.Player.STARTED )     
  66.                 m_sounds.stop();     
  67.             if( m_sounds.getState() == javax.microedition.media.Player.PREFETCHED )     
  68.                 m_sounds.deallocate();     
  69.             m_currentSoundID = -1;     
  70.         }catch( Exception e )     
  71.         {     
  72.             e.printStackTrace();     
  73.         }     
  74.     }     
  75.     
  76.     public static int readFileToMemory( String fileName, byte[] buffer )     
  77.     {     
  78.         java.io.InputStream file = null;     
  79.         int size;     
  80.         try    
  81.         {     
  82.             file = fileName.getClass().getResourceAsStream( fileName );     
  83.             size = file.read( buffer );     
  84.             file.close();     
  85.             file = null;     
  86.         }catch( Exception e )     
  87.         {     
  88.             return -1;     
  89.         }     
  90.         return size;     
  91.     }     
  92. }   

使用方法 是在主Canvas类的初始化或者游戏初始化的地方调用 Sound类的initSound()方法,来初始化声音文件,

然后在想要播放的地方调用Sound类的playSound()方法,目前这个简单的例子里只有一个声音,所以参数给啥都一样,如果以后声音多了!就可以用这个参数来区分用户要调用的是那个声音了!这里的用户是相对这个Sound类的使用者,就是程序员,Sound类都是静态方法,这里相对于一个公共的工具类!

如果上述使用方法您没看明白,那就看一下代码

主Canvas类代码如下

 
  
  1. view plaincopy to clipboardprint?  
  2. package code;     
  3.     
  4. //import java.awt.*;     
  5. //import java.awt.Canvas;     
  6. //import java.awt.event.*;     
  7. //import javax.swing.*;     
  8. import java.util.Random;     
  9. import javax.microedition.lcdui.*;          //写界面所需要的包     
  10. /**    
  11.  * 俄罗斯方块    
  12.  * 高雷    
  13.  * 2007年11月30日    
  14.  */    
  15. public class cGame240x320 extends Canvas implements Runnable      
  16. {     
  17.          
  18.     private Random rand;     
  19.     private Thread thread;     
  20.     private Graphics    gb;     
  21.     private Image       buffer;     
  22.     private Image       gameOverImg;                    //游戏结束     
  23.     private static final int s_width    = 240;     
  24.     private static final int s_height   = 320;     
  25.     private static final int s_box_w    = 16;     
  26.     private static final int s_box_h    = 16;     
  27.     private static final int s_box_w_sum    = 10;       //操作区域宽 格子数     
  28.     private static final int s_box_h_sum    = 20;       //操作区域高 格子数     
  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 cGame240x320()     
  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.         Sound.initSound();              //初始化声音资源     
  103.         initGame();                     //游戏初始化     
  104.         thread  = new Thread(this);     
  105.         thread.start();     
  106.     }     
  107.          
  108.     private void initGame()     
  109.     {     
  110.         level       = 1;                //等级     
  111.         success     = 0;                //得分     
  112.         map  = new short[s_box_h_sum][s_box_w_sum];     
  113.         setNextBox();                   //设置下一个BOX     
  114.         setBox();                       //将下一个BOX设置成当前BOX     
  115.         setGameOver( false );           //恢复游戏     
  116.     }     
  117.          
  118.     private void setBox()               //将next_box设置成当前可控制box     
  119.     {     
  120.         box_state       = 0;                                        //box 状态     
  121.         s_box_x         = init_x;                                   //当前方块坐标X     
  122.         s_box_y         = init_y;                                   //当前方块坐标Y     
  123.         boxColor        = s_next_box;                               //设置当前BOX颜色     
  124.         System.arraycopy( next_box, 0, box, 0, next_box.length );   //box = next_box     
  125.         goDownPreTime   = System.currentTimeMillis();               //设置好当前BOX后 计时     
  126.         setNextBox();                                               //设置下一个BOX     
  127.         if( !isCanMove() )     
  128.         {     
  129.             setGameOver( true );     
  130.         }     
  131.     }     
  132.     
  133.     public static boolean isGameOver = false;     
  134.     public static long updatas  = 0;     
  135.     public static long fps      = 0;     
  136.     private long    startTime, beginTime, endTime;     
  137.     private long    delay       = 25;     
  138.     private long    upTime      = 25;     
  139.     public void run()      
  140.     {     
  141.         while ( true )      
  142.         {     
  143.             try    
  144.             {     
  145.                 beginTime = System.currentTimeMillis();     
  146.                 updatas++;     
  147.                 updata( updatas );     
  148.                 repaint();     
  149.                 endTime = System.currentTimeMillis();     
  150.                 upTime  = endTime-beginTime;     
  151.                 if( upTime<delay )     
  152.                 {     
  153.                     fps = 1000/delay;     
  154.                     thread.sleep(delay-upTime);     
  155.                 }     
  156.                 else    
  157.                     fps = 1000/upTime;     
  158.             }catch(Exception e){ }     
  159.         }     
  160.     }     
  161.     void setGameOver( boolean _isGameOver )     
  162.     {     
  163.         isGameOver = _isGameOver;     
  164.     }     
  165.     public void updata( long updatas )     
  166.     {     
  167.     
  168.     }     
  169.     public void update(Graphics g)      
  170.     {     
  171.         paint(g);     
  172.     }     
  173.     public static int   offx    = 0;     
  174.     public static int   offy    = 0;     
  175.     public void paint(Graphics g)     
  176.     {     
  177.         try    
  178.         {     
  179.             if( buffer == null )     
  180.             {     
  181.                 buffer = Image.createImage( s_width, s_height );    //设置画布缓冲区     
  182.                 gb = buffer.getGraphics();                  //得到绘图设备     
  183.             }     
  184. //          gb.translate( offx, offy );     
  185. //          gb.setColor( new Color( 0x0 ) );                //初始化 画布颜色     
  186.             gb.setColor( 0x0 );                             //初始化 画布颜色     
  187.             gb.setClip ( 00, s_width, s_height);          //初始化 画布区域     
  188.             gb.fillRect( 00, s_width, s_height);          //初始化 画布填充     
  189.             paintReseau( gb );                              //绘制网格     
  190.             paintNextBox( gb );                             //绘制下一BOX     
  191.             paintMap( gb );                                 //绘制地图上不可以动BOX     
  192.             paintBox( gb, s_box_x, s_box_y );               //绘制当前可控制BOX     
  193. //          gb.setColor( new Color( 0xFF3333 ) );           //分割线颜色     
  194.             gb.setColor( 0xFF3333 );                        //分割线颜色     
  195.             gb.drawLine( s_line_between_x, 0, s_line_between_x, s_height ); //分割线     
  196. //          gb.drawString( "FPS:"+fps,          s_line_between_x+10,10 );   //祯数     
  197. //          gb.drawString( "等级:"+level,         s_line_between_x+10,30 );   //等级     
  198. //          gb.drawString( "得分:"+success,       s_line_between_x+10,50 );   //分数     
  199.             gb.drawString( "FPS:"+fps,          s_line_between_x+1010, g.TOP|g.LEFT );//祯数     
  200.             gb.drawString( "等级:"+level,         s_line_between_x+1030, g.TOP|g.LEFT );//等级     
  201.             gb.drawString( "得分:"+success,       s_line_between_x+1050, g.TOP|g.LEFT );//分数     
  202.             if( isGameOver )     
  203.             {     
  204. //              gb.drawImage( gameOverImg, (getWidth()-offx-gameOverImg.getWidth(null))/2, (getHeight()-gameOverImg.getHeight(null))/2 , null );     
  205.                 gb.drawImage( gameOverImg,  s_width>>1, s_height>>1, g.HCENTER|g.VCENTER );     
  206.             }     
  207. //          gb.translate( -offx, -offy );     
  208.         }     
  209.         catch(Exception e)     
  210.         {      
  211.             System.out.println("err at paint.e====="+e);     
  212.         }     
  213. //      g.drawImage( buffer, offx, offy, null);             //将画布缓冲区绘制到屏幕//偏移 (2,2)     
  214.         g.drawImage( buffer, offx, offy, 0);                //将画布缓冲区绘制到屏幕//偏移 (2,2)     
  215.     }     
  216.          
  217.     private void paintReseau( Graphics g )                  //绘制网格     
  218.     {     
  219.         g.setColor( gameBG );     
  220.         g.fillRect( 00, s_line_between_x, s_height );     
  221.         if( isShowReseau )     
  222.         {     
  223.             g.setColor( gameColor[0] );     
  224.             forint i=0; i<s_line_between_x/s_box_w; i++ )  // |     
  225.             {     
  226.                 g.drawLine( i*s_box_h, 0, i*s_box_h, s_height );     
  227.             }     
  228.             forint j=0; j<s_height/s_box_h; j++ )          // -     
  229.             {     
  230.                 g.drawLine( 0, j*s_box_w, s_line_between_x, j*s_box_w );     
  231.             }     
  232.         }     
  233.     }     
  234.     private void paintBox( Graphics g, int off_x, int off_y )     
  235.     {     
  236.         forint i=0; i<4; i++ )     //行     
  237.         {     
  238.             forint j=0; j<4; j++ ) //列     
  239.             {     
  240.                 if( (box[box_state] & matrix[i][j]) == matrix[i][j] )     
  241.                 {     
  242.                     g.setColor( gameColor[ boxColor ] );     
  243.                     g.fillRect( (off_x+j)*s_box_w, (off_y+i)*s_box_h, s_box_w, s_box_h );     
  244.     
  245.                     g.setColor( gameBG );     
  246.                     g.drawRect( (off_x+j)*s_box_w+1, (off_y+i)*s_box_h+1, s_box_w-2, s_box_h-2 );     
  247.                 }     
  248.             }     
  249.         }     
  250.         goDown();                       //BOX是否下降     
  251.     }     
  252.     private void paintNextBox( Graphics g )     
  253.     {     
  254.         int off_x = s_line_between_x+( s_width - s_line_between_x - 4*s_box_w )/2;     
  255.         int off_y = s_height/2;     
  256.              
  257.         g.translate( off_x, off_y );     
  258.         g.setColor( gameBG );     
  259.         g.fillRect( 004*s_box_w, 4*s_box_h );     
  260.              
  261.         if( isShowReseau )              //显示格式     
  262.         {     
  263.             g.setColor( gameColor[0] );     
  264.             forint i=0; i<5; i++ ) // |     
  265.             {     
  266.                 g.drawLine( i*s_box_h, 0, i*s_box_h, 4*s_box_h );     
  267.             }     
  268.             forint j=0; j<5; j++ ) // -     
  269.             {     
  270.                 g.drawLine( 0, j*s_box_w, 4*s_box_w, j*s_box_w );     
  271.             }     
  272.         }     
  273.         forint i=0; i<4; i++ )     //行     
  274.         {     
  275.             forint j=0; j<4; j++ ) //列     
  276.             {     
  277.                 if( (next_box[0] & matrix[i][j]) == matrix[i][j] )     
  278.                 {     
  279.                     g.setColor( gameColor[ s_next_box ] );     
  280.                     g.fillRect( j*s_box_w, i*s_box_h, s_box_w, s_box_h );     
  281.     
  282.                     g.setColor( gameBG );     
  283.                     g.drawRect( j*s_box_w+1, i*s_box_h+1, s_box_w-2, s_box_h-2 );     
  284.                 }     
  285.             }     
  286.         }     
  287.         g.translate( -off_x, -off_y );     
  288.     }     
  289.     
  290.     private long goDownPreTime  = 0;    //上次下降时间     
  291.     private long currTime       = 0;    //当前时间     
  292.     private void goDown()               //当前BOX下降     
  293.     {     
  294.         if( isGameOver )    //游戏结束     
  295.             return;     
  296.         //isKeyDown按了向下移动就需要检查 不需要时间     
  297.         if( isKeyDown==1 || System.currentTimeMillis() - goDownPreTime >= goDownDelayTime[level] )     
  298.         {     
  299.             s_box_y++;     
  300.             goDownPreTime = System.currentTimeMillis();     
  301.             if( !isCanMove() )     
  302.             {     
  303.                 isKeyDown = 0;  //没有按下     
  304.                 s_box_y--;     
  305.                 setMap();       //将BOX放进map      
  306.                 setBox();       //新的BOX     
  307.             }     
  308.         }     
  309.     }     
  310.          
  311.     private void setMap()     
  312.     {     
  313.         forint i=0; i<4; i++ )     //行     
  314.         {     
  315.             forint j=0; j<4; j++ ) //列     
  316.             {     
  317.                 if( ( box[box_state] & matrix[i][j] ) == matrix[i][j] ) //是格子     
  318.                 {     
  319.                     map[s_box_y+i][s_box_x+j] = boxColor;     
  320.                 }     
  321.             }     
  322.         }     
  323.         //检测是否可以消去一行     
  324.         int line_success = 0;     
  325.         forint i=0; i<s_box_h_sum; i++ )       //行     
  326.         {     
  327.             if( isFullLine( i ) )               //这行可以消去     
  328.             {     
  329.                 setNullLine( i );               //设置第i行为空     
  330.                 setGoDownMap( i );              //地图第i行以上的向下移动一行     
  331.                 line_success++;     
  332.                 Sound.playSound( 0 );     
  333.             }     
  334.         }     
  335.         success += line_success*line_success;   //设置得分     
  336.         level_up = (int)(goDownDelayTime[0]-goDownDelayTime[level]);     
  337.         if( success >= level_up )                //设置升级     
  338.         {     
  339.             level %= goDownDelayTime.length;     
  340.             level ++;     
  341.         }     
  342.     }     
  343.     
  344.     private void paintMap( Graphics g )     
  345.     {     
  346.         forint i=0; i<s_box_h_sum; i++ )       //行     
  347.         {     
  348.             forint j=0; j<s_box_w_sum; j++ )   //列     
  349.             {     
  350.                 if( map[i][j] > 0 )              //是格子//绘制格子     
  351.                 {     
  352.                     g.setColor( gameColor[ map[i][j] ] );     
  353.                     g.fillRect( j*s_box_w, i*s_box_h, s_box_w, s_box_h );        
  354.                          
  355.                     g.setColor( gameBG );     
  356.                     g.drawRect( j*s_box_w+1, i*s_box_h+1, s_box_w-2, s_box_h-2 );     
  357.                 }     
  358.             }     
  359.         }     
  360.     }     
  361.          
  362.     private boolean isFullLine(int line)    //是否一行已经满了     
  363.     {     
  364.         forint j=0; j<s_box_w_sum; j++ )   //列     
  365.         {     
  366.             if( map[line][j] <= 0 )     
  367.             {     
  368.                 return false;     
  369.             }     
  370.         }     
  371.         return true;     
  372.     }     
  373.          
  374.     private void  setNullLine( int line )   //设置地图上的这一行 空     
  375.     {     
  376.         forint j=0; j<s_box_w_sum; j++ )   //列     
  377.         {     
  378.             map[line][j] = 0;     
  379.         }        
  380.     }     
  381.     private void setGoDownMap( int line )   //设置地图line以上的每行都向下移动一行     
  382.     {     
  383.         forint i=line; i>0; i-- )          //行     
  384.         {     
  385.             forint j=0; j<s_box_w_sum; j++ )   //列     
  386.             {     
  387.                 map[i][j] = map[i-1][j];    //向下移动一行     
  388.             }     
  389.         }     
  390.     }     
  391.     private static       int act_off_x  = 0;    //方块在左右边界旋转的时候调整方块位置的偏移     
  392.     private static final int act_move   = 0;     
  393.     private static final int act_transfiguration = 1;     
  394.     private boolean isCanMove()     
  395.     {     
  396.         return isCanMove( act_move );     
  397.     }     
  398.     private boolean isCanMove( int act )     
  399.     {     
  400.         forint i=0; i<4; i++ )     //行     
  401.         {     
  402.             forint j=0; j<4; j++ ) //列     
  403.             {     
  404.                 if( ( box[box_state] & matrix[i][j] ) == matrix[i][j] ) //是格子     
  405.                 {     
  406.                     if( s_box_x+j < 0 )                  //左边界检测     
  407.                     {     
  408.                         if( act == act_transfiguration )//左边界检测失败 调整 BOX 位置右移动 最多2格     
  409.                         {     
  410.                             act_off_x=1;     
  411.                             s_box_x ++;     
  412.                             if( isCanMove() )     
  413.                             {     
  414.                                 return true;     
  415.                             }     
  416.                             else    
  417.                             {     
  418.                                 act_off_x=2;     
  419.                                 s_box_x ++;     
  420.                                 if( isCanMove() )     
  421.                                 {     
  422.                                     return true;     
  423.                                 }     
  424.                                 else    
  425.                                 {     
  426.                                     act_off_x = 0;     
  427.                                 }     
  428.                             }     
  429.                         }     
  430.                         System.out.println( "left s_box_x="+s_box_x+" matrix["+i+"]["+j+"]="+matrix[i][j]);     
  431.                         return false;     
  432.                     }     
  433.                     if( s_box_x+j > s_box_w_sum-1 )  //右边界检测     
  434.                     {     
  435.                         if( act == act_transfiguration )//右边界检测失败 调整 BOX 位置左移动 最多1格     
  436.                         {     
  437.                             act_off_x = -1;     
  438.                             s_box_x --;     
  439.                             if( isCanMove() )     
  440.                             {     
  441.                                 return true;     
  442.                             }     
  443.                             else    
  444.                             {     
  445.                                 act_off_x = 0;     
  446.                             }     
  447.                         }     
  448.                         System.out.println( "right s_box_x="+s_box_x+" matrix["+i+"]["+j+"]="+matrix[i][j]);     
  449.                         return false;     
  450.                     }     
  451.                     if( s_box_y+i > s_box_h_sum-1 )  //下边界检测     
  452.                     {     
  453.                         System.out.println( "down s_box_y="+s_box_y+" matrix["+i+"]["+j+"]="+matrix[i][j]);     
  454.                         return false;     
  455.                     }     
  456.                     if( map[s_box_y+i][s_box_x+j] > 0 )  //地图格子检测     
  457.                     {     
  458.                         System.out.println( "map s_box_y="+s_box_y+" matrix["+i+"]["+j+"]="+matrix[i][j]);     
  459.                         return false;     
  460.                     }     
  461.                 }     
  462.             }     
  463.         }     
  464.         return true;     
  465.     }     
  466.     private short isKeyDown = 0;    //0没有按下,1按下,2抬起     
  467. //  public boolean keyDown(Event evt, int key)     
  468.     public void keyPressed( int key )     
  469.     {     
  470.         key = getKeyCode( key );     
  471.         switch( key )     
  472.         {     
  473.             case UP:                //顺时针旋转     
  474.                 isKeyDown = 0;      //0没有按下     
  475.                 box_state ++;     
  476.                 box_state %= 4;     
  477. //              s_box_x -= act_off_x;   //恢复偏移中心到未偏移前//不恢复的好1     
  478.                 if( !isCanMove( act_transfiguration ) )     
  479.                 {     
  480.                     box_state --;     
  481.                     if( box_state<0 )     
  482.                         box_state = 3;     
  483.                 }     
  484.             break;     
  485.             case DOWN:              //向下移动     
  486.                 act_off_x = 0;      //恢复BOX旋转位置偏移为0     
  487.                 if( isKeyDown == 2 )     
  488.                     isKeyDown = 1;     
  489.                 if( isKeyDown == 1 )     
  490.                 {     
  491.                     s_box_y ++;      
  492.                     if( !isCanMove() )     
  493.                         s_box_y --;     
  494.                 }     
  495.             break;     
  496.             case LEFT:              //向左移动BOX     
  497.                 act_off_x = 0;      //恢复BOX旋转位置偏移为0     
  498.                 isKeyDown = 0;      //0没有按下     
  499.                 s_box_x --;     
  500.                 if( !isCanMove() )     
  501.                     s_box_x ++;      
  502.             break;     
  503.             case RIGHT:             //向右移动BOX     
  504.                 act_off_x = 0;      //恢复BOX旋转位置偏移为0     
  505.                 isKeyDown = 0;      //0没有按下     
  506.                 s_box_x ++;     
  507.                 if( !isCanMove() )     
  508.                     s_box_x --;     
  509.             break;     
  510.             case 53:                //数字5键     
  511.                 if( isGameOver )    //游戏结束     
  512.                     initGame();     //重新游戏     
  513.             break;     
  514.             case 42:     
  515.                 if( isGameOver )    //游戏结束     
  516. //                  System.exit(0); //退出游戏     
  517.                     Tetris.s_midlet.destroyApp(true);     
  518.             break;     
  519.             case 48:     
  520.                 setBox();           //新的BOX     
  521.             break;     
  522.             case 49:                //是否显示网格     
  523.                 isShowReseau = !isShowReseau;     
  524.             break;     
  525.         }     
  526.         repaint();                  //重新绘制屏幕     
  527. //      return true;     
  528.     }     
  529.     public void keyRepeated( int key )     
  530.     {     
  531.         keyPressed( key );     
  532.     }     
  533.     public void setNextBox()     
  534.     {     
  535.         int sho   = Math.abs( rand.nextInt() );     
  536.         s_next_box= (short)(sho%box_sum.length);     
  537. //      s_next_box= (short)( rand.nextInt(box_sum.length) );     
  538.         System.arraycopy( box_sum[s_next_box], 0, next_box, 0, next_box.length );     
  539.         s_next_box++;     
  540.     }     
  541.     
  542.     public int getKeyCode( int key )     
  543.     {     
  544.         System.out.println( "key="+key );     
  545.         switch( key )     
  546.         {     
  547.             case 1004:  // up     
  548.             case 119:   // w     
  549.             case 87:    // W     
  550.             case 50:    // 2     
  551.             return UP;     
  552.     
  553.             case 1005:  // down     
  554.             case 115:   // s     
  555.             case 83:    // S     
  556.             case 56:    // 8     
  557.             return DOWN;     
  558.     
  559.             case 1006:  // left     
  560.             case 97:    // a     
  561.             case 65:    // A     
  562.             case 52:    // 4     
  563.             return LEFT;     
  564.     
  565.             case 1007:  // right     
  566.             case 100:   // d     
  567.             case 68:    // D     
  568.             case 54:    // 6     
  569.             return RIGHT;     
  570.             default:     
  571.             return key;     
  572.         }     
  573.     }     
  574. //  public boolean keyUp(Event evt, int key)      
  575.     public void keyReleased( int key )      
  576.     {     
  577.         isKeyDown = 2;  //释放按键     
  578. //      return true;     
  579.     }     
  580. //  public boolean mouseDown(Event evt, int x, int y)     
  581. //  {     
  582. //      try     
  583. //      {     
  584. ////            System.out.println( "x="+x+" y="+y );     
  585. //      }catch( Exception e){e.printStackTrace();}     
  586. ////        this.repaint();     
  587. //      return true;     
  588. //  }     
  589. //  public boolean mouseMove(Event evt, int x, int y)     
  590. //  {     
  591. //      try     
  592. //      {     
  593. //          //System.out.println( "x="+x+" y="+y );     
  594. //      }catch( Exception e){e.printStackTrace();}     
  595. //      return true;     
  596. //  }     
  597. //    public static void main(String[] args)      
  598. //    {     
  599. //      JFrame frame = new JFrame("俄罗斯方块 北京|雷神 QQ:38929568");     
  600. //      final cGame dc = new cGame();     
  601. //      frame.getContentPane().add(dc, BorderLayout.CENTER);     
  602. //     
  603. ////        JButton button = new JButton("刷新");     
  604. ////        button.addActionListener(new ActionListener()      
  605. ////        {     
  606. ////            public void actionPerformed(ActionEvent e)      
  607. ////            {     
  608. ////                dc.repaint();     
  609. ////            }     
  610. ////        });     
  611. ////        frame.getContentPane().add(button, BorderLayout.SOUTH);     
  612. //      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);     
  613. //      frame.setSize(dc.s_width+10, dc.s_height+30);     
  614. //      frame.setVisible(true);     
  615. //  }     
  616. }    
  617. package code;  
  618.  
  619. //import java.awt.*;  
  620. //import java.awt.Canvas;  
  621. //import java.awt.event.*;  
  622. //import javax.swing.*;  
  623. import java.util.Random;  
  624. import javax.microedition.lcdui.*;          //写界面所需要的包  
  625. /**  
  626.  * 俄罗斯方块  
  627.  * 高雷  
  628.  * 2007年11月30日  
  629.  */ 
  630. public class cGame240x320 extends Canvas implements Runnable   
  631. {  
  632.       
  633.     private Random rand;  
  634.     private Thread thread;  
  635.     private Graphics    gb;  
  636.     private Image       buffer;  
  637.     private Image       gameOverImg;                    //游戏结束  
  638.     private static final int s_width    = 240;  
  639.     private static final int s_height   = 320;  
  640.     private static final int s_box_w    = 16;  
  641.     private static final int s_box_h    = 16;  
  642.     private static final int s_box_w_sum    = 10;       //操作区域宽 格子数  
  643.     private static final int s_box_h_sum    = 20;       //操作区域高 格子数  
  644.     private static final int s_line_between_x = s_box_w * s_box_w_sum;//分割线x位置  
  645.  
  646.     public static final int  UP     = -1;  
  647.     public static final int  DOWN   = -2;  
  648.     public static final int  LEFT   = -3;  
  649.     public static final int  RIGHT  = -4;  
  650.       
  651.     public static final int  init_x         = 3;        //当前方块初始化坐标X  
  652.     public static final int  init_y         = 0;        //当前方块初始化坐标y  
  653.       
  654.     public static int   s_box_x             = init_x;   //当前方块坐标X  
  655.     public static int   s_box_y             = init_y;   //当前方块坐标Y  
  656.     private static int  level               = 1;        //等级  
  657.     private static int  success             = 0;        //得分  
  658.     private static long goDownDelayTime[]   = //1800;   //下降延迟时间  
  659.     {  
  660.         1000,   900,    800,    700,  
  661.         600,    500,    400,  
  662.         300,    200,    100 
  663.     };  
  664.     private static int  level_up            = (int)(goDownDelayTime[0]-goDownDelayTime[level]);     //升级成绩  
  665.     private static boolean isShowReseau     = true;     //是否现实网格  
  666.     private static short s_next_box         = 0;        //下一个方块编号  
  667.     private static short boxColor;                      //当前box的颜色  
  668. //  private static final Color gameBG       = new Color( 0x333333 );    //游戏区域背景颜色  
  669.     private static final int gameBG         = 0x333333//游戏区域背景颜色  
  670. //  private static final Color gameColor[]  = new Color[]  
  671.     private static final int gameColor[]    = new int[]  
  672.     {  
  673.         0x444444,   //new Color( 0x444444 ),    //网格颜色  
  674.         0xEEEEEE,   //new Color( 0xEEEEEE ),    //方块颜色  
  675.         0xEE0000,   //new Color( 0xEE0000 ),  
  676.         0x00EE00,   //new Color( 0x00EE00 ),  
  677.         0x0000EE,   //new Color( 0x0000EE ),  
  678.         0xEE00EE,   //new Color( 0xEE00EE ),  
  679.         0xEEEE00,   //new Color( 0xEEEE00 ),  
  680.         0x00EEEE    //new Color( 0x00EEEE )  
  681.     };  
  682.     private static final short box_sum[][] = new short[][]  //所有方块图形  
  683.     {  
  684.         { 0x06600x06600x06600x0660 },  
  685.         { 0x22220x00F00x22220x00F0 },  
  686.         { 0x02640x06300x02640x0630 },  
  687.         { 0x04620x03600x04620x0360 },  
  688.         { 0x02E00x44600x07400x0622 },  
  689.         { 0x0E200x22600x04700x0644 },  
  690.         { 0x04640x00E40x04C40x04E0 }  
  691.     };  
  692.  
  693.     private static short next_box[] = new short[]{ 0x06600x06600x06600x0660 };   
  694.     private static short box[]      = new short[]{ 0x06600x06600x06600x0660 };  
  695.     private static short map[][];       //地图  
  696.     private static short box_state  = 0;//当前BOX的状态//旋转方向  
  697.     private static short matrix[][] =   //定义矩阵用来计算出box_sum的方块  
  698.     {  
  699.         { 0x10000x01000x00100x0001 },  
  700.         { 0x20000x02000x00200x0002 },  
  701.         { 0x40000x04000x00400x0004 },  
  702.         { (short)0x80000x08000x00800x0008 }  
  703.     };  
  704.  
  705.     public cGame240x320()  
  706.     {  
  707.         setFullScreenMode(true);        //设置游戏为全屏幕模式,该函数只能在支持midp2.0的手机上使用  
  708. //      s_width = getWidth();           //得到屏幕尺寸     宽  
  709. //      s_height= getHeight();          //得到屏幕尺寸     高  
  710.         rand = new Random( System.currentTimeMillis() );  
  711.         try 
  712.         {  
  713.             //gameOverImg = Toolkit.getDefaultToolkit().getImage("src/pics/laser.png");  
  714.             gameOverImg = Image.createImage("/pics/laser.png");  
  715.         }catch(Exception e){}  
  716.         //setSize( s_width, s_height ); //设置画布  
  717.         Sound.initSound();              //初始化声音资源  
  718.         initGame();                     //游戏初始化  
  719.         thread  = new Thread(this);  
  720.         thread.start();  
  721.     }  
  722.       
  723.     private void initGame()  
  724.     {  
  725.         level       = 1;                //等级  
  726.         success     = 0;                //得分  
  727.         map  = new short[s_box_h_sum][s_box_w_sum];  
  728.         setNextBox();                   //设置下一个BOX  
  729.         setBox();                       //将下一个BOX设置成当前BOX  
  730.         setGameOver( false );           //恢复游戏  
  731.     }  
  732.       
  733.     private void setBox()               //将next_box设置成当前可控制box  
  734.     {  
  735.         box_state       = 0;                                        //box 状态  
  736.         s_box_x         = init_x;                                   //当前方块坐标X  
  737.         s_box_y         = init_y;                                   //当前方块坐标Y  
  738.         boxColor        = s_next_box;                               //设置当前BOX颜色  
  739.         System.arraycopy( next_box, 0, box, 0, next_box.length );   //box = next_box  
  740.         goDownPreTime   = System.currentTimeMillis();               //设置好当前BOX后 计时  
  741.         setNextBox();                                               //设置下一个BOX  
  742.         if( !isCanMove() )  
  743.         {  
  744.             setGameOver( true );  
  745.         }  
  746.     }  
  747.  
  748.     public static boolean isGameOver = false;  
  749.     public static long updatas  = 0;  
  750.     public static long fps      = 0;  
  751.     private long    startTime, beginTime, endTime;  
  752.     private long    delay       = 25;  
  753.     private long    upTime      = 25;  
  754.     public void run()   
  755.     {  
  756.         while ( true )   
  757.         {  
  758.             try 
  759.             {  
  760.                 beginTime = System.currentTimeMillis();  
  761.                 updatas++;  
  762.                 updata( updatas );  
  763.                 repaint();  
  764.                 endTime = System.currentTimeMillis();  
  765.                 upTime  = endTime-beginTime;  
  766.                 if( upTime<delay )  
  767.                 {  
  768.                     fps = 1000/delay;  
  769.                     thread.sleep(delay-upTime);  
  770.                 }  
  771.                 else 
  772.                     fps = 1000/upTime;  
  773.             }catch(Exception e){ }  
  774.         }  
  775.     }  
  776.     void setGameOver( boolean _isGameOver )  
  777.     {  
  778.         isGameOver = _isGameOver;  
  779.     }  
  780.     public void updata( long updatas )  
  781.     {  
  782.  
  783.     }  
  784.     public void update(Graphics g)   
  785.     {  
  786.         paint(g);  
  787.     }  
  788.     public static int   offx    = 0;  
  789.     public static int   offy    = 0;  
  790.     public void paint(Graphics g)  
  791.     {  
  792.         try 
  793.         {  
  794.             if( buffer == null )  
  795.             {  
  796.                 buffer = Image.createImage( s_width, s_height );    //设置画布缓冲区  
  797.                 gb = buffer.getGraphics();                  //得到绘图设备  
  798.             }  
  799. //          gb.translate( offx, offy );  
  800. //          gb.setColor( new Color( 0x0 ) );                //初始化 画布颜色  
  801.             gb.setColor( 0x0 );                             //初始化 画布颜色  
  802.             gb.setClip ( 00, s_width, s_height);          //初始化 画布区域  
  803.             gb.fillRect( 00, s_width, s_height);          //初始化 画布填充  
  804.             paintReseau( gb );                              //绘制网格  
  805.             paintNextBox( gb );                             //绘制下一BOX  
  806.             paintMap( gb );                                 //绘制地图上不可以动BOX  
  807.             paintBox( gb, s_box_x, s_box_y );               //绘制当前可控制BOX  
  808. //          gb.setColor( new Color( 0xFF3333 ) );           //分割线颜色  
  809.             gb.setColor( 0xFF3333 );                        //分割线颜色  
  810.             gb.drawLine( s_line_between_x, 0, s_line_between_x, s_height ); //分割线  
  811. //          gb.drawString( "FPS:"+fps,          s_line_between_x+10,10 );   //祯数  
  812. //          gb.drawString( "等级:"+level,         s_line_between_x+10,30 );   //等级  
  813. //          gb.drawString( "得分:"+success,       s_line_between_x+10,50 );   //分数  
  814.             gb.drawString( "FPS:"+fps,          s_line_between_x+1010, g.TOP|g.LEFT );//祯数  
  815.             gb.drawString( "等级:"+level,         s_line_between_x+1030, g.TOP|g.LEFT );//等级  
  816.             gb.drawString( "得分:"+success,       s_line_between_x+1050, g.TOP|g.LEFT );//分数  
  817.             if( isGameOver )  
  818.             {  
  819. //              gb.drawImage( gameOverImg, (getWidth()-offx-gameOverImg.getWidth(null))/2, (getHeight()-gameOverImg.getHeight(null))/2 , null );  
  820.                 gb.drawImage( gameOverImg,  s_width>>1, s_height>>1, g.HCENTER|g.VCENTER );  
  821.             }  
  822. //          gb.translate( -offx, -offy );  
  823.         }  
  824.         catch(Exception e)  
  825.         {   
  826.             System.out.println("err at paint.e====="+e);  
  827.         }  
  828. //      g.drawImage( buffer, offx, offy, null);             //将画布缓冲区绘制到屏幕//偏移 (2,2)  
  829.         g.drawImage( buffer, offx, offy, 0);                //将画布缓冲区绘制到屏幕//偏移 (2,2)  
  830.     }  
  831.       
  832.     private void paintReseau( Graphics g )                  //绘制网格  
  833.     {  
  834.         g.setColor( gameBG );  
  835.         g.fillRect( 00, s_line_between_x, s_height );  
  836.         if( isShowReseau )  
  837.         {  
  838.             g.setColor( gameColor[0] );  
  839.             forint i=0; i<s_line_between_x/s_box_w; i++ ) // |  
  840.             {  
  841.                 g.drawLine( i*s_box_h, 0, i*s_box_h, s_height );  
  842.             }  
  843.             forint j=0; j<s_height/s_box_h; j++ )         // -  
  844.             {  
  845.                 g.drawLine( 0, j*s_box_w, s_line_between_x, j*s_box_w );  
  846.             }  
  847.         }  
  848.     }  
  849.     private void paintBox( Graphics g, int off_x, int off_y )  
  850.     {  
  851.         forint i=0; i<4; i++ )        //行  
  852.         {  
  853.             forint j=0; j<4; j++ )    //列  
  854.             {  
  855.                 if( (box[box_state] & matrix[i][j]) == matrix[i][j] )  
  856.                 {  
  857.                     g.setColor( gameColor[ boxColor ] );  
  858.                     g.fillRect( (off_x+j)*s_box_w, (off_y+i)*s_box_h, s_box_w, s_box_h );  
  859.  
  860.                     g.setColor( gameBG );  
  861.                     g.drawRect( (off_x+j)*s_box_w+1, (off_y+i)*s_box_h+1, s_box_w-2, s_box_h-2 );  
  862.                 }  
  863.             }  
  864.         }  
  865.         goDown();                       //BOX是否下降  
  866.     }  
  867.     private void paintNextBox( Graphics g )  
  868.     {  
  869.         int off_x = s_line_between_x+( s_width - s_line_between_x - 4*s_box_w )/2;  
  870.         int off_y = s_height/2;  
  871.           
  872.         g.translate( off_x, off_y );  
  873.         g.setColor( gameBG );  
  874.         g.fillRect( 004*s_box_w, 4*s_box_h );  
  875.           
  876.         if( isShowReseau )              //显示格式  
  877.         {  
  878.             g.setColor( gameColor[0] );  
  879.             forint i=0; i<5; i++ )    // |  
  880.             {  
  881.                 g.drawLine( i*s_box_h, 0, i*s_box_h, 4*s_box_h );  
  882.             }  
  883.             forint j=0; j<5; j++ )    // -  
  884.             {  
  885.                 g.drawLine( 0, j*s_box_w, 4*s_box_w, j*s_box_w );  
  886.             }  
  887.         }  
  888.         forint i=0; i<4; i++ )        //行  
  889.         {  
  890.             forint j=0; j<4; j++ )    //列  
  891.             {  
  892.                 if( (next_box[0] & matrix[i][j]) == matrix[i][j] )  
  893.                 {  
  894.                     g.setColor( gameColor[ s_next_box ] );  
  895.                     g.fillRect( j*s_box_w, i*s_box_h, s_box_w, s_box_h );  
  896.  
  897.                     g.setColor( gameBG );  
  898.                     g.drawRect( j*s_box_w+1, i*s_box_h+1, s_box_w-2, s_box_h-2 );  
  899.                 }  
  900.             }  
  901.         }  
  902.         g.translate( -off_x, -off_y );  
  903.     }  
  904.  
  905.     private long goDownPreTime  = 0;    //上次下降时间  
  906.     private long currTime       = 0;    //当前时间  
  907.     private void goDown()               //当前BOX下降  
  908.     {  
  909.         if( isGameOver )    //游戏结束  
  910.             return;  
  911.         //isKeyDown按了向下移动就需要检查 不需要时间  
  912.         if( isKeyDown==1 || System.currentTimeMillis() - goDownPreTime >= goDownDelayTime[level] )  
  913.         {  
  914.             s_box_y++;  
  915.             goDownPreTime = System.currentTimeMillis();  
  916.             if( !isCanMove() )  
  917.             {  
  918.                 isKeyDown = 0;  //没有按下  
  919.                 s_box_y--;  
  920.                 setMap();       //将BOX放进map   
  921.                 setBox();       //新的BOX  
  922.             }  
  923.         }  
  924.     }  
  925.       
  926.     private void setMap()  
  927.     {  
  928.         forint i=0; i<4; i++ )        //行  
  929.         {  
  930.             forint j=0; j<4; j++ )    //列  
  931.             {  
  932.                 if( ( box[box_state] & matrix[i][j] ) == matrix[i][j] ) //是格子  
  933.                 {  
  934.                     map[s_box_y+i][s_box_x+j] = boxColor;  
  935.                 }  
  936.             }  
  937.         }  
  938.         //检测是否可以消去一行  
  939.         int line_success = 0;  
  940.         forint i=0; i<s_box_h_sum; i++ )      //行  
  941.         {  
  942.             if( isFullLine( i ) )               //这行可以消去  
  943.             {  
  944.                 setNullLine( i );               //设置第i行为空  
  945.                 setGoDownMap( i );              //地图第i行以上的向下移动一行  
  946.                 line_success++;  
  947.                 Sound.playSound( 0 );  
  948.             }  
  949.         }  
  950.         success += line_success*line_success;   //设置得分  
  951.         level_up = (int)(goDownDelayTime[0]-goDownDelayTime[level]);  
  952.         if( success >= level_up )               //设置升级  
  953.         {  
  954.             level %= goDownDelayTime.length;  
  955.             level ++;  
  956.         }  
  957.     }  
  958.  
  959.     private void paintMap( Graphics g )  
  960.     {  
  961.         forint i=0; i<s_box_h_sum; i++ )      //行  
  962.         {  
  963.             forint j=0; j<s_box_w_sum; j++ )  //列  
  964.             {  
  965.                 if( map[i][j] > 0 )             //是格子//绘制格子  
  966.                 {  
  967.                     g.setColor( gameColor[ map[i][j] ] );  
  968.                     g.fillRect( j*s_box_w, i*s_box_h, s_box_w, s_box_h );     
  969.                       
  970.                     g.setColor( gameBG );  
  971.                     g.drawRect( j*s_box_w+1, i*s_box_h+1, s_box_w-2, s_box_h-2 );  
  972.                 }  
  973.             }  
  974.         }  
  975.     }  
  976.       
  977.     private boolean isFullLine(int line)    //是否一行已经满了  
  978.     {  
  979.         forint j=0; j<s_box_w_sum; j++ )  //列  
  980.         {  
  981.             if( map[line][j] <= 0 )  
  982.             {  
  983.                 return false;  
  984.             }  
  985.         }  
  986.         return true;  
  987.     }  
  988.       
  989.     private void  setNullLine( int line )   //设置地图上的这一行 空  
  990.     {  
  991.         forint j=0; j<s_box_w_sum; j++ )  //列  
  992.         {  
  993.             map[line][j] = 0;  
  994.         }     
  995.     }  
  996.     private void setGoDownMap( int line )   //设置地图line以上的每行都向下移动一行  
  997.     {  
  998.         forint i=line; i>0; i-- )         //行  
  999.         {  
  1000.             forint j=0; j<s_box_w_sum; j++ )  //列  
  1001.             {  
  1002.                 map[i][j] = map[i-1][j];    //向下移动一行  
  1003.             }  
  1004.         }  
  1005.     }  
  1006.     private static       int act_off_x  = 0;    //方块在左右边界旋转的时候调整方块位置的偏移  
  1007.     private static final int act_move   = 0;  
  1008.     private static final int act_transfiguration = 1;  
  1009.     private boolean isCanMove()  
  1010.     {  
  1011.         return isCanMove( act_move );  
  1012.     }  
  1013.     private boolean isCanMove( int act )  
  1014.     {  
  1015.         forint i=0; i<4; i++ )        //行  
  1016.         {  
  1017.             forint j=0; j<4; j++ )    //列  
  1018.             {  
  1019.                 if( ( box[box_state] & matrix[i][j] ) == matrix[i][j] ) //是格子  
  1020.                 {  
  1021.                     if( s_box_x+j < 0 )                 //左边界检测  
  1022.                     {  
  1023.                         if( act == act_transfiguration )//左边界检测失败 调整 BOX 位置右移动 最多2格  
  1024.                         {  
  1025.                             act_off_x=1;  
  1026.                             s_box_x ++;  
  1027.                             if( isCanMove() )  
  1028.                             {  
  1029.                                 return true;  
  1030.                             }  
  1031.                             else 
  1032.                             {  
  1033.                                 act_off_x=2;  
  1034.                                 s_box_x ++;  
  1035.                                 if( isCanMove() )  
  1036.                                 {  
  1037.                                     return true;  
  1038.                                 }  
  1039.                                 else 
  1040.                                 {  
  1041.                                     act_off_x = 0;  
  1042.                                 }  
  1043.                             }  
  1044.                         }  
  1045.                         System.out.println( "left s_box_x="+s_box_x+" matrix["+i+"]["+j+"]="+matrix[i][j]);  
  1046.                         return false;  
  1047.                     }  
  1048.                     if( s_box_x+j > s_box_w_sum-1 ) //右边界检测  
  1049.                     {  
  1050.                         if( act == act_transfiguration )//右边界检测失败 调整 BOX 位置左移动 最多1格  
  1051.                         {  
  1052.                             act_off_x = -1;  
  1053.                             s_box_x --;  
  1054.                             if( isCanMove() )  
  1055.                             {  
  1056.                                 return true;  
  1057.                             }  
  1058.                             else 
  1059.                             {  
  1060.                                 act_off_x = 0;  
  1061.                             }  
  1062.                         }  
  1063.                         System.out.println( "right s_box_x="+s_box_x+" matrix["+i+"]["+j+"]="+matrix[i][j]);  
  1064.                         return false;  
  1065.                     }  
  1066.                     if( s_box_y+i > s_box_h_sum-1 ) //下边界检测  
  1067.                     {  
  1068.                         System.out.println( "down s_box_y="+s_box_y+" matrix["+i+"]["+j+"]="+matrix[i][j]);  
  1069.                         return false;  
  1070.                     }  
  1071.                     if( map[s_box_y+i][s_box_x+j] > 0 ) //地图格子检测  
  1072.                     {  
  1073.                         System.out.println( "map s_box_y="+s_box_y+" matrix["+i+"]["+j+"]="+matrix[i][j]);  
  1074.                         return false;  
  1075.                     }  
  1076.                 }  
  1077.             }  
  1078.         }  
  1079.         return true;  
  1080.     }  
  1081.     private short isKeyDown = 0;    //0没有按下,1按下,2抬起  
  1082. //  public boolean keyDown(Event evt, int key)  
  1083.     public void keyPressed( int key )  
  1084.     {  
  1085.         key = getKeyCode( key );  
  1086.         switch( key )  
  1087.         {  
  1088.             case UP:                //顺时针旋转  
  1089.                 isKeyDown = 0;      //0没有按下  
  1090.                 box_state ++;  
  1091.                 box_state %= 4;  
  1092. //              s_box_x -= act_off_x;   //恢复偏移中心到未偏移前//不恢复的好1  
  1093.                 if( !isCanMove( act_transfiguration ) )  
  1094.                 {  
  1095.                     box_state --;  
  1096.                     if( box_state<0 )  
  1097.                         box_state = 3;  
  1098.                 }  
  1099.             break;  
  1100.             case DOWN:              //向下移动  
  1101.                 act_off_x = 0;      //恢复BOX旋转位置偏移为0  
  1102.                 if( isKeyDown == 2 )  
  1103.                     isKeyDown = 1;  
  1104.                 if( isKeyDown == 1 )  
  1105.                 {  
  1106.                     s_box_y ++;   
  1107.                     if( !isCanMove() )  
  1108.                         s_box_y --;  
  1109.                 }  
  1110.             break;  
  1111.             case LEFT:              //向左移动BOX  
  1112.                 act_off_x = 0;      //恢复BOX旋转位置偏移为0  
  1113.                 isKeyDown = 0;      //0没有按下  
  1114.                 s_box_x --;  
  1115.                 if( !isCanMove() )  
  1116.                     s_box_x ++;   
  1117.             break;  
  1118.             case RIGHT:             //向右移动BOX  
  1119.                 act_off_x = 0;      //恢复BOX旋转位置偏移为0  
  1120.                 isKeyDown = 0;      //0没有按下  
  1121.                 s_box_x ++;  
  1122.                 if( !isCanMove() )  
  1123.                     s_box_x --;  
  1124.             break;  
  1125.             case 53:                //数字5键  
  1126.                 if( isGameOver )    //游戏结束  
  1127.                     initGame();     //重新游戏  
  1128.             break;  
  1129.             case 42:  
  1130.                 if( isGameOver )    //游戏结束  
  1131. //                  System.exit(0); //退出游戏  
  1132.                     Tetris.s_midlet.destroyApp(true);  
  1133.             break;  
  1134.             case 48:  
  1135.                 setBox();           //新的BOX  
  1136.             break;  
  1137.             case 49:                //是否显示网格  
  1138.                 isShowReseau = !isShowReseau;  
  1139.             break;  
  1140.         }  
  1141.         repaint();                  //重新绘制屏幕  
  1142. //      return true;  
  1143.     }  
  1144.     public void keyRepeated( int key )  
  1145.     {  
  1146.         keyPressed( key );  
  1147.     }  
  1148.     public void setNextBox()  
  1149.     {  
  1150.         int sho   = Math.abs( rand.nextInt() );  
  1151.         s_next_box= (short)(sho%box_sum.length);  
  1152. //      s_next_box= (short)( rand.nextInt(box_sum.length) );  
  1153.         System.arraycopy( box_sum[s_next_box], 0, next_box, 0, next_box.length );  
  1154.         s_next_box++;  
  1155.     }  
  1156.  
  1157.     public int getKeyCode( int key )  
  1158.     {  
  1159.         System.out.println( "key="+key );  
  1160.         switch( key )  
  1161.         {  
  1162.             case 1004:  // up  
  1163.             case 119:   // w  
  1164.             case 87:    // W  
  1165.             case 50:    // 2  
  1166.             return UP;  
  1167.  
  1168.             case 1005:  // down  
  1169.             case 115:   // s  
  1170.             case 83:    // S  
  1171.             case 56:    // 8  
  1172.             return DOWN;  
  1173.  
  1174.             case 1006:  // left  
  1175.             case 97:    // a  
  1176.             case 65:    // A  
  1177.             case 52:    // 4  
  1178.             return LEFT;  
  1179.  
  1180.             case 1007:  // right  
  1181.             case 100:   // d  
  1182.             case 68:    // D  
  1183.             case 54:    // 6  
  1184.             return RIGHT;  
  1185.             default:  
  1186.             return key;  
  1187.         }  
  1188.     }  
  1189. //  public boolean keyUp(Event evt, int key)   
  1190.     public void keyReleased( int key )   
  1191.     {  
  1192.         isKeyDown = 2;  //释放按键  
  1193. //      return true;  
  1194.     }  
  1195. //  public boolean mouseDown(Event evt, int x, int y)  
  1196. //  {  
  1197. //      try  
  1198. //      {  
  1199. ////            System.out.println( "x="+x+" y="+y );  
  1200. //      }catch( Exception e){e.printStackTrace();}  
  1201. ////        this.repaint();  
  1202. //      return true;  
  1203. //  }  
  1204. //  public boolean mouseMove(Event evt, int x, int y)  
  1205. //  {  
  1206. //      try  
  1207. //      {  
  1208. //          //System.out.println( "x="+x+" y="+y );  
  1209. //      }catch( Exception e){e.printStackTrace();}  
  1210. //      return true;  
  1211. //  }  
  1212. //    public static void main(String[] args)   
  1213. //    {  
  1214. //      JFrame frame = new JFrame("俄罗斯方块 北京|雷神 QQ:38929568");  
  1215. //      final cGame dc = new cGame();  
  1216. //      frame.getContentPane().add(dc, BorderLayout.CENTER);  
  1217. //  
  1218. ////        JButton button = new JButton("刷新");  
  1219. ////        button.addActionListener(new ActionListener()   
  1220. ////        {  
  1221. ////            public void actionPerformed(ActionEvent e)   
  1222. ////            {  
  1223. ////                dc.repaint();  
  1224. ////            }  
  1225. ////        });  
  1226. ////        frame.getContentPane().add(button, BorderLayout.SOUTH);  
  1227. //      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
  1228. //      frame.setSize(dc.s_width+10, dc.s_height+30);  
  1229. //      frame.setVisible(true);  
  1230. //  }  

这部分代码和前一篇(俄罗斯方块_3)的代码基本一致,只是添加了声音的初始化和播放方法!

给大家参考,

为了程序完整性,该程序还有一个主MIDlet类

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

程序代码部分就这3个类,另外整个工程已经打包上传,如果还有问题可以在这里留言,我会经常来看的!