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

作者:雷神
QQ:38929568
QQ群:28048051JAVA游戏编程(满) 28047782(满) 50761834(新开)

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

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

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

游戏图片: 

JAVA游戏编程之三----j2me 手机游戏入门开发--俄罗斯方块_2_第1张图片

工程文件已经打包上传到csdn,地址如下
download.csdn.net/user/kome2000/

代码如下:

 

package  code;
////////////////////////////////////////////////////////////////////////////////////////////////// /
/**
 * 俄罗斯方块
 * 高雷
 * 2007年11月30日
 
*/

////////////////////////////////////////////////////////////////////////////////////////////////// /
import  javax.microedition.midlet. * ;     // j2me MIDlet程序必须继承MIDlet类,所以要引入此包
import  javax.microedition.lcdui. * ;     // Display这个类所在包

////////////////////////////////////////////////////////////////////////////////////////////////// /

public   class  Tetris  extends  MIDlet 
{
    
static Tetris s_midlet;    //MIDlet类的静态对象,方便实用 MIDlet类方法
    static Display s_display = null;//用来显示 Canvas
    static cGame s_game = null;        //Canvas类对象,主要实现游戏的类
    
    
public Tetris()
    
{
        s_midlet 
= this;
    }

    
    
/**
     * 程序开始 系统会调用这个函数
     * 也有些手机 可以把程序初始化部分放到构造函数里,这连个地方应视手机的不同而定!
     
*/

    
public void startApp()             
    
{
        
if (s_display == null
        
{
            s_display 
= Display.getDisplay(this);//创建Display对象,参数是MIDlet类对象,也就是我们当前写的这个Minesweeper类
        }


        
if (s_game == null
        
{
            s_game 
= new cGame();                //创建 Canvas对象
            s_display.setCurrent(s_game);        //把Canvas对象设置成当前显示
        }
 
        
else 
        
{
            s_display.setCurrent(s_game);
        }

    }


    
/**
     * 程序暂停 系统会自动调用这个函数,不是所有手机都支持,
     * 手机在接到中断,如 来电,来短信时候会调用这个函数,这个函数 通常是空的!
     
*/

    
public void pauseApp()         
    
{
        
    }


    
/**
     * 程序关闭 系统会调用这个函数,如果希望关闭程序的时候保存数据,可在这个函数里添加保存数据的方法
     * 比如游戏进行中,按了关机键,程序就会调用这个函数,也可以在程序中调用这个函数来结束游戏!
     
*/

    
public void destroyApp(boolean unconditional) 
    
{
        notifyDestroyed();
    }

}

 

程序主要逻辑代码类

 

package  code;

// import java.awt.*;
// import java.awt.Canvas;
// import java.awt.event.*;
// import javax.swing.*;
import  java.util.Random;
import  javax.microedition.lcdui. * ;             // 写界面所需要的包
/**
 * 俄罗斯方块
 * 高雷
 * 2007年11月30日
 
*/

public   class  cGame  extends  Canvas  implements  Runnable 
{
    
private Random rand;
    
private Thread thread;
    
private Graphics    gb;
    
private Image        buffer;
    
private Image         gameOverImg;                    //游戏结束
    private static final int s_width      = 240;
    
private static final int s_height     = 320;
    
private static final int s_box_w      = 16;
    
private static final int s_box_h      = 16;
    
private static final int s_box_w_sum     = 10;        //操作区域宽 格子数
    private static final int s_box_h_sum     = 20;        //操作区域高 格子数
    private static final int s_line_between_x = s_box_w * s_box_w_sum;//分割线x位置

    
public static final int  UP     = -1;
    
public static final int  DOWN     = -2;
    
public static final int  LEFT     = -3;
    
public static final int  RIGHT     = -4;
    
    
public static final int  init_x         = 3;        //当前方块初始化坐标X
    public static final int  init_y         = 0;        //当前方块初始化坐标y
    
    
public static int     s_box_x                = init_x;    //当前方块坐标X
    public static int     s_box_y                = init_y;    //当前方块坐标Y
    private static int    level                = 1;        //等级
    private static int    success                = 0;        //得分
    private static long goDownDelayTime[]    = //1800;    //下降延迟时间
    {
        
1000,    900,    800,    700,
        
600,    500,    400,
        
300,    200,    100
    }
;
    
private static int    level_up            = (int)(goDownDelayTime[0]-goDownDelayTime[level]);        //升级成绩
    private static boolean isShowReseau        = true;        //是否现实网格
    private static short s_next_box            = 0;        //下一个方块编号
    private static short boxColor;                        //当前box的颜色
//    private static final Color gameBG        = new Color( 0x333333 );    //游戏区域背景颜色
    private static final int gameBG            = 0x333333;    //游戏区域背景颜色
//    private static final Color gameColor[]    = new Color[]
    private static final int gameColor[]    = new int[]
    
{
        
0x444444,    //new Color( 0x444444 ),    //网格颜色
        0xEEEEEE,    //new Color( 0xEEEEEE ),    //方块颜色
        0xEE0000,    //new Color( 0xEE0000 ),
        0x00EE00,    //new Color( 0x00EE00 ),
        0x0000EE,    //new Color( 0x0000EE ),
        0xEE00EE,    //new Color( 0xEE00EE ),
        0xEEEE00,    //new Color( 0xEEEE00 ),
        0x00EEEE     //new Color( 0x00EEEE )
    }
;
    
private static final short box_sum[][] = new short[][]    //所有方块图形
    {
        
0x06600x06600x06600x0660 },
        
0x22220x00F00x22220x00F0 },
        
0x02640x06300x02640x0630 },
        
0x04620x03600x04620x0360 },
        
0x02E00x44600x07400x0622 },
        
0x0E200x22600x04700x0644 },
        
0x04640x00E40x04C40x04E0 }
    }
;

    
private static short next_box[] = new short[]0x06600x06600x06600x0660 }
    
private static short box[]          = new short[]0x06600x06600x06600x0660 };
    
private static short map[][];        //地图
    private static short box_state  = 0;//当前BOX的状态//旋转方向
    private static short matrix[][] =    //定义矩阵用来计算出box_sum的方块
    {
        
0x10000x01000x00100x0001 },
        
0x20000x02000x00200x0002 },
        
0x40000x04000x00400x0004 },
        
{ (short)0x80000x08000x00800x0008 }
    }
;

    
public cGame()
    
{
        setFullScreenMode(
true);        //设置游戏为全屏幕模式,该函数只能在支持midp2.0的手机上使用
//        s_width = getWidth();            //得到屏幕尺寸     宽
//        s_height= getHeight();            //得到屏幕尺寸     高
        rand = new Random( System.currentTimeMillis() );
        
try
        
{
            
//gameOverImg = Toolkit.getDefaultToolkit().getImage("src/pics/laser.png");
            gameOverImg = Image.createImage("/pics/laser.png");
        }
catch(Exception e){}
        
//setSize( s_width, s_height );    //设置画布
        initGame();                        //游戏初始化
        thread  = new Thread(this);
        thread.start();
    }

    
    
private void initGame()
    
{
        level        
= 1;                //等级
        success        = 0;                //得分
        map     = new short[s_box_h_sum][s_box_w_sum];
        setNextBox();                    
//设置下一个BOX
        setBox();                        //将下一个BOX设置成当前BOX
        setGameOver( false );            //恢复游戏
    }

    
    
private void setBox()                //将next_box设置成当前可控制box
    {
        box_state         
= 0;                                        //box 状态
        s_box_x            = init_x;                                    //当前方块坐标X
        s_box_y            = init_y;                                    //当前方块坐标Y
        boxColor        = s_next_box;                                //设置当前BOX颜色
        System.arraycopy( next_box, 0, box, 0, next_box.length );    //box = next_box
        goDownPreTime     = System.currentTimeMillis();                //设置好当前BOX后 计时
        setNextBox();                                                //设置下一个BOX
        if!isCanMove() )
        
{
            setGameOver( 
true );
        }

    }


    
public static boolean isGameOver = false;
    
public static long updatas     = 0;
    
public static long fps         = 0;
    
private long     startTime, beginTime, endTime;
    
private long     delay         = 25;
    
private long     upTime         = 25;
    
public void run() 
    
{
        
while ( true ) 
        
{
            
try
            
{
                beginTime 
= System.currentTimeMillis();
                updatas
++;
                updata( updatas );
                repaint();
                endTime 
= System.currentTimeMillis();
                upTime  
= endTime-beginTime;
                
if( upTime<delay )
                
{
                    fps 
= 1000/delay;
                    thread.sleep(delay
-upTime);
                }

                
else
                    fps 
= 1000/upTime;
            }
catch(Exception e){ }
        }

    }

    
void setGameOver( boolean _isGameOver )
    
{
        isGameOver 
= _isGameOver;
    }

    
public void updata( long updatas )
    
{

    }

    
public void update(Graphics g) 
    
{
        paint(g);
    }

    
public static int     offx     = 0;
    
public static int     offy     = 0;
    
public void paint(Graphics g)
    
{
        
try
        
{
            
if( buffer == null )
            
{
                buffer 
= Image.createImage( s_width, s_height );    //设置画布缓冲区
                gb = buffer.getGraphics();                    //得到绘图设备
            }

//            gb.translate( offx, offy );
//            gb.setColor( new Color( 0x0 ) );                //初始化 画布颜色
            gb.setColor( 0x0 );                                //初始化 画布颜色
            gb.setClip ( 00, s_width, s_height);            //初始化 画布区域
            gb.fillRect( 00, s_width, s_height);            //初始化 画布填充
            paintReseau( gb );                                //绘制网格
            paintNextBox( gb );                                //绘制下一BOX
            paintMap( gb );                                    //绘制地图上不可以动BOX
            paintBox( gb, s_box_x, s_box_y );                //绘制当前可控制BOX
//            gb.setColor( new Color( 0xFF3333 ) );            //分割线颜色
            gb.setColor( 0xFF3333 );                        //分割线颜色
            gb.drawLine( s_line_between_x, 0, s_line_between_x, s_height );    //分割线
//            gb.drawString( "FPS:"+fps,             s_line_between_x+10,10 );    //祯数
//            gb.drawString( "等级:"+level,         s_line_between_x+10,30 );    //等级
//            gb.drawString( "得分:"+success,         s_line_between_x+10,50 );    //分数
            gb.drawString( "FPS:"+fps,             s_line_between_x+1010, g.TOP|g.LEFT );//祯数
            gb.drawString( "等级:"+level,         s_line_between_x+1030, g.TOP|g.LEFT );//等级
            gb.drawString( "得分:"+success,         s_line_between_x+1050, g.TOP|g.LEFT );//分数
            if( isGameOver )
            
{
//                gb.drawImage( gameOverImg, (getWidth()-offx-gameOverImg.getWidth(null))/2, (getHeight()-gameOverImg.getHeight(null))/2 , null );
                gb.drawImage( gameOverImg,    s_width>>1, s_height>>1, g.HCENTER|g.VCENTER );
            }

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

        
catch(Exception e)
        

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

//        g.drawImage( buffer, offx, offy, null);                //将画布缓冲区绘制到屏幕//偏移 (2,2)
        g.drawImage( buffer, offx, offy, 0);                //将画布缓冲区绘制到屏幕//偏移 (2,2)
    }

    
    
private void paintReseau( Graphics g )                    //绘制网格
    {
        g.setColor( gameBG );
        g.fillRect( 
00, s_line_between_x, s_height );
        
if( isShowReseau )
        
{
            g.setColor( gameColor[
0] );
            
forint i=0; i<s_line_between_x/s_box_w; i++ )    // |
            {
                g.drawLine( i
*s_box_h, 0, i*s_box_h, s_height );
            }

            
forint j=0; j<s_height/s_box_h; j++ )            // -
            {
                g.drawLine( 
0, j*s_box_w, s_line_between_x, j*s_box_w );
            }

        }

    }

    
private void paintBox( Graphics g, int off_x, int off_y )
    
{
        
forint i=0; i<4; i++ )        //
        {
            
forint j=0; j<4; j++ )    //
            {
                
if( (box[box_state] & matrix[i][j]) == matrix[i][j] )
                
{
                    g.setColor( gameColor[ boxColor ] );
                    g.fillRect( (off_x
+j)*s_box_w, (off_y+i)*s_box_h, s_box_w, s_box_h );

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

            }

        }

        goDown();                        
//BOX是否下降
    }

    
private void paintNextBox( Graphics g )
    
{
        
int off_x = s_line_between_x+( s_width - s_line_between_x - 4*s_box_w )/2;
        
int off_y = s_height/2;
        
        g.translate( off_x, off_y );
        g.setColor( gameBG );
        g.fillRect( 
004*s_box_w, 4*s_box_h );
        
        
if( isShowReseau )                //显示格式
        {
            g.setColor( gameColor[
0] );
            
forint i=0; i<5; i++ )    // |
            {
                g.drawLine( i
*s_box_h, 0, i*s_box_h, 4*s_box_h );
            }

            
forint j=0; j<5; j++ )    // -
            {
                g.drawLine( 
0, j*s_box_w, 4*s_box_w, j*s_box_w );
            }

        }

        
forint i=0; i<4; i++ )        //
        {
            
forint j=0; j<4; j++ )    //
            {
                
if( (next_box[0& matrix[i][j]) == matrix[i][j] )
                
{
                    g.setColor( gameColor[ s_next_box ] );
                    g.fillRect( j
*s_box_w, i*s_box_h, s_box_w, s_box_h );

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

            }

        }

        g.translate( 
-off_x, -off_y );
    }


    
private long goDownPreTime     = 0;    //上次下降时间
    private long currTime         = 0;    //当前时间
    private void goDown()                //当前BOX下降
    {
        
if( isGameOver )    //游戏结束
            return;
        
//isKeyDown按了向下移动就需要检查 不需要时间
        if( isKeyDown==1 || System.currentTimeMillis() - goDownPreTime >= goDownDelayTime[level] )
        
{
            s_box_y
++;
            goDownPreTime 
= System.currentTimeMillis();
            
if!isCanMove() )
            
{
                isKeyDown 
= 0;    //没有按下
                s_box_y--;
                setMap();        
//将BOX放进map 
                setBox();        //新的BOX
            }

        }

    }

    
    
private void setMap()
    
{
        
forint i=0; i<4; i++ )        //
        {
            
forint j=0; j<4; j++ )    //
            {
                
if( ( box[box_state] & matrix[i][j] ) == matrix[i][j] )    //是格子
                {
                    map[s_box_y
+i][s_box_x+j] = boxColor;
                }

            }

        }

        
//检测是否可以消去一行
        int line_success = 0;
        
forint i=0; i<s_box_h_sum; i++ )        //
        {
            
if( isFullLine( i ) )                //这行可以消去
            {
                setNullLine( i );                
//设置第i行为空
                setGoDownMap( i );                //地图第i行以上的向下移动一行
                line_success++;
            }

        }

        success 
+= line_success*line_success;    //设置得分
        level_up = (int)(goDownDelayTime[0]-goDownDelayTime[level]);
        
if( success >= level_up )                //设置升级
        {
            level 
%= goDownDelayTime.length;
            level 
++;
        }

    }


    
private void paintMap( Graphics g )
    
{
        
forint i=0; i<s_box_h_sum; i++ )        //
        {
            
forint j=0; j<s_box_w_sum; j++ )    //
            {
                
if( map[i][j] > 0 )                //是格子//绘制格子
                {
                    g.setColor( gameColor[ map[i][j] ] );
                    g.fillRect( j
*s_box_w, i*s_box_h, s_box_w, s_box_h );    
                    
                    g.setColor( gameBG );
                    g.drawRect( j
*s_box_w+1, i*s_box_h+1, s_box_w-2, s_box_h-2 );
                }

            }

        }

    }

    
    
private boolean isFullLine(int line)    //是否一行已经满了
    {
        
forint j=0; j<s_box_w_sum; j++ )    //
        {
            
if( map[line][j] <= 0 )
            
{
                
return false;
            }

        }

        
return true;
    }

    
    
private void  setNullLine( int line )    //设置地图上的这一行 空
    {
        
forint j=0; j<s_box_w_sum; j++ )    //
        {
            map[line][j] 
= 0;
        }
    
    }

    
private void setGoDownMap( int line )    //设置地图line以上的每行都向下移动一行
    {
        
forint i=line; i>0; i-- )            //
        {
            
forint j=0; j<s_box_w_sum; j++ )    //
            {
                map[i][j] 
= map[i-1][j];     //向下移动一行
            }

        }

    }

    
    
private boolean isCanMove()
    
{
        
forint i=0; i<4; i++ )        //
        {
            
forint j=0; j<4; j++ )    //
            {
                
if( ( box[box_state] & matrix[i][j] ) == matrix[i][j] )    //是格子
                {
                    
if( s_box_x+< 0 )                //左边界检测
                    {
                        System.out.println( 
"left s_box_x="+s_box_x+" matrix["+i+"]["+j+"]="+matrix[i][j]);
                        
return false;
                    }

                    
if( s_box_x+> s_box_w_sum-1 )    //右边界检测
                    {
                        System.out.println( 
"right s_box_x="+s_box_x+" matrix["+i+"]["+j+"]="+matrix[i][j]);
                        
return false;
                    }

                    
if( s_box_y+> s_box_h_sum-1 )    //下边界检测
                    {
                        System.out.println( 
"down s_box_y="+s_box_y+" matrix["+i+"]["+j+"]="+matrix[i][j]);
                        
return false;
                    }

                    
//地图格子检测
                    if( map[s_box_y+i][s_box_x+j] > 0 )
                        
return false;
                }

            }

        }

        
return true;
    }

    
private short isKeyDown = 0;    //0没有按下,1按下,2抬起
//    public boolean keyDown(Event evt, int key)
    public void keyPressed( int key )
    
{
        key 
= getKeyCode( key );
        
switch( key )
        
{
            
case UP:                //顺时针旋转
                isKeyDown = 0;        //0没有按下
                box_state ++;
                box_state 
%= 4;
                
if!isCanMove() )
                
{
                    box_state 
--;
                    
if( box_state<0 )
                        box_state 
= 3;
                }

            
break;
            
case DOWN:                //向下移动
                if( isKeyDown == 2 )
                    isKeyDown 
= 1;
                
if( isKeyDown == 1 )
                
{
                    s_box_y 
++
                    
if!isCanMove() )
                        s_box_y 
--;
                }

            
break;
            
case LEFT:                //向左移动BOX
                isKeyDown = 0;        //0没有按下
                s_box_x --;
                
if!isCanMove() )
                    s_box_x 
++;    
            
break;
            
case RIGHT:                //向右移动BOX
                isKeyDown = 0;        //0没有按下
                s_box_x ++;
                
if!isCanMove() )
                    s_box_x 
--;
            
break;
            
case 53:                //数字5键
                if( isGameOver )    //游戏结束
                    initGame();        //重新游戏
            break;
            
case 42:
                
if( isGameOver )    //游戏结束
//                    System.exit(0);    //退出游戏
                    Tetris.s_midlet.destroyApp(true);
            
break;
            
case 48:
                setBox();            
//新的BOX
            break;
            
case 49:                //是否显示网格
                isShowReseau = !isShowReseau;
            
break;
        }

        repaint();                    
//重新绘制屏幕
//        return true;
    }

    
public void keyRepeated( int key )
    
{
        keyPressed( key );
    }

    
public void setNextBox()
    
{
        s_next_box 
= (short)rand.nextInt( box_sum.length );
        System.arraycopy( box_sum[s_next_box], 
0, next_box, 0, next_box.length );
        s_next_box
++;
    }


    
public int getKeyCode( int key )
    
{
        System.out.println( 
"key="+key );
        
switch( key )
        
{
            
case 1004:     // up
            case 119:     // w
            case 87:     // W
            case 50:     // 2
            return UP;

            
case 1005:     // down
            case 115:     // s
            case 83:     // S
            case 56:     // 8
            return DOWN;

            
case 1006:     // left
            case 97:     // a
            case 65:     // A
            case 52:     // 4
            return LEFT;

            
case 1007:     // right
            case 100:     // d
            case 68:     // D
            case 54:     // 6
            return RIGHT;
            
default:
            
return key;
        }

    }

//    public boolean keyUp(Event evt, int key) 
    public void keyReleased( int key ) 
    
{
        isKeyDown 
= 2;    //释放按键
//        return true;
    }

//    public boolean mouseDown(Event evt, int x, int y)
//    {
//        try
//        {
////
            System.out.println( "x="+x+" y="+y );
//        }catch( Exception e){e.printStackTrace();}
////
        this.repaint();
//        return true;
//    }
//    public boolean mouseMove(Event evt, int x, int y)
//    {
//        try
//        {
//            //System.out.println( "x="+x+" y="+y );
//        }catch( Exception e){e.printStackTrace();}
//        return true;
//    }
//    public static void main(String[] args) 
//    {
//        JFrame frame = new JFrame("俄罗斯方块 北京|雷神 QQ:38929568");
//        final cGame dc = new cGame();
//        frame.getContentPane().add(dc, BorderLayout.CENTER);
//
////
        JButton button = new JButton("刷新");
////
        button.addActionListener(new ActionListener() 
////
        {
////
            public void actionPerformed(ActionEvent e) 
////
            {
////
                dc.repaint();
////
            }
////
        });
////
        frame.getContentPane().add(button, BorderLayout.SOUTH);
//        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//        frame.setSize(dc.s_width+10, dc.s_height+30);
//        frame.setVisible(true);
//    }
}

 

你可能感兴趣的:(原创文章)