作业描述 | 详情 |
---|---|
这个作业属于哪个课程 | 班级链接 |
这个作业要求在哪里 | 作业要求 |
这个作业的目标 | 讲述你的设计,你选用的渲染方法,你收集到的资料,和你的游戏界面示意图,和。注意:请详细写出你需要的类,和类的成员函数与成员变量。 |
作业正文 | 我罗斯方块汇报(1) |
其他参考文献 | |
项目地址 | 项目GitHub地址 |
小组成员 | 031902517-田剑心 031902637-廖晓玲 061900414-廖智炫 |
开发进度
对于本组框架中的涉及到的四个类:方块类(Brick)、玩家类(Player)、渲染类(Render)、游戏类(Game)
目前,的开发进度中:
方块类(Brick)已经完成并通过了一定数量的测试;
玩家类(Player)已经完成,但尚未测试;
渲染类(Render)由于涉及到较多的内容,尚在学习中,还未开始;
游戏类(Game)由于设计的过程较多,暂定于方块类、玩家类均通过初步测试后再进行编写
开发难题
对于目前本组开发中遇到的难题列举如下:
一、对于设计方案中太过概括的描述,不利于实现(已解决)
因此本组在 2020.5.17 开会,详细商讨了部分类的具体属性与方法:
由于在设计方案中,游戏中的地图储存在玩家类中,因此,方块类不适合用于判定是否判定边界
为此,细化方块类的职责———只负责移动与变化
而对于是否会碰撞,是否触碰到底边导致加入地图,是否触碰到天花板导致游戏结束,是否加入地图后需要删除一行
以上此类的所有操作,交由玩家类实现
二、如何实现游戏类的调度问题(未解决)
由于比赛涉及到双人对战环节,且俄罗斯方块有每隔一段时间会下落一格的特性
因此,如何在实现双人对战的消息转递的同时,还要同时考虑时间的处理
目前,本组可能会考虑使用双线程来处理,即一个线程进行对战过程中的消息传递,另一个线程进行时间的记录。当运行时间达到方块下落的单位时间时,将消息传递到对战
但考虑到双线程这一块目前知识点为 0 ,如果在后续设计过程中有想到其他处理方法可能会取消该想法
三、友元函数在不同文件下的写法(尚未解决)
根据上课所学,如果类 A 中的一个成员函数作为类 B 的友元函数,必须先定义类 A
本游戏实现游戏类时,很可能需要其中渲染的函数需要作为玩家类的友元函数
但游戏类的申明和定义分别在 Game.h
与 Game.cpp
中,玩家类在 Player.h
与 Player.cpp
中
而按照所学,需要先定义游戏类,才能定义玩家类中的友元函数;但游戏类中又存在对玩家类方法的调用
且两个类的申明、定义分别放在不同的文件内,贸然在前面加上申明可能会产生不知名的错误
这一块的代码具体怎么写,还需要写游戏类的时候进行研究
开发日记
田剑心
2020.5.18
实现了上、下、左、右移动的方法。。。
void brickSet(int x, int y);
实现了brickSet()方法,通过中心块(x,y)
来推导其他三块的坐标。。
直接暴力枚举,也就13种方块(其实有19种,太懒了就摸了)
2020.5.19
实现了方块类的旋转方法roteBrick(),
一开始感觉挺复杂,后面突然意识到旋转其实等价于变换形状
所以在中心块确认的条件下,可以直接通过改变参数BrickType,然后调用brickSet()方法重新对其他坐标进行推导,代码就简化成了13个选择语句。。
后续和同学讨论下指令的类型及参数的涵义把identifyOrder()方法解决,Brick类就基本实现了。。。。
2020.5.20
实现了最后的一个方法指令分发,同时优化了Brick的架构,进一步提高了封装性
class Brick {
private:
int BrickColor;//方块颜色
int BrickType;//方块类型
int BrickPos[9];//坐标集合
int CenterX, CenterY;//中心点坐标
void shiftLeft(int pace = 1);//左移
void shiftRight(int pace = 1);//右移
void shiftDown(int pace = 1);//下移
void shiftUp(int pace = 1);//上移
void brickUpdate();//更新颜色和类型
void rotateBrick();//顺时针旋转
static const int TotalBrickType = 17, TotalColorType = 4;
public:
static const int Up = 1, Down = 2,Left = 3, Right = 4, Rotate = 5, Update = 6;
Brick();//初始化类型和颜色
void brickSet(int x, int y);//通过x,y初始化坐标
void Operation(int _Order);//识别指令
int* getInformation();//返回信息
};
廖晓玲
2020.5.18
我先设计了一个首界面。
void Tetris::Welocme() //游戏刚进去的界面
{
SetColor(3);//设置颜色 (这是后面加进去的)
char x;
while(1)
{
system("cls");
cout <<" 俄罗斯方块 " << endl;
cout << "操作方式:" << endl;
cout <<"单人 双人"<<endl;
cout << "↑ - 旋转 w - 旋转" << endl;
cout << "↓ - 加速下移 s - 加速下移" << endl;
cout << "← - 左移 a - 左移" << endl;
cout << "→ - 右移 d - 右移" << endl;
cout <<"按1选择单人模式-按2选择双人模式" << endl;
SetPos(20, 10);//控制光标位置, 列, 行
x = getchar();
if(x <= '9' && x >= '0')
{
type = x - '0';//模式
break;
}
}
}
2020.5.19
我上百度搜索了渲染(包括字体颜色的改变)
渲染也包括界面的设计。
然后我设置了9种的颜色改字体的颜色。,主要是用上system("")来实现颜色的改变。
void Tetris::SetColor(int color_num)//设置颜色
{
int n;
switch(color_num)
{
case 0: n = 0x08; break;
case 1: n = 0x0C; break;
case 2: n = 0x0D; break;
case 3: n = 0x0E; break;
case 4: n = 0x0A; break;
case 5: n = 0x0F; break;
case 6: n = 0x09; break;
case 7: n = 0x0B; break;
case 8: n = 0x05; break;
case 9: n = 0x03; break;
}
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), n);
}
2020.5.20
我设计了两个游戏界面,且用了两个函数,绘画出一个是单人模式一个是双人模式
这是单人模式
void Tetris::DrawMap1() //单人画游戏时界面
{
int i;
for(i = 0; i <= 15; i++)
{
SetColor(5);
SetPos(i * 2, 0);
cout << "■";
SetPos(i * 2, 27);
cout << "■";
}
for(i = 0; i < 27; i++)
{
SetColor(5);
SetPos(0, i);
cout << "■";
SetPos(15*2, i);
cout << "■";
}
for(i = 16; i < 30; i++)
{
SetColor(0);
SetPos(i * 2, 0);
cout << "☆";
SetPos(i * 2, 10);
cout << "☆";
}
for(i = 0; i <= 10; i++)
{
SetColor(0);
SetPos(32, i);
cout << "☆";
SetPos(60, i);
cout << "☆";
}
SetPos(34, 2);
cout << "分数: " << score;
SetPos(34, 5);
cout << "下一图形:";
}
这是双人模式
void Tetris::DrawMap2() //双人画游戏时界面
{
int i;
SetColor(0);
//第一个计分的人
for(i = 0; i < 13; i++) //宽13格计分
{
SetColor(0);
SetPos(i * 2, 0);
cout << "☆";
SetPos(i * 2, 10);
cout << "☆";
}
for(i = 0; i <= 10; i++) //高10格计分
{
SetPos(0, i);
cout << "☆";
SetPos(13*2, i);
cout << "☆";
}
//第二个人计分的人
for(i = 43; i < 57; i++) //宽13格计分
{
SetPos(i * 2, 0);
cout << "☆";
SetPos(i * 2, 10);
cout << "☆";
}
for(i = 0; i <= 10; i++) //高10格计分
{
SetPos(43*2, i);
cout << "☆";
SetPos(57*2, i);
cout << "☆";
}
//第一个人的界面
for(i = 14; i < 25; i++) //宽13格计分
{
SetColor(5);
SetPos(i * 2, 21);
cout << "■";
}
for(i = 0; i <= 21; i++) //高21格计分
{
SetColor(5);
SetPos(50, i);
cout << "■";
SetPos(28, i);
cout << "■";
}
//第二个人的界面
for(i = 30; i < 42; i++) //宽13格计分
{
SetColor(5);
SetPos(i * 2, 21);
cout << "■";
}
for(i = 0; i <21; i++) //高21格计分
{
SetColor(5);
SetPos(60, i);
cout << "■";
SetPos(82, i);
cout << "■";
}
SetColor(3);
//Input_score();
SetPos(2, 2);
cout << "分数: " << score;
SetPos(2, 5);
cout << "下一图形:";
SetPos(88, 2);
cout << "分数: " << score;
SetPos(88, 5);
cout << "下一图形:";
}
这是用来画地图的光标移动!!
void SetPos(int i, int j) //控制光标位置, 列, 行
{
COORD pos={i,j};
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}
一开始感觉绘图还有光标移动很难,发现自己动手操作起来就可以实现了,这也是我第一次写开发日记,第一次用markdown,有一点点不熟悉,然后就是我知道我自己的水平可能不怎么样,但是我会努力学习的!!我认为对于界面的设计,对称尤为重要,我反复尝试,终于设计出我认为还算满意的界面了,另外对于色彩的选择,也得达到赏心悦目的标准,整个游戏的渲染代码不多,主要在于设计。
廖智炫
2020.5.17
和 dalao 樱落三千讨论了一下午,在尽量满足框架的情况下,比较清晰地确定了玩家类(Player)的职能,以及玩家类与方块类(Squre)、游戏类(Game)的互动方式
目前初步确定了玩家类的属性和方法。将在第二天确定玩家类属性和方法的具体方案。
2020.5.18
和 dalao 樱落三千讨论,进一步细化了玩家类的属性和方法。确认了玩家类和方块类、游戏类的交互模式,以及玩家类具体实现的想法。确定了玩家类的属性与方法,并写为了文件 Player.h
其中包括以下成员变量与函数:
class Player {
private:
int CountScore;//用于计分
bool MapSqure[30][10];//描述地图
bool GameOver;//判定是否游戏结束
std::string Name;//设定选手昵称
Brick NowBrick, NextBrick;//当前方块与下一方块
bool isOverlap();//判断是否方块会与地图重叠
bool carryCommand(int Direction);//执行指令,并返回是否执行成功
bool touchBottom();//判断方块是否与地图(包括已经成为地图的方块)重叠
bool touchCeiling();//判断方块放置后是否触碰到顶
void addToMap();//将方块加入到地图中
int delLine();//删除满的行,并返回删除行的数量
public:
Player(bool StartGame=0);//初始化
void setName(const std::string& Name_);//设置姓名
void run(int Direction,int &CountRemoveLine);//运行指令
void addLine(int CountLine);//增加行数
};
2020.5.19
实现了 Player.h
的部分方法。包括:判重、执行对方块的变化、判定是否触碰底部、删除目标行等
为了实现方便,添加入新的静态变量:
static int UP_LIM, DOWN_LIM, LEFT_LIM, RIGHT_LIM;
分别表示地图的边界
同时,使用暴力变换->判定重叠的方式来判定变换的合法性
2020.5.2
由于 Brick.h
的部分修改,修改了 Player.cpp
中的部分代码
同时,补充完了 Player.cpp
中的主体部分。目前 Player.cpp
部分仅剩余对游戏类提供的查询接口(可能考虑使用友元函数),以及测试
介于实现方便,对玩家类的描述改良为如下所示
class Player {
private:
static int UP_LIM, DOWN_LIM, LEFT_LIM, RIGHT_LIM;
int CountScore;
bool MapSqure[31][11];
bool GameOver;
std::string Name;
Brick NowBrick, NextBrick;
bool isOverlap();
bool carryCommand(int Direction);
bool touchBottom();
bool touchCeiling();
void addToMap();
int delLine();
int renewBrick();
public:
Player(bool StartGame=0);
void setName(const std::string& Name_);
int run(int Direction);
int addLine(int CountLine);
};
2020.5.21
对代码进行了初步的调试,解决了构造函数中数组溢出的问题,并加入了对方块类的初始化
突然觉得我用英文给代码写注释是个错误。按我的英语水平,会不会导致别人根本看不懂我在注释什么鬼