2. 俄罗斯游戏方块的旋转和运动控制
该游戏方块的运动由键盘的方向键控制,左键表示让方块向左移动,右键表示让方块向右移动,向下的方向键让方块加速下落,上键及中间键实现游戏方块的旋转变化。
3. 俄罗斯游戏方块的颜色选择
该游戏中的4种方块都是固定的颜色,每种方块一种颜色。 4. 俄罗斯方块的自动消行功能和计分功能
游戏中当方块填满一行时便可以消行,每消去一行分数增加1,同时消去的行数越多,分数增长的越快。
5. 游戏的自动升级功能
该游戏设置的游戏等级是自动增加的。当玩家达到一定的分数时,游戏等级上升,当然游戏难度也会上升
3.2游戏代码分析
3.2.1 绘制方块
游戏操作区域就是由10*18个16*16的网格组成,这些网格实际上就是通过Graphics方法画出一条条线组成的,当游戏开始后就会在界面上显示出来,实现代码如下:
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++ ) { }
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 );
// -
g.drawLine( i*s_box_h, 0, i*s_box_h, s_height );
// |
//绘制网格
} 3.2.2 绘制方块
游戏总共设计了7种造型,每种造型又可以通过旋转而变化出4种形状,利用随机函数在一个预览窗体中提前展示形状供用户参考,然后将展示的形状复制到游戏窗体中进行摆放,在游戏窗体中用户就可以使用键盘的方向键来控制方块的运动。游戏方块本质上为16个小砖块组成的正方形,一共有七种,如“田”字形、“L”字形等。每种方块一共有四种旋转变化,程序中是用16进制表示的这些方块,这些用16进制表示的方块可以换算成用一个4×4的二维数组来存储每种方块的一种状态。在有色砖块出现的位置,值为1,而只有背景颜色,无需绘制的位置,值为0。如下图所示为“长条”形的四种状态在数组中的存储方式。
图5方块模型
这4种状态的16进制 → { 0x2222, 0x00F0, 0x2222, 0x00F0 } 游戏实例图如图6所示:
图6 方块实例
//所有方块图形
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 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 );
}
}
//BOX是否下降
goDown();
}
3.2.3 随机出现方块
游戏总共设计了7种不同的方块,每次游戏是方块的出现都是随机的,这种方法是
通过random函数实现的, public void setNextBox() { s_next_box = (short)rand.nextInt( box_sum.length );//random()方法 System.arraycopy( box_sum[s_next_box], 0, next_box, 0, next_box.length ); s_next_box++; }
具体实现方法是用random函数产生下一个将要出现的方块,把该方块放到预览窗口,然后程序中通过自定义方法setBox() 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 ); }
}
把随机产生的方块放入到游戏操作区域
具体调用方法如下: 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 ); //恢复游戏
}
3.2.3 最高分的设定
图7 最高分界面
当游戏结束时在结束界面可以点击“最高分”按钮,该游戏记分系统的功能指定在RecordCanvas类内。采用的是手机专用的一种简化的数据库Record Managerment System(RMS),记分系统记录每次玩的最高的分数并在最高分界面显示出来。当玩家的得分超过上次的最高分时即打破记录,系统显示祝贺信息,没有通过最高分时也会出现激励信息提示。图7所示为界面图,以下是所需主要代码:
public void paihang(){
String s =Integer.toString(success); frm2=new Form("最高分");
cmd3=new Command("返回",Command.BACK,1); cmd4=new Command("退出游戏",Command.SCREEN,1); frm2.addCommand(cmd3); frm2.addCommand(cmd4); addRecordToRMS(s); try {
int number=Tetris.rs.getNumRecords();
frm2.setCommandListener(this);
String a = null; String b=null;
s2=displayRecordFromRMS(number); if(number==1){ }