我罗斯方块最终篇
这个作业属于哪个课程 | 2020春福大面向对象程序设计 |
---|---|
这个作业要求在哪里 | 我罗斯方块最终篇 |
这个作业的目标 | 代码的 git 仓库链接、运行截图/运行视频、代码要点、收获与心得、依然存在的问题 |
作业正文 | 我罗斯方块最终篇 |
项目地址 | https://github.com/Blythe-fby/-.git |
小组成员姓名 | 学号 |
吴艳妮 | 031902141 |
范彬洋 | 031902433 |
运行截图
代码要点
- 新增了player类继承于Block类
class Player1:public Block{
int id1;//玩家A当前的图形id
int next_id1;//玩家A的下一个图形id
int t1;
public:
int play1[20][10];
void update();//不断更新绘制A画布
void newblock();//生成新的方块
void nextblock();//生成下一个方块
void getfunA();//获取A玩家的操作
void carry();
};
- 开始测试下落的时候生成方块后原来的方块没消除,后来加了覆盖操作
void Player1::update(){
int x,y;
for(x=0;x<20;x++){
for(y=0;y<10;y++){
if(ground->background[x][y]==1||ground->background[x][y]==2){
gotoxy(2*y+12,x+5);
cout<<"■";
}
if(ground->background[x][y]==0){//消除覆盖原来方块
gotoxy(2*y+12,x+5);
cout<<" ";
}
}
}
}
- 利用gotoxy()函数来控制光标位置,从而实现输入输出
void gotoxy(int x, int y) {
HANDLE hout;
COORD coor;
coor.X = x;
coor.Y = y;
hout = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hout, coor);
}//控制光标位置的函数
- 根据两个二维数组来实现对方框内容的增加、修改等,并呈现在控制台上。注意不能只写到输出方块,还要在内容为空的时候输出两个空格,避免方块曾经留下的痕迹持续保留
void Player1::update(){//玩家A的刷新画布函数
int x,y;
for(x=0;x<20;x++){
for(y=0;y<10;y++){
if(ground->background[x][y]==1||ground->background[x][y]==2){
gotoxy(2*y+12,x+5);
cout<<"■";
}
if(ground->background[x][y]==0){
gotoxy(2*y+12,x+5);
cout<<" ";
}
}
}
}
- 可以利用随机数的生成来随机产生新方块以及增加底层行
void Player1::addlastline(){//增加A玩家的底层行
int k,i,j;
for(i=0;i<20;i++){
for(j=0;j<10;j++){
if(play1[i][j]==2){
play1[i][j]=0;
play1[i-1][j]=2
}
}
}
for(j=0;j<10;j++){
k=rand%100;
if(k>40)
play1[19][j]=2;
else
play1[19][j]=0;
}
}
开始时面向过程的思想非常重,总是希望按顺序一个一个操作往下写,后来看到大家main()函数里都只有几行定义和调用,了解了封装和继承思想之后我采用两个方法:
- 专门开辟一个成员函数用来调用
- 按照操作顺序在上一个函数的结尾调用下一个操作的函数
这样可以简便的调用一两个函数就能实现整个运行。
收获与心得
- 体会到写一个游戏和写pta样式的题目的性质和体验是完全不同的,写题目只要解决单独一个问题就好了,而游戏的代码更加庞大,需要解决更多衔接、关联相关的问题。
- 通过学习代码学到了一些看上去比较长但是好用的函数,以及获取上下左右按键的方法
- 对于封装与继承思想理解更深刻了,感觉整个代码思路变得更加清晰了。
- 测试过程中出现了各种问题,一点点对比数值调试,提升了调试技术,学习了许多新函数,由于开始在网上参考的代码经常篇幅很长而且看不懂,我和队友就用简单易懂的方法一点点写一点点调试,没有用什么花哨的颜色和特效因为都是自己写的技术有点不到位,以后可以多多学习渲染技巧。
还存在的问题
-
不能支持重开游戏
-
面向对象的知识可能没有得到充分的应用,例如定义的两个整型函数并不能在类中保持私有的封装,没有摆脱被全局的命运,以及渲染类里面的两个函数最后被拆分到游戏类和玩家类当中去了,类和类之间的关系并不是很紧密。
-
如果使用两个数组来操作两个方块,且操作方法需要写两份功能一样但名称不一样的代码,会让代码变得非常的长,写起来也消耗时间。
-
目前还不能够实现方块的正常旋转。
-
在一个函数里调用一个方块生成下落固定的过程,放弃了计时器选用Sleep()函数来实现下落的停顿,每一次循环实现下落一格且扫描一次键盘输入,但出现每次下移都必须输入一次,不输入就无法下移的问题,如何实现下落循环和和玩家操作循环分开同时进行?
代码如下:
void Player1::carry()
{
newblock();生成新随机方块
update();
while(isDown_collide()&&isDown())//下落碰撞判断
{
fall(); 下落一格
Sleep(300);
getfunA();
int m=Fix();//固定函数1转换成2
del(); //消行
update();//更新绘制方块
if(!m) break;
}
}
void Player1::getfunA(){
char c;
if(c=_getch()){
//if(c=='w')
if(c=='a')
if(isLeft()&&isLeft_collide())
MoveLeft();
if(c=='s')
fall();
if(c=='d')
if(isRight()&&isRight_collide())
MoveRight();
}
}