俄罗斯方块java

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import https://www.360docs.net/doc/d07094580.html,ng.*;

class systemStatus
{
public systemStatus(int tmpX,int tmpY)
{
origin=new Point(tmpX,tmpY);
iSystemStatus=0;
}

public void drawSystemStatus(Graphics g)
{
g.setColor(Color.black);
String strSystemStatus;
switch(iSystemStatus)
{
case 0:
strSystemStatus="初始化完成...\"S\"键开始."; //在状态前面空出一个汉字的宽度.
break;
case 1:
strSystemStatus="游戏进行中...\"D\"键暂停,\"S\"键重新开始."; //在状态前面空出一个汉字的宽度.
break;
case 2:
strSystemStatus="游戏暂停中...\"D\"键恢复,\"S\"键重新开始."; //在状态前面空出一个汉字的宽度.
break;
case 3:
strSystemStatus="GAMEOVER...\"S\"键重新开始."; //在状态前面空出一个汉字的宽度.
break;
default:
strSystemStatus="系统发生严重异常...请立即退出!!!"; //在状态前面空出一个汉字的宽度.
break;
}
g.drawString(strSystemStatus,origin.x,origin.y);
}

public int getSystemStatus()
{
return iSystemStatus;
}

public void setSystemStatus(int iTmp)
{
iSystemStatus=iTmp;
}

private Point origin; //得分字符串的最左边字符左下角的坐标.
private final int ROWINTERVAL=15; //2行字符串之间的行间距.
private int iSystemStatus; //存放系统的当前状态;0-刚启动或gameOver后重启动的状态(容器中没有已固定的格子,分数为0,只接受S键的输入事件开始游戏),1-玩家游戏时的状态,2-系统暂停时的状态(计时器停止,只接收P键或S键的输入事件),3-GAMEOVER(计时器停止,只接收S键的输入事件).
}

class copyright
{
public copyright(int tmpX,int tmpY)
{
origin=new Point(tmpX,tmpY);
}

public void drawCopyright(Graphics g)
{
String strCopyright;
strCopyright="作者:";
g.drawString(strCopyright,origin.x,origin.y);
strCopyright=" ⊙杨⊙";
g.drawString(strCopyright,origin.x,origin.y+ROWINTERVAL);
strCopyright="QQ:";
g.drawString(strCopyright,origin.x,origin.y+2*ROWINTERVAL);
strCopyright=" 5419208";
g.drawString(strCopyright,origin.x,origin.y+3*ROWINTERVAL);
strCopyright="版本号:";
g.drawString(strCopyright,origin.x,origin.y+4*ROWINTERVAL);
strCopyright=" 1.0r";
g.drawString(strCopyright,origin.x,origin.y+5*ROWINTERVAL);
}
private final int ROWINTERVAL=15; //2行字符串之间的行间距.
private Point origin;
}

class score
{
public score(int tmpX,int tmpY)
{
origin=

new Point(tmpX,tmpY);
iScore=0;
}

public void restart()
{
iScore=0;
}

public void drawScore(Graphics g)
{
g.setColor(Color.black);
String strScore;
strScore="得分:";
g.drawString(strScore,origin.x,origin.y);
strScore=" "+iScore; //在分数前面空出一个汉字的宽度.
g.drawString(strScore,origin.x,origin.y+ROWINTERVAL);
}

public void addScore(int tmpLineNum) //tmpLineNum是消除的行数.根据消除的行数来计分.
{
switch(tmpLineNum)
{
case 1:
iScore+=100;
break;
case 2:
iScore+=300;
break;
case 3:
iScore+=600;
break;
case 4:
iScore+=1000;
break;
}
}

private final int ROWINTERVAL=15; //2行字符串之间的行间距.
private Point origin; //得分字符串的最左边字符左下角的坐标.
private int iScore;
}

class preview
{
public preview(int tmpX,int tmpY,int tmpHeightGrid,int tmpWidthGrid,int tmpHeight,int tmpWidth)
{
origin=new Point(tmpX,tmpY+tmpHeight);
iHeightGrid=tmpHeightGrid;
iWidthGrid=tmpWidthGrid;
iHeight=tmpHeight;
iWidth=tmpWidth;
aryGrids=new grid[iHeightGrid][iWidthGrid];
calGridToPosition();
}


public void calGridToPosition() //计算出预览框中各个格子左上角的坐标.
{
//对容器中的4*4个格子进行初始化.
for(int i=0;i{
for(int j=0;j{
aryGrids[i][j]=new grid(iHeight/iHeightGrid,iWidth/iWidthGrid,origin.x+j*(iWidth/iWidthGrid),origin.y-i*(iHeight/iHeightGrid),1,1,0);
}
}
}

public void drawGrids(Graphics g,int[][] tmpRowColNos) //tmpRowColNos存放有方块在预览框中显示的行号和列号.
{

//在预览框中显示方块.

for(int i=0;iif((tmpRowColNos[i][0]!=-1)&&(tmpRowColNos[i][1]!=-1))
aryGrids[tmpRowColNos[i][0]][tmpRowColNos[i][1]].drawDiamonds(g); //tmpRowColNos[i][0]是行号,tmpRowColNos[i][1]是列号.

}

public void drawGridFrame(Graphics g)
{
//画各个格子之间的分割线
g.setColor(Color.lightGray);
//画格子的竖分隔线
for(int i=1;i{
g.drawLine(origin.x+i*(iWidth/iWidthGrid),origin.y,origin.x+i*(iWidth/iWidthGrid),origin.y-iHeight);
}
//画格子的横分隔线
for(int i=1;i{
g.drawLine(origin.x,origin.y-i*(iHeight/iHeightGrid),origin.x+iWidth,origin.y-i*(iHeight/iHeightGrid));
}


//画容器的整个外框
g.setColor(Color.black);
//System.out.println("origin in drawGridFrame(): " +origin.x+","+origin.y);
g.drawRect(origin.x,origin.y-iHeight,iWidth,iHeight);
}


private Point origin; //原点是整个预览容器左下角的坐标.
private int iHeightGrid;
private int iWidthGrid;
private int iHeight;
private int iWidth;
private grid[][] aryGrids; //第1,2维的下标是用于确定是平面上的哪个格子.第1维对应行号,取值范围0~iHeightGrid-1;第2维对应列号,取值范围是0~iWidthgrid-1

}

//方块下落固定后,就变成了格子
class diamonds
{
public diamonds(int tmpRowNo,int tmpColNo)
{
initDiamondsTable();
referPoint[0]=tmpRowNo;
referPoint[1]=tmpColNo;
orgReferPoint[0]=tmpRowNo;
orgReferPoint[1]=tmpColNo;
createNew();
iPreStatusNo=iStatusNo; //初始化,应付第1个方块的第1次旋转时遇到冲突时的情况.其实问题也不大因为刚开始时容器中没有已固定的方块会发生冲突.

}

public void restart()
{
referPoint[0]=orgReferPoint[0];
referPoint[1]=orgReferPoint[1];

}

//经过判断方块无法进行旋转,调用此函数恢复方块本次旋转之前的状态.
public void unCircumrotate()
{
referPoint[0]=preReferPoint[0];
referPoint[1]=preReferPoint[1];
iStatusNo=iPreStatusNo;
setAryDiamonds();
}

public void circumrotate()
{
preReferPoint[0]=referPoint[0];
preReferPoint[1]=referPoint[1];
iPreStatusNo=iStatusNo;
iStatusNo=diamondsTable[iSortNo][iStatusNo];
setAryDiamonds();
}

//重新生成一个新的方块,实质是随机设定方块的类型和方块的状态,并将其位置复位.
public void createNew()
{
//获得在方块种类数范围之内的随机数.
iSortNo=(int)(Math.random()*100)%SORTNUM;
//每个方块的状态数是不同的.
iStatusNo=(int)(Math.random()*100)%diamondsTable[iSortNo].length;

setAryDiamonds();

}

//返回方块所占的行号,用于消行.
public int[] getRowNos()
{
int[] rtnRowNos=new int[iHeightGrid];
//注意返回数组中行号的排列顺序是从大到小的.顺序不能打乱,否则消行时会产生错误.
//对所有的方块通用.
for(int i=0;i{
rtnRowNos[i]=referPoint[0]+(iHeightGrid-i-1);
}

return rtnRowNos;
}


//返回方块中所有有效部分在容器中显示的行号和列号.
public int[][] diamondsPosition()
{
int[][] rtnRowC

olNos=new int[iHeightGrid*iWidthGrid][2];
//转换,把方块内有效部分的坐标都转换成容器内的坐标,然后返回.
for(int i=0;ifor(int j=0;jif(aryDiamonds[i][j]==1)
{
rtnRowColNos[i*iWidthGrid+j][0]=referPoint[0]+i;
rtnRowColNos[i*iWidthGrid+j][1]=referPoint[1]+j;
}
else //把方块中不用显示的部分的行号和列号设为-1,便于区分.
{
rtnRowColNos[i*iWidthGrid+j][0]=-1;
rtnRowColNos[i*iWidthGrid+j][1]=-1;
}

return(rtnRowColNos);
}

//返回判定向左移动时判定接触的方块部分的行号和列号,数组中元素存放的顺序无要求.
public int[][] leftTouchGrids()
{
int[][] rtnRowColNos=new int[iHeightGrid][2]; //第1维是接触面所占格子的数量,第2维的第1,2个元素是格子相对于容器的坐标.
//这里默认方块的接触面是连续的没有空缺.
for(int i=0;i{
for(int j=0;j{
if(aryDiamonds[i][j]==1)
{
rtnRowColNos[i][0]=referPoint[0]+i;
rtnRowColNos[i][1]=referPoint[1]+j;
break;
}
}
}


/*只适合方块5的代码.
if(iSortNo==5)
{
rtnRowColNos[0][0]=referPoint[0];
rtnRowColNos[0][1]=referPoint[1];
rtnRowColNos[1][0]=referPoint[0];
rtnRowColNos[1][1]=referPoint[1]+1;
}*/

return rtnRowColNos;
}

//返回判定向右移动时判定接触的方块部分的坐标
public int[][] rightTouchGrids()
{
int[][] rtnRowColNos=new int[iHeightGrid][2];
for(int i=0;i{
for(int j=iWidthGrid-1;j>=0;j--)
{
if(aryDiamonds[i][j]==1)
{
rtnRowColNos[i][0]=referPoint[0]+i;
rtnRowColNos[i][1]=referPoint[1]+j;
break;
}
}
}

return rtnRowColNos;
}

//返回判定向下移动时判定接触的方块部分的坐标
public int[][] downTouchGrids()
{
int[][] rtnRowColNos=new int[iWidthGrid][2];
for(int i=0;i{
for(int j=0;j{
if(aryDiamonds[j][i]==1)
{
rtnRowColNos[i][0]=referPoint[0]+j;
rtnRowColNos[i][1]=referPoint[1]+i;
break;
}
}
}

return rtnRowColNos;
}

public void initDiamondsTable()
{
diamondsTable=new int[SORTNUM][];
diamondsTable[0]=new int[2];
diamondsTable[1]=new int[4];
diamondsTable[2]=new int[4];
diamondsTable[3]=new int[2];
diamondsTable[4]=new int[2];
diamondsTable[5]=new int[1];
diamondsTable[6]=new int[4];

//存放各种方块旋转后的下一个状态号.
for(int i=0;i

gth;i++)
for(int j=0;jif(j==diamondsTable[i].length-1)
diamondsTable[i][j]=0;
else
diamondsTable[i][j]=j+1;

}

public void setAryDiamonds()
{
switch(iSortNo)
{
case 0:
switch(iStatusNo)
{
case 0:
iHeightGrid=4;
iWidthGrid=1;
aryDiamonds=new int[iHeightGrid][iWidthGrid];
for(int i=0;ifor(int j=0;jaryDiamonds[i][j]=1; //对于方块0的状态0,4*1矩阵中的每一个元素都是显示部分.
break;
case 1:
iHeightGrid=1;
iWidthGrid=4;
aryDiamonds=new int[iHeightGrid][iWidthGrid];
for(int i=0;ifor(int j=0;jaryDiamonds[i][j]=1;
break;
}
break;
case 1:
switch(iStatusNo)
{
case 0:
iHeightGrid=3;
iWidthGrid=2;
aryDiamonds=new int[iHeightGrid][iWidthGrid];
for(int i=0;ifor(int j=0;jif(((i==1)&&(j==1))||((i==2)&&(j==1)))
aryDiamonds[i][j]=0;
else
aryDiamonds[i][j]=1;
break;
case 1:
iHeightGrid=2;
iWidthGrid=3;
aryDiamonds=new int[iHeightGrid][iWidthGrid];
for(int i=0;ifor(int j=0;jif(((i==0)&&(j==1))||((i==0)&&(j==2)))
aryDiamonds[i][j]=0;
else
aryDiamonds[i][j]=1;
break;
case 2:
iHeightGrid=3;
iWidthGrid=2;
aryDiamonds=new int[iHeightGrid][iWidthGrid];
for(int i=0;ifor(int j=0;jif(((i==0)&&(j==0))||((i==1)&&(j==0)))
aryDiamonds[i][j]=0;
else
aryDiamonds[i][j]=1;
break;
case 3:
iHeightGrid=2;
iWidthGrid=3;
aryDiamonds=new int[iHeightGrid][iWidthGrid];
for(int i=0;ifor(int j=0;jif(((i==1)&&(j==0))||((i==1)&&(j==1)))
aryDiamonds[i][j]=0;
else
aryDiamonds[i][j]=1;
break;
}
break;
case 2:
switch(iStatusNo)
{
case 0:
iHeightGrid=3;
iWidthGrid=2;
aryDiamonds=new int[iHeightGrid][iWidthGrid];
for(int i=0;ifor(int j=0;jif(((i==1)&&(j==0))||((i==2)&&(j==0)))
aryDiamonds[i][j]=0;
else
aryDiamonds[i][j]=1;
break;
case 1:
iHeightGrid=2;
iWidthGrid=3;
aryDiamonds=new int[iHeightGrid][iWidthGrid];
for(int i=0;ifor(int j=0;jif(((i==1)&&(j==1))||((i==1)&&(j==2)))
aryDiamonds[i][j]=0;
else
aryDiamonds[i][j]=1;
break;
case 2:
iHeightGrid=3;
iWidthGrid=2;
aryDiamonds=new int[iHeightGrid][iWidthGrid];
for(int i=0;i


for(int j=0;jif(((i==0)&&(j==1))||((i==1)&&(j==1)))
aryDiamonds[i][j]=0;
else
aryDiamonds[i][j]=1;
break;
case 3:
iHeightGrid=2;
iWidthGrid=3;
aryDiamonds=new int[iHeightGrid][iWidthGrid];
for(int i=0;ifor(int j=0;jif(((i==0)&&(j==0))||((i==0)&&(j==1)))
aryDiamonds[i][j]=0;
else
aryDiamonds[i][j]=1;
break;
}
break;
case 3:
switch(iStatusNo)
{
case 0:
iHeightGrid=3;
iWidthGrid=2;
aryDiamonds=new int[iHeightGrid][iWidthGrid];
for(int i=0;ifor(int j=0;jif(((i==0)&&(j==0))||((i==2)&&(j==1)))
aryDiamonds[i][j]=0;
else
aryDiamonds[i][j]=1;
break;
case 1:
iHeightGrid=2;
iWidthGrid=3;
aryDiamonds=new int[iHeightGrid][iWidthGrid];
for(int i=0;ifor(int j=0;jif(((i==0)&&(j==2))||((i==1)&&(j==0)))
aryDiamonds[i][j]=0;
else
aryDiamonds[i][j]=1;
break;
}
break;
case 4:
switch(iStatusNo)
{
case 0:
iHeightGrid=3;
iWidthGrid=2;
aryDiamonds=new int[iHeightGrid][iWidthGrid];
for(int i=0;ifor(int j=0;jif(((i==0)&&(j==1))||((i==2)&&(j==0)))
aryDiamonds[i][j]=0;
else
aryDiamonds[i][j]=1;
break;
case 1:
iHeightGrid=2;
iWidthGrid=3;
aryDiamonds=new int[iHeightGrid][iWidthGrid];
for(int i=0;ifor(int j=0;jif(((i==0)&&(j==0))||((i==1)&&(j==2)))
aryDiamonds[i][j]=0;
else
aryDiamonds[i][j]=1;
break;
}
break;
case 5:
iHeightGrid=2;
iWidthGrid=2;
aryDiamonds=new int[iHeightGrid][iWidthGrid];
for(int i=0;ifor(int j=0;jaryDiamonds[i][j]=1;
break;
case 6:
switch(iStatusNo)
{
case 0:
iHeightGrid=2;
iWidthGrid=3;
aryDiamonds=new int[iHeightGrid][iWidthGrid];
for(int i=0;ifor(int j=0;jif(((i==1)&&(j==0))||((i==1)&&(j==2)))
aryDiamonds[i][j]=0;
else
aryDiamonds[i][j]=1;
break;
case 1:
iHeightGrid=3;
iWidthGrid=2;
aryDiamonds=new int[iHeightGrid][iWidthGrid];
for(int i=0;ifor(int j=0;jif(((i==0)&&(j==1))||((i==2)&&(j==1)))
aryDiamonds[i][j]=0;
else
aryDiamonds[i][j]=1;
break;
case 2:
iHeightGrid=2;
iWidthGrid=3;
aryDiamonds=new int[iHeightGrid][iWidthGrid];
for(int i=0;ifor(int j=0;jif(((i==0)&&(j==0))||((i==0)&&(j

==2)))
aryDiamonds[i][j]=0;
else
aryDiamonds[i][j]=1;
break;
case 3:
iHeightGrid=3;
iWidthGrid=2;
aryDiamonds=new int[iHeightGrid][iWidthGrid];
for(int i=0;ifor(int j=0;jif(((i==0)&&(j==0))||((i==2)&&(j==0)))
aryDiamonds[i][j]=0;
else
aryDiamonds[i][j]=1;
break;
}
break;
}
}

public int getWidthGrid()
{
return iWidthGrid;
}

public int getStatusNo()
{
return iStatusNo;
}

public void setStatusNo(int tmpStatusNo)
{
iStatusNo=tmpStatusNo;
}

public int getSortNo()
{
return iSortNo;
}

public void setSortNo(int tmpSortNo)
{
iSortNo=tmpSortNo;
}

public int[] getReferPoint()
{
return(referPoint);
}

public void setReferPoint(int tmpRowNo,int tmpColNo)
{
referPoint[0]=tmpRowNo;
referPoint[1]=tmpColNo;
}

private final int SORTNUM=7; //目前有7种方块,各方块在各状态定义的图案参考开发文档.
private int[] orgReferPoint=new int[2]; //存放调用构造函数时,得到的参照点的行号和列号参数.
private int[] preReferPoint=new int[2]; //用于解决超出右边界进行调整后,又发生方块和已固定方块发生冲突的情况.
private int[] referPoint=new int[2]; //1维数组记录左下角元素在容器中所处的位置,存放行号和列号,不是存放象素.
private int iHeightGrid; //方块矩阵高占的格子数.
private int iWidthGrid; //方块矩阵宽占的格子数.
private int[][] aryDiamonds; //2维矩阵,用于绘制方块.第1维对应行号,取值范围是0~iHeightGrid-1,从下到上编号从小到大;第2维对应列号,取值范围是0~iWidthGrid-1,从左到右编号从小到大.0表示不是方块的显示部分,1表示是方块的显示部分.
private int iSortNo; //存放当前方块的种类编号,取值范围0~6,编号对应的图案查看开发文档
private int iStatusNo; //存放当前方块的状态编号,状态编号随方块的旋转而改变.
private int[][] diamondsTable; //此2维数组中第1维是代表方块的种类,第2维是代表方块的状态,数组中存放的是方块下一个状态的编号
private int iPreStatusNo; //存放方块在旋转前的上一个状态.旋转方块不会改变方块的种类号.

}

class grid
{
public grid(int tmpHeight,int tmpWidth,int tmpX,int tmpY,int tmpDiffX,int tmpDiffY,int tmpInUse)
{
iHeight=tmpHeight;
iWidth=tmpWidth;
XYPosition=new Point(tmpX,tmpY-tmpHeight);
diffX=tmpDiffX;
diffY=tmpDiffY;
inUse=tmpInUse;
}

public void drawGrid(Graphics g)
{
if(inUse==1)
{
g.setColor(Color.black);
g.fillRect(XYPosition.x+diffX,XYPosition.y+diffY,iWidth-2*diffX,iHeight-2*diffY);
}
}

public void drawDiamonds(Graphics g)
{
g.setColor(Color.black);
g.fillRect(XYPosition.x+diffX,XYPosition.y+diffY,iWidth-2*diffX,iHeight-2*diffY);
}

public int getInUse() //返回当前的格子是否被使用
{
return inUse;
}

public void setInUse(int tmpMode) //参数tmpMode为0-未使用,为1-已使用
{
inUse=tmpMode;
}

private int iHeight; //格子在Y轴方向上的高度,以象素为单位
private int iWidth; //格子在X轴方向上的宽度,以象素为单位
private Point XYPosition; //格子左上角的实际坐标
private int diffX; //格子中图黑部分在X轴方向单边缩进象素
private int diffY; //格子中图黑部分在Y轴方向单边缩进象素
private int inUse; //存放整型0或1.0表示格子已被占用,1表示格子未被占用
//还要加个有关颜色的参数,可以由用户设置格子颜色

}

class board
{
public board(int tmpX,int tmpY,int tmpHeightGrid,int tmpWidthGrid,int tmpHeight,int tmpWidth,int tmpBufferHeightGrid,int tmpBufferHeight) //tmpX,tmpY是容器右上角的X,Y坐标.tmpHeightGrid,tmpWidthGrid是高占几格和宽占几格,以格子为单位.tmpHeight,tmpWidth是高和宽,以象素为单位.tmpBufferHeightGrid和tmpBufferHeight是缓冲区,让方块作进入容器的准备工作.
{
//System.out.println("in board() tmpX="+tmpX+" tmpY="+tmpY+" tmpHeight="+tmpHeight);
origin=new Point(tmpX,tmpY+tmpHeight);
//System.out.println("origin in board(): " +origin.x+","+origin.y);
iHeightGrid=tmpHeightGrid;
iWidthGrid=tmpWidthGrid;
iHeight=tmpHeight;
iWidth=tmpWidth;
iBufferHeightGrid=tmpBufferHeightGrid;
iBufferHeight=tmpBufferHeight;
aryGrids=new grid[iHeightGrid+iBufferHeightGrid][iWidthGrid]; //包括缓冲行,便于进行GAMEOVER判断.
calGridToPosition();
objDiamonds=new diamonds(iHeightGrid,iWidthGrid/2-1);
objSystemStatus=new systemStatus(10,10+300+20);
}

public void restart() //把所有格子的状态设为未使用.
{
for(int i=0;ifor(int j=0;jaryGrids[i][j].setInUse(0);

}

public int gameOverChk() //检查是否已经GAMEOVER;返回值=0,没有GAMEOVER;=1,已经GAMEOVER.
{
int rtnGameOver=0;
for(int i=0;ii

f(aryGrids[iHeightGrid][i].getInUse()==1)
{
rtnGameOver=1;
break;
}
return rtnGameOver;
}

public int conflictChk() //方块旋转后的冲突检测.返回值=0,无冲突;=1,有冲突.
{
int isConflict=0; //=0,无冲突;=1,有冲突
int[][] rtnRowColNos;
rtnRowColNos=objDiamonds.diamondsPosition();

for(int i=0;iif(((rtnRowColNos[i][0]!=-1)&&(rtnRowColNos[i][1]!=-1))&&aryGrids[rtnRowColNos[i][0]][rtnRowColNos[i][1]].getInUse()==1)
{
isConflict=1;
break;
}
return isConflict;
}



public void adjust() //方块在旋转后,某部分超出了容器的边界就要进行调整操作
{
int[] rtnReferPoint;
int tmpWidthGrid;
tmpWidthGrid=objDiamonds.getWidthGrid();
rtnReferPoint=objDiamonds.getReferPoint();
if((rtnReferPoint[1]+tmpWidthGrid)>iWidthGrid)
objDiamonds.setReferPoint(rtnReferPoint[0],iWidthGrid-tmpWidthGrid);
}

public int removeRows() //进行消行操作.返回值为消去的行数.
{
int[] rtnRowNos; //存放方块所占行的行号.
int[] fullRowNos; //存放已满行的行号.
int fullCount=0; //存放已满行的行数.
rtnRowNos=objDiamonds.getRowNos();

//System.out.print("In removeRows: ");
//for(int i=0;i//{
// System.out.print(rtnRowNos[i]+",");
//}
//System.out.println();

fullRowNos=new int[rtnRowNos.length];
for(int i=0;ifullRowNos[i]=0;

//方块所在行中,如果有行已满,则取出此行的行号.
for(int i=0;i{
int rowNo;
int isFull; //0-当前行未满,1-当前行已满.
rowNo=rtnRowNos[i];
isFull=1;
for(int j=0;j{
//System.out.println("In removeRows: aryGrids["+rowNo+"]["+j+"].getInUse()="+aryGrids[rowNo][j].getInUse());
if(aryGrids[rowNo][j].getInUse()==0)
{
isFull=0;
break;
}
}
//System.out.println("In removeRows: isFull="+isFull);
if(isFull==1)


{
fullRowNos[fullCount]=rowNo;
fullCount++;
}
}
//System.out.println("In removeRows: fullCount="+fullCount);

for(int i=0;i{
int rowNo;
rowNo=fullRowNos[i];
for(int j=rowNo;j{
for(int k=0;k{
int tmpMode;
tmpMode=aryGrids[j+1][k].getInUse();
aryGrids[j][k].setInUse(tmpMode);
}
}
}
return fullCount;
}

public void calGridToPosition() //计算出各个格子左上角的坐标.
{
//对容器中的20*10个格子进行初始化.
for(int i=0;i<(iHeightGrid+iBufferHeightGrid);i++)
{
for(int j=0;j{
aryGrids[i][j]=new grid((iHeight+iBufferHeight)/(iHeightGrid+iBufferHeightGrid),iWidth/iWidthGrid,origin.x+j*(iWidth/iWidthGrid),origin.y-i*((iHeight+iBufferHeight)/(iHeightGrid+iBufferHeightGrid)),2,2,0);
}
}
}

public void drawGrids(Graphics g)
{
//显示已经固定的格子.
for(int i=0;ifor(int j=0;jaryGrids[i][j].drawGrid(g);

//显示方块.
int[][] rtnRowColNos;
rtnRowColNos=objDiamonds.diamondsPosition();

//System.out.println("in drawGrids: rtnRowColNos.length=" +rtnRowColNos.length);
//for(int i=0;i//{
// System.out.println("rtnRowColNos["+i+"][0]="+rtnRowColNos[i][0]+","+"rtnRowColNos["+i+"][1]="+rtnRowColNos[i][1]);
//}

for(int i=0;iif((rtnRowColNos[i][0]!=-1)&&(rtnRowColNos[i][1]!=-1))
if(rtnRowColNos[i][0]aryGrids[rtnRowColNos[i][0]][rtnRowColNos[i][1]].drawDiamonds(g); //rtnRowColNos[i][0]是行号,rtnRowColNos[i][1]是列号.

}

public void drawGridFrame(Graphics g)
{
//画各个格子之间的分割线
g.setColor(Color.lightGray);
//画格子的竖分隔线
for(int i=1;i{
g.drawLine(origin.x+i*(iWidth/iWidthGrid),origin.y,ori

gin.x+i*(iWidth/iWidthGrid),origin.y-(iHeight));
}
//画格子的横分隔线
for(int i=1;i{
g.drawLine(origin.x,origin.y-i*((iHeight+iBufferHeight)/(iHeightGrid+iBufferHeightGrid)),origin.x+iWidth,origin.y-i*((iHeight+iBufferHeight)/(iHeightGrid+iBufferHeightGrid)));
}

//画容器的整个外框
g.setColor(Color.black);
//System.out.println("origin in drawGridFrame(): " +origin.x+","+origin.y);
g.drawRect(origin.x,origin.y-iHeight,iWidth,iHeight);
}


public int getHeightGrid()
{
return iHeightGrid;
}

public int getWidthGrid()
{
return iWidthGrid;
}

public int getBufferHeightGrid()
{
return iBufferHeightGrid;
}

public int getAryGrids(int i,int j) //i是行号对应y轴;j是列号对应x轴.
{
return aryGrids[i][j].getInUse();
}

public void setAryGrids(int i,int j,int tmpMode) //设置矩阵中行号为i,列号为j的格子的状态(使用或未使用);参数tmpMode=0表示把当前格设为未使用,=1表示把当前格设为使用.
{
aryGrids[i][j].setInUse(tmpMode);
}
private Point origin; //原点是整个方块容器左下角的坐标.
private int iHeightGrid; //存放高有几格
private int iWidthGrid; //存放宽有几格
private int iHeight; //存放容器的高度,以象素为单位
private int iWidth; //存放容器的宽度,以象素为单位
private int iBufferHeightGrid; //iBufferHeightGrid和iBufferHeight是缓冲区,让方块作进入容器的准备工作.
private int iBufferHeight;
private grid[][] aryGrids; //第1,2维是用于确定是平面上的哪个格子.第1维对应行号,取值范围0~iHeightGrid+iBufferHeightGrid-1;第2维对应列号,取值范围是0~iWidthGrid-1.

public diamonds objDiamonds;
public systemStatus objSystemStatus;

}


class eluosiPanel extends JPanel implements KeyListener,ActionListener
{
public eluosiPanel()
{
b=new board(10,10,20,10,300,150,10,150);
objPreview=new preview(10+150+10,10,5,5,50,50);
objPreDiamonds=new diamonds(0,0);
addKeyListener(this);
objScore=new score(10+150+10,10+50+20);
objCopyright=new copyright(10+150+10,10+50+20+15+20+50);
t = new Timer(delay,this);

}


//覆盖eluosiPanel类的isFocusTraversable方法,使面板能够获得焦点.
public boolean isFocusTraversable()
{
return(true);
}

//通过方向键左右下,来控制方块5的移动.
public void keyPressed(KeyEvent evt)
{
int keyCode=evt.getKeyCode();
int[] rtnRowColNo; //存放方块中的参照格子的行

号和列号.
rtnRowColNo=b.objDiamonds.getReferPoint();
//移动前要先判断是否会超出容器的边框.
if(keyCode==KeyEvent.VK_LEFT)
{
if(b.objSystemStatus.getSystemStatus()!=0&&b.objSystemStatus.getSystemStatus()!=2&&b.objSystemStatus.getSystemStatus()!=3)
{
if(rtnRowColNo[1]-1>=0)
{
t.stop();
//方块5向左移动时,如果遇到已使用的格子,就取消向左移动的情况.
int isTouch=0; //为0表示未接触,为1表示已接触.
int[][] aryLeftTouchGrids; //存放方块左侧接触面上格子的行号和列号.
aryLeftTouchGrids=b.objDiamonds.leftTouchGrids();
for(int i=0;i{
if(b.getAryGrids(aryLeftTouchGrids[i][0],aryLeftTouchGrids[i][1]-1)==1)
{
isTouch=1;
break;
}
}
if(isTouch==0)
b.objDiamonds.setReferPoint(rtnRowColNo[0],rtnRowColNo[1]-1);
t.start();
}
}
}
else
if(keyCode==KeyEvent.VK_RIGHT)
{
if(b.objSystemStatus.getSystemStatus()!=0&&b.objSystemStatus.getSystemStatus()!=2&&b.objSystemStatus.getSystemStatus()!=3)
{
if(rtnRowColNo[1]+1<(b.getWidthGrid()-(b.objDiamonds.getWidthGrid()-1)))
{
t.stop();
//方块5向右移动时,如果遇到已使用的格子,就取消向右移动的情况.
int isTouch=0; //为0表示未接触,为1表示已接触.
int[][] aryRightTouchGrids;
aryRightTouchGrids=b.objDiamonds.rightTouchGrids();
for(int i=0;i{
if(b.getAryGrids(aryRightTouchGrids[i][0],aryRightTouchGrids[i][1]+1)==1)
{
isTouch=1;
break;
}
}
if(isTouch==0)
b.objDiamonds.setReferPoint(rtnRowColNo[0],rtnRowColNo[1]+1);
t.start();
}
}
}
else
//按了"向下键"的事件处理比较特殊,如果位置合适,方块5将变为固定的格子.
if(keyCode==KeyEvent.VK_DOWN)
{
if(b.objSystemStatus.getSystemStatus()!=0&&b.objSystemStatus.getSystemStatus()!=2&&b.objSystemStatus.getSystemStatus()!=3)
{
//t.stop(); //按向下键时方块不自动下落.
//方块5已经沉底,要被固定的情况
if(rtnRowColNo[0]-1<0)
{
int[][] rtnPosition;
rtnPosition=b.objDiamonds.diamondsPosition();
//把容器中与方块的显示部分位置相对应的格子设为已使用.
for(int i=0;iif((rtnPosition[i][0]!=-1)&&(rtnPosition[i][1]!=-1))
b.setAryGrids(rtnPosition[i][0],rtnPosition[i][1],1);

//对已满的行要进行消行处理.
int tmpLineNum;
tmpLineNum=b.removeRows();
objScore.addScore(tmpLineNum); //消行后要累加分数

.

if(b.gameOverChk()==1)
{
//System.out.println("GAME OVER!!");
t.stop();
b.objSystemStatus.setSystemStatus(3);

}
else
{
//重新生成一个新的方块,实质是设定方块的类型,并将其位置复位.
b.objDiamonds.setSortNo(objPreDiamonds.getSortNo());
b.objDiamonds.setStatusNo(objPreDiamonds.getStatusNo());
b.objDiamonds.setAryDiamonds();
objPreDiamonds.createNew();
b.objDiamonds.setReferPoint(b.getHeightGrid(),b.getWidthGrid()/2-1);
//t.start();
}
}
else
{
//方块5向下移动遇到已使用的格子而固定的情况
int isTouch=0; //为0表示未接触,为1表示已接触.
int[][] aryDownTouchGrids;
aryDownTouchGrids=b.objDiamonds.downTouchGrids();
for(int i=0;i{
if(b.getAryGrids(aryDownTouchGrids[i][0]-1,aryDownTouchGrids[i][1])==1)
{
isTouch=1;
break;
}
}

if(isTouch==1) //向下移动已发生了接触.
{
int[][] rtnPosition;
rtnPosition=b.objDiamonds.diamondsPosition();
//把容器中与方块5位置相对应的格子设为已使用.
for(int i=0;iif((rtnPosition[i][0]!=-1)&&(rtnPosition[i][1]!=-1))
b.setAryGrids(rtnPosition[i][0],rtnPosition[i][1],1);

//对已满的行要进行消行处理.
int tmpLineNum;
tmpLineNum=b.removeRows();
objScore.addScore(tmpLineNum);

if(b.gameOverChk()==1)
{
t.stop();
System.out.println("GAME OVER!!");
b.objSystemStatus.setSystemStatus(3);


}
else
{
//重新生成一个新的方块,实质是设定方块的类型,并将其位置复位.
b.objDiamonds.setSortNo(objPreDiamonds.getSortNo());
b.objDiamonds.setStatusNo(objPreDiamonds.getStatusNo());
b.objDiamonds.setAryDiamonds();
objPreDiamonds.createNew();
b.objDiamonds.setReferPoint(b.getHeightGrid(),b.getWidthGrid()/2-1);
//t.start();
}
}
else
{
b.objDiamonds.setReferPoint(rtnRowColNo[0]-1,rtnRowColNo[1]);
//t.start();
}
}
}
}
else
/*
if(keyCode==KeyEvent.VK_UP)
{
if(b.objSystemStatus.getSystemStatus()!=0&&b.objSystemStatus.getSystemStatus()!=2&&b.objSystemStatus.getSystemStatus()!=3)
{
if(rtnRowColNo[0]+1<(b.getHeightGrid()+b.getBufferHeightGrid()-1))
b.objDiamonds.setReferPoint(rtnRowColNo[0]+1,rtnRowColNo[1]);
}
}
else*/
if(keyCode==KeyEvent.VK_SPACE)
{
if(b.objSystemStatus.getSystemStatus()!=0&&b.objSystemStatus.getSystemStatus()!=2&&b.objSystemStatus.getSystemStatus()!=3)
{
t.stop(); //翻转时方块不自动下落
b.objDiamonds.circumrotate();
b.adjust();
if(b.conflictChk()==1) //进行冲突检查,如果旋转后方块与容器中已固定的方块发生位置冲突,必须取消这次旋转.
b.objDiamonds.unCircumrotate();
t.start();
}
}
else
if(keyCode==KeyEvent.VK_S) //按S键,根据iSystemStatus判断是开始或重新开始
{
if(b.objSystemStatus.getSystemStatus()==0) //开始
{
t.start();
//System.out.println("start...");
b.objSystemStatus.setSystemStatus(1); //转到玩家游戏状态.
}
else
if(b.objSystemStatus.getSystemStatus()==1||b.objSystemStatus.getSystemStatus()==2||b.objSystemStatus.getSystemStatus()==3) //重新开始
{
t.stop();
b.restart();
//System.out.println("restart...");
objScore.restart();
b.objDiamonds.restart();
b.objSystemStatus.setSystemStatus(1);
t.start();
}
}
else
if(keyCode==KeyEvent.VK_D) //按P键,如果当前系统处于玩家游戏状态,就暂停(iSysStatus=2).如果处于暂停状态,就恢复到玩家游戏状态.
{

if(b.objSystemStatus.getSystemStatus()!=0&&b.objSystemStatus.getSystemStatus()!=3)
{
if(b.objSystemStatus.getSystemStatus()==1)
{
t.stop();
b.objSystemStatus.setSystemStatus(2);
}
else
if(b.objSystemStatus.getSystemStatus()==2)
{
t.start();
b.objSystemStatus.setSystemStatus(1);
}
}
}
repaint();
}

public void keyReleased(KeyEvent evt)
{}

public void keyTyped(KeyEvent evt)
{}

//计时器事件,与按下键的事件处理一致.
public void actionPerformed(ActionEvent evt)
{
int[] rtnRowColNo; //存放方块中的参照格子的行号和列号.
rtnRowColNo=b.objDiamonds.getReferPoint();
//方块5已经沉底,要被固定的情况
if(rtnRowColNo[0]-1<0)
{
int[][] rtnPosition;
rtnPosition=b.objDiamonds.diamondsPosition();
//把容器中与方块的显示部分位置相对应的格子设为已使用.
for(int i=0;iif((rtnPosition[i][0]!=-1)&&(rtnPosition[i][1]!=-1))
b.setAryGrids(rtnPosition[i][0],rtnPosition[i][1],1);

//对已满的行要进行消行处理.
int tmpLineNum;
tmpLineNum=b.removeRows();
objScore.addScore(tmpLineNum); //消行后要累加分数.

if(b.gameOverChk()==1)
System.out.println("GAME OVER!!");

if(b.gameOverChk()==1)
{
t.stop();
//System.out.println("GAME OVER!!");
b.objSystemStatus.setSystemStatus(3);
}
else
{
//重新生成一个新的方块,实质是设定方块的类型,并将其位置复位.
b.objDiamonds.setSortNo(objPreDiamonds.getSortNo());
b.objDiamonds.setStatusNo(objPreDiamonds.getStatusNo());
b.objDiamonds.setAryDiamonds();
objPreDiamonds.createNew();
b.objDiamonds.setReferPoint(b.getHeightGrid(),b.getWidthGrid()/2-

1);
}
}
else
{
//方块5向下移动遇到已使用的格子而固定的情况
int isTouch=0; //为0表示未接触,为1表示已接触.
int[][] aryDownTouchGrids;
aryDownTouchGrids=b.objDiamonds.downTouchGrids();
for(int i=0;i{
if(b.getAryGrids(aryDownTouchGrids[i][0]-1,aryDownTouchGrids[i][1])==1)
{
isTouch=1;
break;
}
}

if(isTouch==1) //向下移动已发生了接触.
{
int[][] rtnPosition;
rtnPosition=b.objDiamonds.diamondsPosition();
//把容器中与方块5位置相对应的格子设为已使用.
for(int i=0;iif((rtnPosition[i][0]!=-1)&&(rtnPosition[i][1]!=-1))
b.setAryGrids(rtnPosition[i][0],rtnPosition[i][1],1);

//对已满的行要进行消行处理.
int tmpLineNum;
tmpLineNum=b.removeRows();
objScore.addScore(tmpLineNum);

if(b.gameOverChk()==1)
System.out.println("GAME OVER!!");

if(b.gameOverChk()==1)
{
t.stop();
System.out.println("GAME OVER!!");
b.objSystemStatus.setSystemStatus(3);
}
else
{
//重新生成一个新的方块,实质是设定方块的类型,并将其位置复位.
b.objDiamonds.setSortNo(objPreDiamonds.getSortNo());
b.objDiamonds.setStatusNo(objPreDiamonds.getStatusNo());
b.objDiamonds.setAryDiamonds();
objPreDiamonds.createNew();
b.objDiamonds.setReferPoint(b.getHeightGrid(),b.getWidthGrid()/2-1);
}
}
else
{
b.objDiamonds.setReferPoint(rtnRowColNo[0]-1,rtnRowColNo[1]);
}
}
repaint();
}

public void paintComponent(Graphics g)
{
super.paintComponent(g);
b.drawGridFrame(g);
b.drawGrids(g);
objPreview.drawGridFrame(g);
objPreview.drawGrids(g,objPreDiamonds.diamondsPosition());
objScore.drawScore(g);
objCopyright.drawCopyright(g);
b.objSystemStatus.drawSystemStatus(g);
}

private Timer t;
private int delay=200;
private board b;
private diamonds objPreDiamonds;
private preview objPreview;
private score objScore;
private copyright objCopyright;
}

class eluosiFrame extends JFrame
{
public eluosiFrame()
{
setT

itle("经典俄罗斯方块");
setSize(240,400);
addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
Container contentPane=getContentPane();
contentPane.add(new eluosiPanel());
}
}

public class eluosi
{
public static void main(String[] args)
{
JFrame myEluosi=new eluosiFrame();
myEluosi.show();
}
}

相关主题
相关文档
最新文档