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();
}
}
未完待續。。。