武汉理工大学论文
五 详细设计与实现
5.1 游戏开始菜单界面的设计
游戏开始菜单界面是游戏的重要组成部分,为了增强游戏界面的美化效果,同时又使界面简洁直观,该界面用一张图片作为背景,添加了三个按钮,这三个按钮分别是开始按钮,帮助按钮,退出按钮。该界面由类TTetris实现,该类继承Activity类,当监听到开始按钮被点击时,游戏会跳转到游戏开始的Activity,当监听到帮助按钮被点击时,就跳转到帮助Activity,监听到退出键被点击时,游戏退出,该类实现起来较为简单。
5.2 方块类的设计与实现
方块是游戏最基本的元素,俄罗斯方块所有的操作都是建立在对方块的操作上,方块可以用不同的颜色的方格图片来显示,方块的数据结构定义在类Store中。方块类定义了方块的数据结构,用一个三维数组来表示7种类型一共28种方块,每一个方块由一个4×4的二维数组表示。定义4×4的数组是因为7种方块的旋转变化恰好都在长、宽各为4个单元格内。当数组的元素为1时则显示一个小方格,为0是则不显示。
这28种状态的数据模型用三维数组store表示。
public static int[][][] store = new int[][][] {
{{ 0, 0, 1, 0 }, { 0, 0, 1, 0 }, { 0, 0, 1, 0 }, { 0, 0, 1, 0 } },//I {{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 1, 1, 1, 1 }, { 0, 0, 0, 0 } },//I {{ 0, 0, 1, 0 }, { 0, 0, 1, 0 }, { 0, 0, 1, 0 }, { 0, 0, 1, 0 } },//I {{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 1, 1, 1, 1 }, { 0, 0, 0, 0 } },//I {{ 0, 0, 0, 0 }, { 0, 1, 1, 0 }, { 0, 1, 1, 0 }, { 0, 0, 0, 0 } },//O {{ 0, 0, 0, 0 }, { 0, 1, 1, 0 }, { 0, 1, 1, 0 }, { 0, 0, 0, 0 } },//O {{ 0, 0, 0, 0 }, { 0, 1, 1, 0 }, { 0, 1, 1, 0 }, { 0, 0, 0, 0 } },//O {{ 0, 0, 0, 0 }, { 0, 1, 1, 0 }, { 0, 1, 1, 0 }, { 0, 0, 0, 0 } },//O {{ 0, 1, 0, 0 }, { 0, 1, 0, 0 }, { 0, 1, 1, 0 }, { 0, 0, 0, 0 } },//L {{ 0, 0, 0, 0 }, { 1, 1, 1, 0 }, { 1, 0, 0, 0 }, { 0, 0, 0, 0 } },//L {{ 0, 1, 1, 0 }, { 0, 0, 1, 0 }, { 0, 0, 1, 0 }, { 0, 0, 0, 0 } },//L {{ 0, 0, 0, 0 }, { 0, 0, 1, 0 }, { 1, 1, 1, 0 }, { 0, 0, 0, 0 } },//L
17
武汉理工大学论文
{{ 0, 0, 1, 0 }, { 0, 0, 1, 0 }, { 0, 1, 1, 0 }, { 0, 0, 0, 0 } },//J {{ 0, 0, 0, 0 }, { 1, 0, 0, 0 }, { 1, 1, 1, 0 }, { 0, 0, 0, 0 } },//J {{ 0, 1, 1, 0 }, { 0, 1, 0, 0 }, { 0, 1, 0, 0 }, { 0, 0, 0, 0 } },//J {{ 0, 0, 0, 0 }, { 1, 1, 1, 0 }, { 0, 0, 1, 0 }, { 0, 0, 0, 0 } },//J {{ 0, 0, 0, 0 }, { 0, 1, 0, 0 }, { 1, 1, 1, 0 }, { 0, 0, 0, 0 } },//T {{ 0, 1, 0, 0 }, { 0, 1, 1, 0 }, { 0, 1, 0, 0 }, { 0, 0, 0, 0 } },//T {{ 0, 0, 0, 0 }, { 1, 1, 1, 0 }, { 0, 1, 0, 0 }, { 0, 0, 0, 0 } },//T {{ 0, 0, 1, 0 }, { 0, 1, 1, 0 }, { 0, 0, 1, 0 }, { 0, 0, 0, 0 } },//T {{ 0, 0, 0, 0 }, { 0, 1, 1, 0 }, { 1, 1, 0, 0 }, { 0, 0, 0, 0 } },//S {{ 0, 1, 0, 0 }, { 0, 1, 1, 0 }, { 0, 0, 1, 0 }, { 0, 0, 0, 0 } },//S {{ 0, 0, 0, 0 }, { 0, 1, 1, 0 }, { 1, 1, 0, 0 }, { 0, 0, 0, 0 } },//S {{ 0, 1, 0, 0 }, { 0, 1, 1, 0 }, { 0, 0, 1, 0 }, { 0, 0, 0, 0 } },//S {{ 0, 0, 0, 0 }, { 1, 1, 0, 0 }, { 0, 1, 1, 0 }, { 0, 0, 0, 0 } },//Z {{ 0, 0, 1, 0 }, { 0, 1, 1, 0 }, { 0, 1, 0, 0 }, { 0, 0, 0, 0 } },//Z {{ 0, 0, 0, 0 }, { 1, 1, 0, 0 }, { 0, 1, 1, 0 }, { 0, 0, 0, 0 } },//Z {{ 0, 0, 1, 0 }, { 0, 1, 1, 0 }, { 0, 1, 0, 0 }, { 0, 0, 0, 0 } }//Z };
每种类型的方块都设计了四种结构,这样有利于实现方块的变形,在同种类型的方块里,方块每变一次形就变成了它下面的方块结构,第四种结构的方块变形就变成了第一种结构,实现方块的循环变形。
该类定义了一个主要的方法Sttore(int),该方法用来生成一个方块,并把生成的方块用两个一维数组记录下来,该方法通过传递进去的参数来控制生成方块的方式,以两种形式来生成方块,一种是随机生成28种方块的一种,该形式用来生成新的方块,另一种是生成一个指定形状的方块,该形式用于游戏区域的方块生成。
5.3 方块的装载
装载方块是使游戏进行下去必不可少的条件,游戏方块装载体现在两个方面,一个是游戏区域的方块装载,另一个是下一个方块区域。游戏开始后分别为游戏区域和下一个方块区域随机生成一个方块,此后游戏区域的方块都是由存储下一个方块的数组传递过来,不再随机生成方块。游戏区域的方块传入屏幕布局数组array,下一个方块区域的数组传入brray,然后用draw()函数画出方块,以达到方块在屏幕上显示的效果。
18
武汉理工大学论文
方块的装载首先要随机生成一个方块,关键代码如下所示。
public void Sttore(int chang) {
int k = 0; if(chang == -1) { } else { }
//标志方块显示的颜色,一共有七种颜色的方块color的值1到7 color = (int) (kind / 4 + 1); for(int i=0; i<4; i++) {
for(int j=0; j<4; j++) { }
if(store[kind][i][j] != 0) { //用ai,aj两个数组来记录方块的形状 }
ai[k] = i; aj[k] = j; k++;
kind = chang;
//随机产生0到1之间的double正数 kind = (int)(Math.random()*28);
} }
当传入该方法的值为-1时,就随机生成一个方块,否则生成指定类型的方块,指定类型由传入的参数决定。生成的方块行坐标用数组ai记录,列坐标用数组aj记录。
生成方块的方块有两个用途,一个装载在下一个方块区域,另一个装载在游戏区域。 装载下一个方块区域的方块。
public void putS(Store c) {
}
for(int i = 0; i < 4; i++) { }
brray[c.ai[i]][c.aj[i]] = c.color;
删除下一个方块区域的方块。
19
武汉理工大学论文
public void delS(Store c) {
}
for(int i = 0; i < 4; i++) { }
brray[c.ai[i]][c.aj[i]] = 0;
装载屏幕区域的方块。
public void putStore(Store a,int x,int y) {
}
for(int i = 0; i < 4; i++) { }
if(x+a.ai[i]>0) { }
array[x+a.ai[i]][y+a.aj[i]] = a.color;
删除下一个方块区域的方块。
public void delStore(Store a,int x,int y) {
}
for(int i = 0; i < 4; i++) { }
if(x+a.ai[i]>0) { }
array[x+a.ai[i]][y+a.aj[i]] = 0;
5.4 方块的控制设计
对方块的控制,实际就是对二维数组array的控制,该二维数组用来布置游戏区域方块的显示,方块的控制主要在两个类里实现,一个是StarSurfaceView,控制方块的移动、旋转在该类里实现;另一个是类showPage,用来判断方块的各种操作是否可行,如果可行则执行相应的操作,否则操作无效。
控制方块时,首先要判断该操作是否可以执行,判断方法主要有判断方块是否可以左右移动,判断方块是否碰壁,判断方块是否触顶。
判断方块是否可以左移。
public boolean leftM(Store a,int x,int y) {
for(int i = 0; i < 4; i++) {
20
武汉理工大学论文
}
}
if(x+a.ai[i]>0 && array[x+a.ai[i]][y+a.aj[i] - 1] != 0) { }
return false;
return true;
判断方块是否可以右移。
public boolean rightM(Store a,int x,int y) {
}
for(int i = 0; i < 4; i++) { } return true;
if(x+a.ai[i]>0 && array[x+a.ai[i]][y+a.aj[i] + 1] != 0) { }
return false;
判断方块下面是否碰壁。
public boolean fit(Store a,int x,int y) {
}
for(int i = 0; i < 4; i++) { } return true;
if(x+a.ai[i]>0 && array[x+a.ai[i] + 1][y+a.aj[i]] != 0) { }
return false;
判断方块是否触顶。
public boolean outM(Store a,int x,int y) {
}
for(int i = 0; i < 4; i++) { }
return false;
if(x+a.ai[i] < 1) { }
return true;
对方块的控制定义在方法run()内,用while()来实现循环操作。当游戏监听到键
21