我罗斯方块汇报(1)
这个作业属于哪个课程 | 2020春福大面向对象程序设计 |
---|---|
这个作业要求在哪里 | 我罗斯方块汇报(1) |
这个作业的目标 | 汇报自己这个阶段的开发进度、讲述自己遇到的问题和尝试解决的方法和最后的结果,制作一篇开发日记 |
作业正文 | 我罗斯方块汇报(1) |
参考文献 | C++产生随机数 |
项目地址 | https://github.com/Blythe-fby/-.git |
小组成员姓名 | 学号 |
吴艳妮 | 031902141 |
范彬洋 | 031902433 |
开发进度
该项目目前暂定有五个类:背景类,方块类,边框类,渲染类,游戏类
- 在背景类中实现了空格方块、下落方块和固定方块的区分标记
- 在方块类中实现了方块的位置移动、判断是否可以移动、满行判断和消行操作的函数
- 在渲染类中实现了绘制长宽固定的两个边框以及其他文字信息的绘制边框函数
开发难题及解决情况
问题1:在玩家操作键盘移动时,不知如何简化判断是否能移动,和实现移动。[已解决]:用0,1,2数字标记方格搜索方格数字判断移动方格附近方格类型,改变旁边位置的标记数字实现移动
问题2:在绘制基本的边框时,使用了自定义的gotoxy函数却经常出现输出字符的位置和预期的位置有较大的偏差。[已解决]:注意x,y与行、列的对应,多次调试即可。
问题3:如何实现方块的生成?[未解决]
开发日记
方块类边框类实现日记
用背景类简化标记
最先思考的是在玩家操作键盘实现方块左右移动,和方块自动、手动下移时如何简化实现方块的移动 。
为了方便实现方块的位置的变换,我设计了一个背景类,用来存放10x20游戏界面方格的背景类型,一共有三种类型的背景,正在下落的方块(标记为1),落下之后固定的方块(标记为2),空格部分的方块(标记为零),将10x20方格背景都初始化为零。
class backg
{
public:
backg(void);
int addmarkA(int num);//玩家A满行加分
int addmarkB(int num);
public:
int background[20][10];
private:
int markA,markB;//计分
};
backg *ground = new backg;
backg::backg()//构造函数初始化背景
{
for(int i =0;i<20;i++)//边框行数为20
for(int j=0;j<10;j++)//边框列数为10
background[i][j]=0;//初始化无方块的空白背景为0
markA=0;
markB=0;
}
int backg::addmarkA(int num)
{
return this->markA=this->markA+num;
}
实现方块位置判断
方块每次移动前都要判断是否符合移动的要求
- 第一类情况是判断是否触及了边框(下、左、右)
bool Block::isDown()//是否接触到框下边
{
for(int i=0;i<10;i++)
if(1==ground->background[19][i])
return false;
return true;
}
bool Block::isLeft()//是否接触到框右边
{
for(int i=0;i<20;i++)
if(1==ground->background[i][0])
return false;
return true;
}
- 第二种情况是判断是否触碰到已固定方块(左右下碰撞函数)
以下落碰撞为例,其他同理见git
bool Block::isDown_collide()//下落障碍碰撞*
{
for(int i=19;i>=0;i--)
for(int j=0;j<10;j++)
if(1==ground->background[i][j])
if(2==ground->background[i+1][j])//&若下落方块(1)下面那行是2(固定方块)则碰撞不能下落
return false;
return true;
}
方块类的移动函数
通过改变相应位置标记数字实现方块的移动,如果玩家按左移键,先便利搜索所有标记为一的方格位置将标记数字置为0,在把相应位置左侧方格标记置为1,即实现左移。
void Block::MoveLeft()//左移
{
for(int i=0;i<sizeof(point)/sizeof(POINT);i++)
{
point[i].x-=20;
}
for(int i=0;i<20;i++)
{
for(int j=0;j<10;j++)
{
if(1==ground->background[i][j])
{
ground->background[i][j-1]=ground->background[i][j];
ground->background[i][j]=0;//&同理使左边的方块变为(1)原来为(1)的变为(0)
}
}
}
}
实现满行判断并将其消除玩家加分
每次下落方块变成固定方块时判断是否出现满行,遍历每行,有一行10个方块标记全为2时满行,第i行满行函数return true时,将第i行上面所有行的标记数逐行下移来实现消行
void Block::Fix()//固定函数
{
if(!isDown_collide()&&!isDown()) //两个下落判断函数都传回false
{
for(int i=0;i<20;i++)
{
for(int j=0;j<10;j++)
{
if(1==ground->background[i][j])
{
ground->background[i][j]=2;//1>>2;
num = 0;//
}
}
}
}
}
//判断是否满行*
bool Block::isFull(int a)//&第a行是否满行
{
int n=0;
for(int j=0;j<10;j++)
if(ground->background[a][j]==2)
n++;
if(n==10)//&这行10个方块都是(2)
{
ground->addmarkA(10);//&分数加10
//给对方增加一随机行
return true;
}
return false;
}
void Block::del()//消行*
{
for(int i=0;i<20;i++)
{
if(isFull(i))//&第i行的满行函数return true时
{
for(int n=i;n>=0;n--)
for(int j=0;j<10;j++)
ground->background[n][j] = ground->background[n-1][j];
//&从第i行往上的每行都向下移一行
for(int i2=0;i2<10;i2++)
ground->background[0][i2]=0;
//&由于所有行都向下了,最上面缺一行所以补一行(0)
}
}
}