罗马游戏
使用二维数组保存游戏地图:
//?游戏地图网格,每个网格保存一个盒子,数组记录盒子的状态。
私人?状态?映射[][]?=?新的?状态[行][列];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
最后,我们可以重画并显示积分。
重复上述生成图形、图形下落、左右移动、判断消除线条的操作,一个简单的俄罗斯方块就完成了。