罗马游戏

用Java实现一个小游戏:俄罗斯方块

使用二维数组保存游戏地图:

//?游戏地图网格,每个网格保存一个盒子,数组记录盒子的状态。

私人?状态?映射[][]?=?新的?状态[行][列];123

游戏开始前将地图中的所有格子初始化为空:

/*?将所有框初始化为空?*/

为了什么?(int?我?=?0;?我?& lt?map .长度;?i++)?{

为了什么?(int?j?=?0;?j?& lt?地图[i]。长度;?j++)?{

map[i][j]?=?状态。空的;

}

}1234567

在玩游戏的过程中,我们可以看到界面上的方块,所以我们要把地图上的方块都画出来。当然,除了画方块,必要时还需要画游戏分数和游戏结束时的字符串:

/**

*?绘制表单的内容,包括游戏框、游戏积分或结束字符串。

*/

@覆盖

公共?作废?油漆(图形?g)?{

super.paint(克);

为了什么?(int?我?=?0;?我?& lt?行;?i++)?{

为了什么?(int?j?=?0;?j?& lt?列;?j++)?{

如果?(图[i][j]?==?状态。主动)?{?//?绘制活动块

g . set color(active color);

g.fillRoundRect(j?*?块大小?我?*?BLOCK_SIZE?+?25,

BLOCK_SIZE?-?1,?BLOCK_SIZE?-?1,?BLOCK_SIZE?/?5,

BLOCK_SIZE?/?5);

}?不然呢?如果?(图[i][j]?==?状态。STOPED)?{?//?画一个静止的方块

g . set color(stoped color);

g.fillRoundRect(j?*?块大小?我?*?BLOCK_SIZE?+?25,

BLOCK_SIZE?-?1,?BLOCK_SIZE?-?1,?BLOCK_SIZE?/?5,

BLOCK_SIZE?/?5);

}

}

}

/*?打印分数?*/

g . set color(score color);

g.setFont(新?Font("Times?新的?罗曼“,?字体。大胆,?30));

g.drawString("分数?:?"?+?总分,?5,?70);

//?游戏结束,打印结束字符串。

如果?(!正在进行)?{

g.setColor(颜色。红色);

g.setFont(新?Font("Times?新的?罗曼“,?字体。大胆,?40));

g.drawString("游戏?结束了?!",?this.getWidth()?/?2?-?140,

this.getHeight()?/?2);

}

}123456789101112131415161718192021222324252627282930313233343536

由块组成的几种图形是由随机数生成的,一般是七种图形:条形、场形、正7形、反7形、T形、Z形、反Z形。

地图[0][randPos]?=?地图[0][randPos?-?1]?=?地图[0][randPos?+?1]?

=?地图[0][randPos?+?2]?=?状态。活跃;123

图形生成后,实现下落的操作。如果遇到阻碍,就不能继续往下掉:

isFall?=?真实;?//?是否能降。

//?从当前线开始检查,遇到障碍物停止下落。

为了什么?(int?我?=?0;?我?& lt?blockRows?i++)?{

为了什么?(int?j?=?0;?j?& lt?列;?j++)?{

//?如果该行中的块是活动块,下一行中的块是静态块,就会遇到障碍。

如果?(图【rowIndex?-?我][j]?==?状态。活跃的

& amp& amp?map[rowIndex?-?我?+?1][j]?==?状态。STOPED)?{

isFall?=?假的;?//?停止下降

打破;

}

}

如果?(!isFall)

打破;

}123456789101112131415

如果没有障碍物,下落时,正方形图形会整体下移一行:

//?这个数字下降了一行。

为了什么?(int?我?=?0;?我?& lt?blockRows?i++)?{

为了什么?(int?j?=?0;?j?& lt?列;?j++)?{

如果?(图【rowIndex?-?我][j]?==?状态。主动)?{?//?活动块向下移动一行。

map[rowIndex?-?我][j]?=?状态。空的;?//?原始活动块变为空。

map[rowIndex?-?我?+?1][j]?=?状态。活跃;?//?下一个块成为活动块。

}

}

}12345678910

向左和向右移动是类似的操作:

/**

*?向左转

*/

私人?作废?左()?{

//?标出左侧是否有障碍物。

布尔?hasBlock?=?假的;

/*?判断左侧是否有障碍物。*/

为了什么?(int?我?=?0;?我?& lt?blockRows?i++)?{

如果?(图【rowIndex?-?我][0]?==?状态。主动)?{?//?确定左边是不是墙。

hasBlock?=?真实;

打破;?//?如果有障碍,不需要回收判断线。

}?不然呢?{

为了什么?(int?j?=?1;?j?& lt?列;?j++)?{?//?判断左边是否还有其他区块。

如果?(图【rowIndex?-?我][j]?==?状态。活跃的

& amp& amp?map[rowIndex?-?我][j?-?1]?==?状态。STOPED)?{

hasBlock?=?真实;

打破;?//?如果有障碍,不需要回收判断栏。

}

}

如果?(hasBlock)

打破;?//?如果有障碍,不需要回收判断线。

}

}

/*?如果左边没有障碍物,将图形向左移动一个街区?*/

如果?(!hasBlock)?{

为了什么?(int?我?=?0;?我?& lt?blockRows?i++)?{

为了什么?(int?j?=?1;?j?& lt?列;?j++)?{

如果?(图【rowIndex?-?我][j]?==?状态。主动)?{

map[rowIndex?-?我][j]?=?状态。空的;

map[rowIndex?-?我][j?-?1]?=?状态。活跃;

}

}

}

//?重画

repaint();

}

}1234567891011121314151617181920212223242526272829303132333435363738394041

加速向下运动时,是为了减少每次正常下落的时间间隔:

/**

*?直走

*/

私人?作废?down()?{

//?印记会加速坠落。

立竿见影?=?真实;

}12345678

如何改变图形的方向,这里只用一个非常简单的方法来实现方向的改变。当然,可以有更好的算法来实现变向操作,你可以自己研究一下:

/**

*?旋转正方形图形

*/

私人?作废?rotate()?{

试试?{

如果?(形状?==?4)?{?//?正方形,旋转前后形状相同。

返回;

}?不然呢?如果?(形状?==?0)?{?//?剥夺

//?用于放置旋转图形的临时数组。

状态[][]?tmp?=?新的?状态[4][4];

int?startColumn?=?0;

//?在形状的开头找到第一个框的位置。

为了什么?(int?我?=?0;?我?& lt?列;?i++)?{

如果?(map[rowIndex][i]?==?状态。主动)?{

startColumn?=?我;

打破;

}

}

//?旋转后寻找障碍物,有障碍物就不要旋转。

为了什么?(int?我?=?0;?我?& lt?4;?i++)?{

为了什么?(int?j?=?0;?j?& lt?4;?j++)?{

如果?(图【rowIndex?-?3?+?我][j?+?startColumn)?==?状态。STOPED)?{

返回;

}

}

}

如果?(map[rowIndex][startColumn?+?1]?==?状态。主动)?{?//?水平条,转换成垂直条

为了什么?(int?我?=?0;?我?& lt?4;?i++)?{

tmp[i][0]?=?状态。活跃;

为了什么?(int?j?=?1;?j?& lt?4;?j++)?{

tmp[i][j]?=?状态。空的;

}

}

blockRows?=?4;

}?不然呢?{?//?竖线,转换成横线

为了什么?(int?j?=?0;?j?& lt?4;?j++)?{

tmp[3][j]?=?状态。活跃;

为了什么?(int?我?=?0;?我?& lt?3;?i++)?{

tmp[i][j]?=?状态。空的;

}

}

blockRows?=?1;

}

//?将原始地图中的图形修改为变换后的图形。

为了什么?(int?我?=?0;?我?& lt?4;?i++)?{

为了什么?(int?j?=?0;?j?& lt?4;?j++)?{

map[rowIndex?-?3?+?我][startColumn?+?j]?=?tmp[I][j];

}

}

}?不然呢?{

//?用于放置旋转图形的临时数组。

状态[][]?tmp?=?新的?状态[3][3];

int?startColumn?=?列;

//?在形状的开头找到第一个框的位置。

为了什么?(int?j?=?0;?j?& lt?3;?j++)?{

为了什么?(int?我?=?0;?我?& lt?列;?i++)?{

如果?(图【rowIndex?-?j][i]?==?状态。主动)?{

startColumn?=?我?& lt?startColumn?我?:?startColumn

}

}

}

//?判断改造后是否会有障碍。

为了什么?(int?我?=?0;?我?& lt?3;?i++)?{

为了什么?(int?j?=?0;?j?& lt?3;?j++)?{

如果?(图【rowIndex?-?2?+?j][startColumn?+?2?-?我]?==?状态。停止)

返回;

}

}

//?变化

为了什么?(int?我?=?0;?我?& lt?3;?i++)?{

为了什么?(int?j?=?0;?j?& lt?3;?j++)?{

tmp[2?-?j][i]?=?map[rowIndex?-?2?+?我][startColumn?+?j];

}

}

//?将原始地图中的图形修改为变换后的图形。

为了什么?(int?我?=?0;?我?& lt?3;?i++)?{

为了什么?(int?j?=?0;?j?& lt?3;?j++)?{

map[rowIndex?-?2?+?我][startColumn?+?j]?=?tmp[I][j];

}

}

//?重画

repaint();

//?修改行指针。

为了什么?(int?我?=?0;?我?& lt?3;?i++)?{

为了什么?(int?j?=?0;?j?& lt?3;?j++)?{

如果?(图【rowIndex?-?我][startColumn?+?j]?!=?空

||?map[rowIndex?-?我][startColumn?+?j]?!=?状态。空)?{

rowIndex?=?rowIndex?-?我;

blockRows?=?3;

返回;

}

}

}

}

}?接住?(例外?e)?{

//?当数组下标越界时,意味着图形的形状不经过任何处理就无法改变。

}

}123456789101112131415161718192021222324252627282930313233343536373 839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101

当图形的下降在受阻时停止,我们需要判断是否有某一条线或几条线可以消除。这时,我们可以先得到每行的方块数,然后判断:

int[]?blocksCount?=?新的?int[rows];?//?记录每行有方框的行数。

int?消除行?=?0;?//?消除的行数

/*?计算每行的方块数?*/

为了什么?(int?我?=?0;?我?& lt?行;?i++)?{

blocksCount[i]?=?0;

为了什么?(int?j?=?0;?j?& lt?列;?j++)?{

如果?(图[i][j]?==?状态。停止)

blocks count[I]++;

}

}1234567891011

如果有一整行盒子,则该行中的盒子被消除:

/*?实现满行的消盒操作?*/

为了什么?(int?我?=?0;?我?& lt?行;?i++)?{

如果?(blocksCount[i]?==?专栏)?{

//?清理线路

为了什么?(int?m?=?我;?m?& gt=?0;?m -)?{

为了什么?(int?n?=?0;?n?& lt?列;?n++)?{

map[m][n]?=?(m?==?0)?状态。空的?:?地图[m?-?1][n];

}

}

eliminate rows++;?//?记录消除的行数

}

}12345678910111213

最后,我们可以重画并显示积分。

重复上述生成图形、图形下落、左右移动、判断消除线条的操作,一个简单的俄罗斯方块就完成了。