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

 

 未完待續。。。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章