引言:这几天我由于生病,影响了写代码的进度,十分遗憾!好了,我会接住上一篇的继续写下去,希望和我一样不顾一切喜欢、热爱软件和游戏开发的朋友们继续支持我,你们的回帖就是对我最大的支持,要说明的是:如果发现文章或代码中的错误之处请指出,欢迎所有阅读这篇文章的人,我们一起进步,一起提高!
步入正题:这篇讲的是方块生成与坐标控制模块TetrisBlock类。
在TetrisBlock类中定义了7种方块的不同形状和对应的颜色,都有一个对应的ID,分别为1—7,且对于每种方块来说,其颜色均是固定,方块由16个4*4的小方格组成,故在逻辑上可以使用4*4的二维数组表示,又由于每个方块都有4种旋转变化,故可以用4*4*4的三维数组表示一个方块的所有状态。
例如,“T”形方块可由如下的数组来表示:
- protected int blockpattern1[][][]={//blockpattern1:“T”字及四种旋转形状
- {{0,0,0,0},{1,1,1,0},{0,1,0,0},{0,0,0,0}},
- {{0,1,0,0},{1,1,0,0},{0,1,0,0},{0,0,0,0}},
- {{0,1,0,0},{1,1,1,0},{0,0,0,0},{0,0,0,0}},
- {{0,1,0,0},{0,1,1,0},{0,1,0,0},{0,0,0,0}}
- };
protected int blockpattern1[][][]={//blockpattern1:“T”字及四种旋转形状
{{0,0,0,0},{1,1,1,0},{0,1,0,0},{0,0,0,0}},
{{0,1,0,0},{1,1,0,0},{0,1,0,0},{0,0,0,0}},
{{0,1,0,0},{1,1,1,0},{0,0,0,0},{0,0,0,0}},
{{0,1,0,0},{0,1,1,0},{0,1,0,0},{0,0,0,0}}
};
小tips:这一章代码是俄罗斯方块生成与控制算法,应该是比较重要的,所以我的注释写得尽可能的多,希望所有的人都能看得明白!
1.方块生成与坐标控制模块(TetrisBlock类)
程序源代码如下:
- /*
- * To change this template, choose Tools | Templates
- * and open the template in the editor.
- */
- package game.teris;
- import java.util.Random;
- import javax.microedition.lcdui.Graphics;
- /**
- *
- * @author dongdong
- */
- public class TetrisBlock {
- //各种方块,1-7为活动方块的颜色,8为砖墙的颜色
- public static final int[] BRICK_COLORS = {
- 0x00FF0000,
- 0x0000FF00,
- 0x00FFFF00,
- 0x000000FF,
- 0x00FF00FF,
- 0x0000FFFF,
- 0x00C0DCC0,
- 0x00808080
- };
- /**
- * blockpattern的编码规则:blockpattern表示一种方块的形状
- * 每种方块的颜色是固定的
- * 对于一个方块,用一个三维数组表示,第一维用rot表示(旋转值),第二维用
- * x表示(行),第三维用y表示(列)
- * 第一维最重要即rot,表示旋转值
- */
- protected int blockpattern1[][][]={//blockpattern1:“T”字及四种旋转形状
- {{0,0,0,0},{1,1,1,0},{0,1,0,0},{0,0,0,0}},
- {{0,1,0,0},{1,1,0,0},{0,1,0,0},{0,0,0,0}},
- {{0,1,0,0},{1,1,1,0},{0,0,0,0},{0,0,0,0}},
- {{0,1,0,0},{0,1,1,0},{0,1,0,0},{0,0,0,0}}
- };
- protected int blockpattern2[][][]={//blockpattern2:“田”字及四种旋转形状
- {{1,1,0,0},{1,1,0,0},{0,0,0,0},{0,0,0,0}},
- {{1,1,0,0},{1,1,0,0},{0,0,0,0},{0,0,0,0}},
- {{1,1,0,0},{1,1,0,0},{0,0,0,0},{0,0,0,0}},
- {{1,1,0,0},{1,1,0,0},{0,0,0,0},{0,0,0,0}}
- };
- protected int blockpattern3[][][]={//blockpattern3:“L”字及四种旋转形状
- {{1,1,0,0},{0,1,0,0},{0,1,0,0},{0,0,0,0}},
- {{0,0,1,0},{1,1,1,0},{0,0,0,0},{0,0,0,0}},
- {{1,0,0,0},{1,0,0,0},{1,1,0,0},{0,0,0,0}},
- {{1,1,1,0},{1,0,0,0},{0,0,0,0},{0,0,0,0}}
- };
- protected int blockpattern4[][][]={//blockpattern4:反“L”字及四种旋转形状
- {{1,1,0,0},{1,0,0,0},{1,0,0,0},{0,0,0,0}},
- {{1,1,1,0},{0,0,1,0},{0,0,0,0},{0,0,0,0}},
- {{0,1,0,0},{0,1,0,0},{1,1,0,0},{0,0,0,0}},
- {{1,0,0,0},{1,1,1,0},{0,0,0,0},{0,0,0,0}}
- };
- protected int blockpattern5[][][]={//blockpattern5:反“Z”字及四种旋转形状
- {{1,0,0,0},{1,1,0,0},{0,1,0,0},{0,0,0,0}},
- {{0,1,1,0},{1,1,0,0},{0,0,0,0},{0,0,0,0}},
- {{1,0,0,0},{1,1,0,0},{0,1,0,0},{0,0,0,0}},
- {{0,1,1,0},{1,1,0,0},{0,0,0,0},{0,0,0,0}}
- };
- protected int blockpattern6[][][]={//blockpattern6:“Z”字及四种旋转形状
- {{0,1,0,0},{1,1,0,0},{1,0,0,0},{0,0,0,0}},
- {{1,1,0,0},{0,1,1,0},{0,0,0,0},{0,0,0,0}},
- {{0,1,0,0},{1,1,0,0},{1,0,0,0},{0,0,0,0}},
- {{1,1,0,0},{0,1,1,0},{0,0,0,0},{0,0,0,0}}
- };
- protected int blockpattern7[][][]={//blockpattern7:“1”字及四种旋转形状
- {{1,1,1,1},{0,0,0,0},{0,0,0,0},{0,0,0,0}},
- {{1,0,0,0},{1,0,0,0},{1,0,0,0},{1,0,0,0}},
- {{1,1,1,1},{0,0,0,0},{0,0,0,0},{0,0,0,0}},
- {{1,0,0,0},{1,0,0,0},{1,0,0,0},{1,0,0,0}}
- };
- /*当前下坠方块形状,为以上定义的7种方块之一*/
- private int blockpattern[][][];
- /*下一个方块形状,显示在游戏容器的右边*/
- private int blockNextpattern[][][];
- //blockpattern左上角x坐标
- //x=i表示左上角距离游戏容器左上角x轴上i个小砖块单位
- private int x;
- //blockpattern左上角y坐标
- //y=i表示左上角距离游戏容器左上角y轴上i个小砖块单位
- private int y;
- //x的旧值
- private int oldx;
- //y的旧值
- private int oldy;
- //旋转值,0-3
- private int rot;
- //旋转旧值
- private int oldrot;
- /*当前下坠方块*/
- private int pattern;
- /*下一个下坠方块*/
- private int next;
- private final int UNDEFINED=99;
- private TetrisMap map;
- protected Random rand;
- public int gamearea_x;
- public int gamearea_y;
- public int brick_Width;
- /*构造函数,保存map,初始化blockimage、rand、next*/
- public TetrisBlock(TetrisMap map,boolean isMaster){
- this.map=map;
- if(isMaster){
- rand= new Random();
- //随机生成的pattern和next在1-7之间,8为墙
- next=Math.abs(rand.nextInt())%7+1;
- pattern=next;
- next=Math.abs(rand.nextInt())%7+1;
- }
- else{
- //如果本TetrisBlock代表的是附屏
- //则当前下坠方块和下一个下坠方块由远端设备决定
- pattern=UNDEFINED;
- next=UNDEFINED;
- }
- setParameter();
- }
- /**
- * 用来设置附屏对应的TetrisBlock对象
- * @param pattern_2
- * @param next_2
- */
- public void setPN(int pattern_2,int next_2){
- pattern=pattern_2;
- next=next_2;
- }
- public void setParameter(){
- gamearea_x=map.gamearea_x;
- gamearea_y=map.gamearea_y;
- brick_Width=map.brick_Width;
- }
- /*初始化*/
- protected void init(){
- }
- /**
- * 读取当前下坠方块
- * @param nowblock int[][][] 七种方块常量之一
- */
- private void readPattern(int[][][] nowblock){
- blockpattern=new int[4][4][4];
- for(int i=0;i<4;i++){
- for(int j=0;j<4;j++){
- for(int k=0;k<4;k++){
- blockpattern[i][j][k]=nowblock[i][j][k];
- }
- }
- }
- }
- /**
- * 读取下一个下坠方块
- * 只需要保存4种旋转变化中的第一种即可,所以rot=0
- * @param nowblock int[][][] 7种方块之一
- */
- private void readNextPattern(int[][][] nowblock){
- blockNextpattern=new int[0][4][4];
- for(int i=0;i<4;i++){
- for(int j=0;j<4;j++){
- blockNextpattern[0][i][j]=nowblock[0][i][j];
- }
- }
- }
- /*旋转方块*/
- protected void rotBlock(){
- }
- /**
- * 绘制方块,包括清除下坠方块的旧图像,调用绘制下坠方块新图像
- * 本地方法
- * @param g Graphics
- */
- public void paint(Graphics g){
- //如果三维都没有变化,则无需重画
- if( (oldrot!=rot)||(oldx!=x)||(oldy!=y) ){
- //清除旧图形
- g.setColor(TetrisCanvas.BACKGROUND);
- for(int i=0;i<4;i++){
- for(int j=0;j<4;j++){
- if(blockpattern[oldrot][i][j] == 1){
- g.fillRect(gamearea_x +
- (oldx + j) * brick_Width,
- gamearea_y +
- (oldy + i) * brick_Width,
- brick_Width, brick_Width);
- }
- }
- }
- drawBlock(g);
- oldrot=rot;
- oldx=x;
- oldy=y;
- }
- }
- /**
- * 绘制下坠方块
- * @param g Graphics
- * 本地、远端均可使用
- */
- public void drawBlock(Graphics g){
- for(int i=0;i<4;i++){
- for(int j=0;j<4;j++){
- if(blockpattern[rot][i][j] == 1){
- drawBrick(gamearea_x +
- (x + j) * brick_Width,
- gamearea_y +
- (y + i) * brick_Width,g,pattern - 1);
- }
- }
- }
- }
- /**
- * 远端用户使用、清除当前下坠的方块
- */
- public void eraseBlock(Graphics g){
- }
- /**
- * 判断下坠方块是不是和map种已有的砖块重叠,为了处理gameover的情况,只需画出部分
- * 下坠方块的情况
- * @return true:有重叠;false:无重叠
- */
- public boolean isCrashAtBegin(){
- //行
- for(int i=3;i>=0;i--){
- //列
- for(int j=0;j<4;j++){
- int mx=x + j;
- int my=y + i;
- if(my<0){
- my=0;
- }
- if(blockpattern[rot][i][j] == 1 && map.get(mx, my) != 8 &&
- map.get(mx, my) != 0){
- return true;
- }
- }
- }
- return false;
- }
- /**
- * 画小砖块
- * @param px x坐标
- * @param py y坐标
- * @param g Graphics
- * @param colorIndex颜色索引值
- */
- public void drawBrick(int px, int py, Graphics g, int colorIndex){
- //画白边
- g.setColor(255, 255, 255);
- g.fillRect(px, py, 1, brick_Width);
- g.fillRect(px, py, brick_Width, 1);
- //画中心
- int color=BRICK_COLORS[colorIndex];
- g.setColor(color);
- g.fillRect(px+1, py+1, brick_Width-1,
- brick_Width-1);
- //画灰边
- g.setColor(0x00c0c0c0);
- g.fillRect(px + brick_Width - 1, py + 1, 1,
- brick_Width - 1);
- g.fillRect(px + 1, py + brick_Width - 1,
- brick_Width - 2, 1);
- }
- /**
- * 在游戏容器的右边绘出下一个下坠物形状
- * @param g Graphics
- */
- public void drawNextBlock(Graphics g){
- }
- /**
- * 判断下坠方块是否能下移
- */
- public boolean checkDown(){
- boolean check = true;
- /*分别扫描下坠物的4行,从最下面的那行开始*/
- for(int i = 0;i < 4;i++){
- int row=3;
- while(row >= 0){
- if(blockpattern[rot][row][i] == 1){
- if(map.get(x + i, y + row + 1) !=0){
- check = false;
- }
- row = -1; //终止循环
- }
- else{
- row--;
- }
- }
- }
- return check;
- }
- /*下坠物下移1行*/
- public void down(){
- }
- /*判断是否能旋转*/
- public boolean checkRot(){
- boolean check = true;
- int tmpRot = rot + 1;
- if(tmpRot == 4){
- tmpRot = 0;
- }
- for(int i = 0; i < 4; i++){
- for(int j = 0; j < 4; j++){
- if(blockpattern[tmpRot][i][j] == 1){
- if(map.get(x + j, y + i) != 0){
- check = false;
- }
- }
- }
- }
- return check;
- }
- /*判断下坠物是否可以移动*/
- public boolean checkMove(int direct){
- boolean check = true;
- //分别扫描下坠物的4行
- for(int i = 0; i < 4; i++){
- if(direct == 1){ //左移
- int row = 0;
- while(row <= 3){
- if(blockpattern[rot][i][row] == 1){
- if(map.get(x + row - 1, y + i) != 0){
- check = false;
- }
- row = 4;//终止循环
- }
- else{
- row++;
- }
- }
- }
- else{ //右移
- int row = 3;
- while(row >= 0){
- if(blockpattern[rot][i][row] == 1){
- if(map.get(x + row +1, y + i) != 0){
- check = false;
- }
- row = -1; //终止循环
- }
- else{
- row--;
- }
- }
- }
- }
- return check;
- }
- /*左右移动*/
- public void move(int direct){
- }
- public int getY(){
- }
- /**
- * 根据下坠物的当前位置设置地图数据
- */
- public void fixBlock(){
- }
- public int getPattern(){
- }
- public int getNext(){
- }
- /**
- * 空中的方块落下后,则产生新的方块
- */
- public void generatePN(){
- pattern=next;
- next=Math.abs(rand.nextInt())%7+1;
- }
- }