`

J2ME实战:蓝牙联网俄罗斯方块(3)—方块生成与坐标控制模块( 未完待续。。。)

阅读更多

引言:这几天我由于生病,影响了写代码的进度,十分遗憾!好了,我会接住上一篇的继续写下去,希望和我一样不顾一切喜欢、热爱软件和游戏开发的朋友们继续支持我,你们的回帖就是对我最大的支持,要说明的是:如果发现文章或代码中的错误之处请指出,欢迎所有阅读这篇文章的人,我们一起进步,一起提高!

 

步入正题:这篇讲的是方块生成与坐标控制模块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}}   
    };

 

小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;
    }
}

 

 未完待续。。。

1
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics