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(); }}?
?未完待续。。。
1 楼 jiyanliang 2008-11-07 不知道bluetooth对svg的地图传输效果如何,特别当数据量大的时候。 2 楼 wuhua 2008-11-09 jiyanliang 写道不知道bluetooth对svg的地图传输效果如何,特别当数据量大的时候。