J2ME實戰:藍牙聯網俄羅斯方塊(4)—數據傳輸序列化與遊戲地圖存儲模塊( 未完待續。。。)...

1.數據傳輸序列化模塊(Serialization接口)


在遊戲的過程中需要將地圖數據傳輸到遠端玩家的手機上,故需進行數據的序列化和反序列化,因此我們這裏定義了Serialization接口。

 

該接口的具體代碼如下:

 

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package game.teris;
import java.io.*;

/**
 *
 * @author dongdong
 */
public interface Serialization {
    public byte[] serialize() throws IOException;
    public void deserialize(byte[] data) throws IOException;

}
 

 

該接口中定義的serialize()方法和deserialize()方法會在遊戲地圖存儲模塊(TetrisMap)類中作具體的實現。定義Serialization接口的目的是爲了對序列化進行規範,使所有的進行序列化傳輸的類都遵守相同的規則,並不是說不實現Serialization接口就不可以進行傳輸了。



2.遊戲地圖存儲模塊(TetrisMap類)



TetrisMap類提供瞭如下的功能:


a.通過mapdata[][]和mapBlockExist[]兩個數組提供了對遊戲地圖在數組上的邏輯表示;

b.提供了對遊戲地圖中對應的方塊的消除和添加算法;

c.提供了對方塊的繪製方法paint(),供遊戲邏輯控制模塊TetrisCanvas類(tips:後續章節將講到)調用,把方法繪製到屏幕上。


具體代碼如下:


/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package game.teris;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Graphics;
import javax.microedition.media.MediaException;
import javax.microedition.media.Player;

/**
 *
 * @author dongdong
 */
public class TetrisMap {
    int gamearea_x;
    int gamearea_y;
    int brick_Width;
    private TetrisCanvas canvas;
    private int[][] mapdata;
    private boolean[] mapBlockExist;
    private boolean _isSlave;
    private boolean isMaster;
    private int score;
    private int deleteRowNum;
    private Player player;
    private Font SCOREFONT;
    public TetrisMap(TetrisCanvas canvas, boolean _isMater) {
        this.canvas=canvas;
        //定義遊戲地圖爲一個高16、寬12的數組,mapBlockExist代表每一行
        mapdata=new int[16][12];
        mapBlockExist=new boolean[16];
        setParameters(_isSlave);
    }
    public void setParameters(boolean _isMaster){
        isMaster=_isMaster;
        if(isMaster)
        {
            gamearea_x=canvas.GAMEAREA_X;
            gamearea_y=canvas.GAMEAREA_Y;
            brick_Width=canvas.BRICK_WIDTH;
        }else
        {
            gamearea_x=canvas.GAMEAREA_X_REMOTE;
            gamearea_y=canvas.GAMEAREA_Y_REMOTE;
            brick_Width=canvas.BRICK_WIDTH_REMOTE;
        }
    }
    public void init() {//初始化TetrisMap實例中mapdata和mapBlockExist數據
        //清除計分
        score=0;
        //先把全部元素清0
        for(int i=0; i<16; i++)
        {
            for(int j=0; j<12; j++)
            {
                mapdata[i][j]=0;
            }
            mapBlockExist[i]=false;
        }
        //設置兩堵牆
        for(int i=0; i<16; i++)
        {
            mapdata[i][0]=8;
            mapdata[i][11]=8;
        }
        //設置容器底
        for(int i=0;i<12;i++)
        {
            mapdata[15][i]=8;
        }
        mapBlockExist[15]=true;
        
    }

    public int get(int x, int y) {//地圖數據的提取
        int data =mapdata[y][x];
        return data;
       
    }
    public void  set(int x, int y, int val){
        if(x >= 0 && y >= 0)
        {
            mapdata[y][x]= val;
            mapBlockExist[y]=true;
        }
    }
    public void paint(Graphics g) {/*首先根據TetrisMap代表的是主屏還是附屏清處不同
     的區域然後繪製非運動磚塊*/
        //清屏
        if(isMaster)
        {
            TetrisCanvas.clear(g);
        }
        else
        {
            TetrisCanvas.clear_Remote(g);
        }
        for(int i=0; i<16; i++)
        {
            for(int j=0; j<12; j++)
            {
                if(mapdata[i][j] == 8)
                {
                    block.drawBrick(gamearea_x + j * brick_Width,
                            gamearea_y + i * brick_Width, g,7);
                }
            }
        }
        
    }
    public boolean check(Graphics g, int row){
        boolean deleteFlag=false;
        deleteRowNum=0;
        //最多可以連銷4行
        int tmpRowNo;
        if(row + 4>= 15)
        {
            tmpRowNo=15;
        }
        else{
            tmpRowNo=row+4;
        }
        
        for(int y=row; y<tmpRowNo; y++)
        {
            boolean flag = true;
            
            for(int x=1; x<11; x++)
            {
                if(mapdata[y][x]==0)
                {
                    //空白區
                    flag=false;
                }
            }
            //需要消行
            if(flag)
            {
                mapBlockExist[y] = false;
                for(int x=1; x<11; x++)
                {
                    mapdata[y][x] = 0;
                }//這一行的地圖數據全部置0
                
                deleteRow(g,y);
                
                deleteFlag=true;
                
                deleteRowNum ++;
                
                //加分
                score += 10;
                paintScore(g);
                //發聲
                try{
                    if(player != null)
                    {
                        player.start();
                    }
                }
                catch (MediaException me){ }
            }
        }// end for
        return deleteFlag;
    }

    public void deleteRow(Graphics g, int y) {//本地方法,用來將需要消去的行簡單置黑
      g.setColor(TetrisCanvas.BACKGROUND);
      g.fillRect(gamearea_x + brick_Width, gamearea_y + y*brick_Width, 
              10 * brick_Width, brick_Width);
    }
    
    public void repaintMap(Graphics g){/*對mapdata和mapBlockExist的值進行檢查,幾行方塊被消完
        上面的方塊依次下降幾行*/
        //從容器底開始
        for(int i =14; i>0;i--)
        {
            int tmp;
            
            //有磚塊的行才移動
            if(mapBlockExist[i]){
                //只有下一行爲空白行才進行移動
                if(!mapBlockExist[i+1]){
                    tmp= i+1;
                    
                    if(!mapBlockExist[i+2]){
                        tmp=i+2;
                        
                        if(!mapBlockExist[i+3]){
                             tmp=i+3;
                        }//end if(!mapBlockExist[i+3])
                    }//end if(!mapBlockExist[i+2])
                    deleteRow(g,i);
                    //行復制
                    for(int j=1; j<11; j++){
                        mapdata[tmp][j] = mapdata[i][j];
                        mapdata[i][j] = 0;
                    }
                    mapBlockExist[i]= false;
                    mapBlockExist[tmp]= true;
                    
                    drawBlock(g,tmp);
                }//end  if(!mapBlockExist[i+1])
            }//end  if(!mapBlockExist[i])
        }//end for
        
    }
    
    public void repaintMap_Remote(Graphics g){/*負責遠端屏幕繪製,非實時更新,僅本地有方塊
     落下及消去時才被調用*/
        for(int i=15; i>0; i--)
        {
            drawBlockAll(g,i);
        }
        paintScore(g);
    }

    public void drawBlock(Graphics g, int y) {//繪製主屏
       for(int x=1;x<11;x++)
       {
           if(mapdata[y][x]!=0)
           {
               block.drawBrick(gamearea_x + x*brick_Width, 
                       gamearea_y + y*brick_Width,
                       g, mapdata[y][x] -1);
           }
       }
    }

    public void drawBlockAll(Graphics g, int y) {//繪製附屏
        for(int x=1; x<11; x++)
        {
            if(mapdata[y][x] !=0)
            {
                block.drawBrick(gamearea_x + x*brick_Width, gamearea_y + y*brick_Width, 
                        g, mapdata[y][x] -1);
            }else
            {
                g.setColor(TetrisCanvas.BACKGROUND);
                g.fillRect(gamearea_x + x*brick_Width, gamearea_y + y*brick_Width, 
                        brick_Width, brick_Width);
            }
        }
    }

    private void paintScore(Graphics g) {//繪製分數
       
        if(0 == score)
        {
            return;
        }
        
        //清除記分牌
        g.setColor(TetrisCanvas.BACKGROUND);
        g.fillRect(gamearea_x + 12*brick_Width, gamearea_y + 6*brick_Width, 
                brick_Width * 7, brick_Width * 7);
        //計分
        g.setColor(0, 255, 0);
        g.setFont(SCOREFONT);
        g.drawString("" + score, 
                gamearea_x + 14*brick_Width,
                gamearea_y + 8*brick_Width,
                g.TOP | g.HCENTER);
    }
    
    public void caculateScore(){//計算分數
        score += deleteRowNum * 10;
    }
    
     public byte[] serialize() throws IOException{/*實現Serialization接口的
         serialize()方法*/
         
         ByteArrayOutputStream byteArrayOutStream = new
                 ByteArrayOutputStream();
         DataOutputStream dataOutputStream = new 
                 DataOutputStream(byteArrayOutStream);
         
         for( int i=0; i<16; i++)
         {
             for(int j=0; j<12; j++)
             {
                 dataOutputStream.writeInt(mapdata[i][j]);
             }
         }
         dataOutputStream.writeInt(deleteRowNum);
         
         return byteArrayOutStream.toByteArray();
         
     }
     
     public void deserialize(byte[] data) throws IOException{/*實現Serialization
      接口的deserialize()方法*/
         ByteArrayInputStream byteArrayInputStream = new 
                 ByteArrayInputStream(data);
         DataInputStream dataInputStream = new 
                 DataInputStream(byteArrayInputStream);
         for(int i=0; i<16; i++)
         {
             for(int j=0;j<12;j++)
             {
                 mapdata[i][j]= dataInputStream.readInt();
             }
         }
         deleteRowNum= dataInputStream.readInt();
         caculateScore();
         
     }

}

 

  未完待續。。。

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