我罗斯方块最终篇
我罗斯方块最终篇
这个作业属于哪个课程 | 2020面向对象程序设计 |
---|---|
这个作业要求在哪里 | 查看详情 |
这个作业的目标 | 实现并展示我罗斯方块 |
作业正文 | 作业链接 |
作业要求 | 代码的 git 仓库链接、 运行截图/运行视频、 代码要点、 收获与心得、依然存在的问题 |
项目地址 | 仓库一 仓库二 |
小组成员 | 031902407林建斌 031902408林蒋辉 |
一、运行效果截图
二、代码要点
1. 渲染类
- 负责静态的界面
class Drawing {
public:
void drawMap();//游戏运行的静态边框
void welcome();//欢迎界面
void overScreen(int s1, int s2);//结束界面
};
2. 方块类
- 方块基类,将以它为基类派生七个不同方块的基本形状,其中change()声明为虚函数,以便派生类调用
class Block
{
public:
int x0, y0;//玩家地图基点
fangge f[4];//方块四个方格坐标
int shape;//方块的形状
int state;//之前是想表示方块状态,后来发觉没啥用,改的话派生类得改很多
void clearNextBlock(int wanjia);//显示下一个方块前,清除上一次显示的
void drawNextBlock(int a,int wanjia);//在小地图画下一个方块
virtual void change() {}//同类方块之间切换形状,声明为虚函数
void down();//下降
void moveLeft();//左移
void moveRight();//右移
bool checkLeft();//检查能否左移
bool checkRight();//检查能否右移
bool checkDown();//检查能否下降
void show();//显示方块
void hide();//消除方块
bool checkOver();//检查游戏是否结束
};
- 一字型方块,还有余下六种与之类似
class Block2 :public Block
{
public:
Block2(int x0, int y0);//构造函数声明方块的四个点坐标,形状
void change();//换形函数,通过改变坐标,实现换形
};
- change()函数 ,发现180°的翻转只要坐标通过改变加减符号即可。
void Block2::change() {
if (state == 1) {
hide();
switch (shape) {
case 0:
case 2:
if (MapValue[f[0].x + 2][f[0].y - 1] != 0 || MapValue[f[2].x - 2][f[2].y + 1] || MapValue[f[3].x - 4][f[3].y + 2] != 0) break;
f[0].x += 2; f[0].y -= 1;
f[2].x -= 2; f[2].y += 1;
f[3].x -= 4; f[3].y += 2;
shape = (++shape) % 4;
break;
case 1:
case 3:
if (MapValue[f[0].x - 2][f[0].y + 1] != 0 || MapValue[f[2].x + 2][f[2].y - 1] || MapValue[f[3].x + 4][f[3].y - 2] != 0) break;
f[0].x -= 2; f[0].y += 1;
f[2].x += 2; f[2].y -= 1;
f[3].x += 4; f[3].y -= 2;
shape = (++shape) % 4;
break;
}
show();
}
}
3. 玩家类
+两个玩家的区别,双人游戏实现的基础
class Player1 :public Block
{
private:
int n, m;//产生连个随机数
Block* b;//作为基类指针,以便后面指向新产生的方块
int Time;//双人游戏时,对时间的控制
public:
int score;//记录得分
Player1();//构造函数
void readKey(Block *b);//键盘读入
int checkFull();//检查是否满行,并消行
void Run();//游戏运行,方块下落
void newShow(int i);//消行或增加垃圾行后刷新画布
void showScore();//分数变化时,刷新分数
void addLine();//增加垃圾行
};
- 消行函数
int Player1::checkFull()
{
int count = 0;//计算消行数
for (int i = MapHeight - 1; i > 3; i--) //从下往上读
{
int flag = 1;
for (int j = x0 + 2; j < x0 + MapWidth-1; j += 2)//从左往右读
{
if (MapValue[j][i] == 0) {
flag = 0; break;
}
}
if (flag == 1)
{
for (int j = x0 + 2; j < x0 + MapWidth-1; j += 2)
{
for (int k = i; k > 3; k--) {
MapValue[j][k] = MapValue[j][k - 1];//将游戏地图值上移一行
}
}
count++;
newShow(i);
i++;
}
}
line2 = count;
score += count * 100;
showScore();
return 0;
}
- 增加垃圾行
void Player1::addLine()
{
while (line1--) {//增加line1行
for (int j = x0 + 2; j < x0 + MapWidth - 1; j += 2)//将游戏地图值往上移一行
{
for (int k = 4; k < MapHeight; k++) {
MapValue[j][k] = MapValue[j][k + 1];
}
}
for (int j = x0 + 2; j < x0 + MapWidth - 1; j += 2) {//随机增加一行
int n = getRandRange(0, 1);
setMapValue(j, MapHeight - 1, n);
}
newShow(MapHeight - 1);
}
}
- 运行函数
void Player1::Run()
{
while (1)
{
//判断是否产生垃圾行
if(line1!=0){
addLine();
line1 = 0;
}
if (Time > 150) { //标记时间,与双人有关
Time = 0;
//下落
if (b->checkDown()) b->down();
//不能下落
else {
//消行,并改变玩家二的line值,玩家二产生垃圾行
checkFull();
//准备下落新方块,并产生下一个方块
m = n;
n = getRandRange(1, 7);
drawNextBlock(n, 1);
switch (m)
{
case 1:b = new Block1(x0, y0); break;
case 2:b = new Block2(x0, y0); break;
case 3:b = new Block3(x0, y0); break;
case 4:b = new Block4(x0, y0); break;
case 5:b = new Block5(x0, y0); break;
case 6:b = new Block6(x0, y0); break;
case 7:b = new Block7(x0, y0); break;
}
//检查产生新方块时,是否已经到达上端
if (!(b->checkOver())) {
score = -1;
GameState = 0;
}
}
}
//读入按键
readKey(b);
//值越小读入按键更流畅,速度也更快
//通过Sleep和Time的使用,run1和run2交替执行,实现双人
Sleep(0.00001);
Time++;
break;
}
}
玩家二与玩家一基本相同
4. 游戏类
class Game
{
public:
void RunGame();
};
- 运行函数
void Game::RunGame()
{
HideCursor();//隐藏光标
Drawing Draw;
Draw.welcome();
system("cls");
Draw.drawMap();
Player1 player1;
Player2 player2;
//运行游戏
while (GameState) {
player1.Run();
player2.Run();
}
system("cls");
Draw.overScreen(player1.score, player2.score);
system("pause>nul");
}
5. 其他
//结构体表示方块坐标x,y
struct fangge {
int x, y;
};
//隐藏光标
void HideCursor();
//光标去到某处
void gotoXY(int x, int y);
//枚举将颜色与数字关联
enum Color{};
//设置颜色
void setColor (enum Color color);
//获取min到max之间的随机数
int getRandRange(int min, int max);