JAVA俄罗斯方块程序 勉强能看懂,但是我写不出来,555
代码贴出如下:
package com.zzk.cn;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.lang.*;
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 = "aaa";
g.drawString(strCopyright, origin.x, origin.y + ROWINTERVAL);
strCopyright = "联系方式:";
g.drawString(strCopyright, origin.x, origin.y + 2 * ROWINTERVAL);
strCopyright = "暂无";
g.drawString(strCopyright, origin.x, origin.y + 3 * ROWINTERVAL);
strCopyright = "版本号:";
g.drawString(strCopyright, origin.x, origin.y + 4 * ROWINTERVAL);
strCopyright = "1.0";
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 < iHeightGrid; i++) {
for (int j = 0; j < iWidthGrid; 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; i < tmpRowColNos.length; i++)
if ((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 < iWidthGrid; i++) {
g.drawLine(origin.x + i * (iWidth / iWidthGrid), origin.y, origin.x
+ i * (iWidth / iWidthGrid), origin.y - iHeight);
}
// 画格子的横分隔线
for (int i = 1; i < iHeightGrid; 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 < iHeightGrid; i++) {
rtnRowNos[i] = referPoint[0] + (iHeightGrid - i - 1);
}
return rtnRowNos;
}
// 返回方块中所有有效部分在容器中显示的行号和列号.
public int[][] diamondsPosition() {
int[][] rtnRowColNos = new int[iHeightGrid * iWidthGrid][2];
// 转换,把方块内有效部分的坐标都转换成容器内的坐标,然后返回.
for (int i = 0; i < iHeightGrid; i++)
for (int j = 0; j < iWidthGrid; j++)
if (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 < iHeightGrid; i++) {
for (int j = 0; j < iWidthGrid; 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 < iHeightGrid; 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 < iWidthGrid; i++) {
for (int j = 0; j < iHeightGrid; 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 < diamondsTable.length; i++)
for (int j = 0; j < diamondsTable[i].length; j++)
if (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; i < iHeightGrid; i++)
for (int j = 0; j < iWidthGrid; j++)
aryDiamonds[i][j] = 1; // 对于方块0的状态0,4*1矩阵中的每一个元素都是显示部分.
break;
case 1:
iHeightGrid = 1;
iWidthGrid = 4;
aryDiamonds = new int[iHeightGrid][iWidthGrid];
for (int i = 0; i < iHeightGrid; i++)
for (int j = 0; j < iWidthGrid; j++)
aryDiamonds[i][j] = 1;
break;
}
break;
case 1:
switch (iStatusNo) {
case 0:
iHeightGrid = 3;
iWidthGrid = 2;
aryDiamonds = new int[iHeightGrid][iWidthGrid];
for (int i = 0; i < iHeightGrid; i++)
for (int j = 0; j < iWidthGrid; j++)
if (((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; i < iHeightGrid; i++)
for (int j = 0; j < iWidthGrid; j++)
if (((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; i < iHeightGrid; i++)
for (int j = 0; j < iWidthGrid; j++)
if (((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; i < iHeightGrid; i++)
for (int j = 0; j < iWidthGrid; j++)
if (((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; i < iHeightGrid; i++)
for (int j = 0; j < iWidthGrid; j++)
if (((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; i < iHeightGrid; i++)
for (int j = 0; j < iWidthGrid; j++)
if (((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 < iHeightGrid; i++)
for (int j = 0; j < iWidthGrid; j++)
if (((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; i < iHeightGrid; i++)
for (int j = 0; j < iWidthGrid; j++)
if (((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; i < iHeightGrid; i++)
for (int j = 0; j < iWidthGrid; j++)
if (((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; i < iHeightGrid; i++)
for (int j = 0; j < iWidthGrid; j++)
if (((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; i < iHeightGrid; i++)
for (int j = 0; j < iWidthGrid; j++)
if (((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; i < iHeightGrid; i++)
for (int j = 0; j < iWidthGrid; j++)
if (((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; i < iHeightGrid; i++)
for (int j = 0; j < iWidthGrid; j++)
aryDiamonds[i][j] = 1;
break;
case 6:
switch (iStatusNo) {
case 0:
iHeightGrid = 2;
iWidthGrid = 3;
aryDiamonds = new int[iHeightGrid][iWidthGrid];
for (int i = 0; i < iHeightGrid; i++)
for (int j = 0; j < iWidthGrid; j++)
if (((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; i < iHeightGrid; i++)
for (int j = 0; j < iWidthGrid; j++)
if (((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; i < iHeightGrid; i++)
for (int j = 0; j < iWidthGrid; j++)
if (((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; i < iHeightGrid; i++)
for (int j = 0; j < iWidthGrid; j++)
if (((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; i < iHeightGrid + iBufferHeightGrid; i++)
for (int j = 0; j < iWidthGrid; j++)
aryGrids[i][j].setInUse(0);
}
public int gameOverChk() // 检查是否已经GAMEOVER;返回值=0,没有GAMEOVER;=1,已经GAMEOVER.
{
int rtnGameOver = 0;
for (int i = 0; i < iWidthGrid; i++)
if (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; i < rtnRowColNos.length; i++)
if (((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<rtnRowNos.length;i++)
// {
// System.out.print(rtnRowNos[i]+",");
// }
// System.out.println();
fullRowNos = new int[rtnRowNos.length];
for (int i = 0; i < fullRowNos.length; i++)
fullRowNos[i] = 0;
// 方块所在行中,如果有行已满,则取出此行的行号.
for (int i = 0; i < rtnRowNos.length; i++) {
int rowNo;
int isFull; // 0-当前行未满,1-当前行已满.
rowNo = rtnRowNos[i];
isFull = 1;
for (int j = 0; j < iWidthGrid; 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 < fullCount; i++) {
int rowNo;
rowNo = fullRowNos[i];
for (int j = rowNo; j < iHeightGrid; j++) {
for (int k = 0; k < iWidthGrid; 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 < iWidthGrid; 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; i < iHeightGrid; i++)
for (int j = 0; j < iWidthGrid; j++)
aryGrids[i][j].drawGrid(g);
// 显示方块.
int[][] rtnRowColNos;
rtnRowColNos = objDiamonds.diamondsPosition();
// System.out.println("in drawGrids: rtnRowColNos.length="
// +rtnRowColNos.length);
// for(int i=0;i<rtnRowColNos.length;i++)
// {
// System.out.println("rtnRowColNos["+i+"][0]="+rtnRowColNos[i][0]+","+"rtnRowColNos["+i+"][1]="+rtnRowColNos[i][1]);
// }
for (int i = 0; i < rtnRowColNos.length; i++)
if ((rtnRowColNos[i][0] != -1) && (rtnRowColNos[i][1] != -1))
if (rtnRowColNos[i][0] < iHeightGrid)
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 < iWidthGrid; i++) {
g.drawLine(origin.x + i * (iWidth / iWidthGrid), origin.y, origin.x
+ i * (iWidth / iWidthGrid), origin.y - (iHeight));
}
// 画格子的横分隔线
for (int i = 1; i < iHeightGrid; 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 < aryLeftTouchGrids.length; 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 < aryRightTouchGrids.length; 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; i < rtnPosition.length; i++)
if ((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 < aryDownTouchGrids.length; 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; i < rtnPosition.length; i++)
if ((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; i < rtnPosition.length; i++)
if ((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 < aryDownTouchGrids.length; 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; i < rtnPosition.length; i++)
if ((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() {
setTitle("经典俄罗斯方块");
setSize(240, 400);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
Container contentPane = getContentPane();
contentPane.add(new eluosiPanel());
}
}
public class Russia {
public static void main(String[] args) {
JFrame myEluosi = new eluosiFrame();
myEluosi.show();
}
}
最后更新:2017-04-02 06:52:18