您的位置:首页 > 编程语言 > Java开发

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

2007-12-04 16:41 961 查看
作者:雷神

QQ:38929568

QQ群:28048051JAVA游戏编程(满) 28047782(满) 50761834(新开)

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

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

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

游戏图片:





工程文件如附件所示,地址如下:方块2
代码如下:

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[][]    //所有方块图形
...{
...{ 0x0660, 0x0660, 0x0660, 0x0660 },
...{ 0x2222, 0x00F0, 0x2222, 0x00F0 },
...{ 0x0264, 0x0630, 0x0264, 0x0630 },
...{ 0x0462, 0x0360, 0x0462, 0x0360 },
...{ 0x02E0, 0x4460, 0x0740, 0x0622 },
...{ 0x0E20, 0x2260, 0x0470, 0x0644 },
...{ 0x0464, 0x00E4, 0x04C4, 0x04E0 }
};

private static short next_box[] = new short[]...{ 0x0660, 0x0660, 0x0660, 0x0660 };
private static short box[]          = new short[]...{ 0x0660, 0x0660, 0x0660, 0x0660 };
private static short map[][];        //地图
private static short box_state  = 0;//当前BOX的状态//旋转方向
private static short matrix[][] =    //定义矩阵用来计算出box_sum的方块
...{
...{ 0x1000, 0x0100, 0x0010, 0x0001 },
...{ 0x2000, 0x0200, 0x0020, 0x0002 },
...{ 0x4000, 0x0400, 0x0040, 0x0004 },
...{ (short)0x8000, 0x0800, 0x0080, 0x0008 }
};

public 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 ( 0, 0, s_width, s_height);            //初始化 画布区域
gb.fillRect( 0, 0, s_width, s_height);            //初始化 画布填充
paintReseau( gb );                                //绘制网格
paintNextBox( gb );                                //绘制下一BOX
paintMap( gb );                                    //绘制地图上不可以动BOX
paintBox( gb, s_box_x, s_box_y );                //绘制当前可控制BOX
//            gb.setColor( new Color( 0xFF3333 ) );            //分割线颜色
gb.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+10, 10, g.TOP|g.LEFT );//祯数
gb.drawString( "等级:"+level,         s_line_between_x+10, 30, g.TOP|g.LEFT );//等级
gb.drawString( "得分:"+success,         s_line_between_x+10, 50, 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( 0, 0, s_line_between_x, s_height );
if( isShowReseau )
...{
g.setColor( gameColor[0] );
for( int i=0; i<s_line_between_x/s_box_w; i++ )    // |
...{
g.drawLine( i*s_box_h, 0, i*s_box_h, s_height );
}
for( int j=0; j<s_height/s_box_h; j++ )            // -
...{
g.drawLine( 0, j*s_box_w, s_line_between_x, j*s_box_w );
}
}
}
private void paintBox( Graphics g, int off_x, int off_y )
...{
for( int i=0; i<4; i++ )        //行
...{
for( int 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( 0, 0, 4*s_box_w, 4*s_box_h );

if( isShowReseau )                //显示格式
...{
g.setColor( gameColor[0] );
for( int i=0; i<5; i++ )    // |
...{
g.drawLine( i*s_box_h, 0, i*s_box_h, 4*s_box_h );
}
for( int j=0; j<5; j++ )    // -
...{
g.drawLine( 0, j*s_box_w, 4*s_box_w, j*s_box_w );
}
}
for( int i=0; i<4; i++ )        //行
...{
for( int 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()
...{
for( int i=0; i<4; i++ )        //行
...{
for( int 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;
for( int 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 )
...{
for( int i=0; i<s_box_h_sum; i++ )        //行
...{
for( int 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)    //是否一行已经满了
...{
for( int j=0; j<s_box_w_sum; j++ )    //列
...{
if( map[line][j] <= 0 )
...{
return false;
}
}
return true;
}

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

private boolean isCanMove()
...{
for( int i=0; i<4; i++ )        //行
...{
for( int j=0; j<4; j++ )    //列
...{
if( ( box[box_state] & matrix[i][j] ) == matrix[i][j] )    //是格子
...{
if( s_box_x+j < 0 )                //左边界检测
...{
System.out.println( "left s_box_x="+s_box_x+" matrix["+i+"]["+j+"]="+matrix[i][j]);
return false;
}
if( s_box_x+j > 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+i > 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);
//    }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: