C++面向对象程序综合设计
一、基本要求
1、综合实验设计可采取一人一设计,也可以组成小组,每组成员(不得超过4人)分工合作完成一个设计,每个人的任务不同。
2、要求利用面向对象程序设计方法以及C++的编程思想来完成系统的设计。
3、要求有菜单、文件操作,数据使用数组、结构体等均可,键盘操作或鼠标操作均可。
4、所编写的程序必须上机通过,并获得满意的结果。
5、完成综合实验设计报告书。
二、实验内容
(1)实验题目:俄罗斯方块小游戏
(2)问题描述
俄罗斯方块是在一个m*n 的矩形框内进行的,矩形框的顶部会随机的出现一个有四个小方块组成的砖块,每过一段时间,就会下落一格,知道他碰到底部,然后再过一个时间下落另一个砖块,依次进行,砖块是随机出现的。当发现底部砖块是满的话,则消去它从而得到相应设置的分数,当砖块到达顶部的时候,游戏结束。选择俄罗斯方块进行C++面向对象程序设计课程设计主要是在学习C++这门面向对象语言的基础上,并通过实践加深对 C++面向对象程序设计语言特点的认识与理解。同时,可以提高运用C++编程语言解决实际问题的能力;锻炼实际的编程能力;还能提高调查研究、查阅技术文献、资料以及编写软件设计文档的能力。
(3)功能要求
【1】实现方块的变形、下落、左移、右移消行等基本的功能。
【2】实现方块暂停、判断分数以及等级设置功能。
【3】界面窗口、以及小方块图形设计功能。
(4)算法分析
游戏中会出现6大类,19种形状类型,每种形状在游戏中都能够旋转,形成新的形状。每种形状都是由方形的色块组成的。
a)程序中方法void make_tetris(struct Tetris *tetris)穷举出19中方块形状类型。
b)方法int if_moveable(struct Tetris *tetris)判断方块是否可以移动。
c)方法void get_flag(struct Tetris *tetris)随机产生19中方块形状类型的序号用于区分不同的形状。
d)方法void print_tetris(HANDLE hOut,struct Tetris *tetris)打印随机生成的俄罗斯方块。
e)方法void clear_tetris(HANDLE hOut,struct Tetris *)用于清除俄罗斯方块的痕迹。
f)方法void del_full(HANDLE hOut,struct Tetris *);判断方块是否满行。
三、概要设计
(1)俄罗斯方块功能设计图
(2)功能描述
a)方块操作功能:在方块下落时,可以通过键盘左方向键← 和 右方向键→ 控制方块在下降的过程中向左移动、向右移动。方向键↑控制方块的变形。
b)得分功能:每消除一行得100分。以此累加。
c)等级提升功能:当得分为1000分时(即消除10行),等级提升一级。
d)方块速度控制:默认速度是400ms,每当等级提升一级时,下降时间减少20ms。
e)游戏控制:空格键游戏暂停,再次点击空格键,游戏继续。当点击Esc按键时退出游戏。
四、详细设计
4.1声明结构体
//声明俄罗斯方块的结构体
struct Tetris
{
int x; //中心方块的x轴坐标
int y; //中心方块的y轴坐标
int flag; //标记方块类型的序号
int next; //下一个俄罗斯方块类型的序号
int speed; //俄罗斯方块移动的速度
int count; //产生俄罗斯方块的个数
int score; //游戏的分数
int level; //游戏的等级
};
4.2制作游戏窗口
/******制作游戏窗口 */
void make_frame()
{
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); //定义显示器句柄变量
gotoxy(hOut,FrameX+Frame_width-5,FrameY-2); //打印游戏名称
cout<<"俄罗斯方块"<<endl;
gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+7); //打印选择菜单
cout<<"**********下一个方块:"<<endl;
gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+13);
cout<<"**********"<<endl;
gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+17);
cout<<"↑键:变体"<<endl;
gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+19);
cout<<"空格:暂停游戏"<<endl;
gotoxy(hOut,FrameX+2*Frame_width+3,FrameY+15);
cout<<"Esc :退出游戏"<<endl;
gotoxy(hOut,FrameX,FrameY); //打印框角并记住该处已有图案
cout<<"╔"<<endl;
gotoxy(hOut,FrameX+2*Frame_width-2,FrameY);
cout<<"╗"<<endl;
gotoxy(hOut,FrameX,FrameY+Frame_height);
cout<<"╚"<<endl;
gotoxy(hOut,FrameX+2*Frame_width-2,FrameY+Frame_height);
cout<<"╝"<<endl;
a[FrameX][FrameY+Frame_height]=2;
a[FrameX+2*Frame_width-2][FrameY+Frame_height]=2;
for(i=2;i<2*Frame_width-2;i+=2)
{
gotoxy(hOut,FrameX+i,FrameY);
cout<<"═"<<endl; //打印上横框
}
for(i=2;i<2*Frame_width-2;i+=2)
{
gotoxy(hOut,FrameX+i,FrameY+Frame_height);
cout<<"═"<<endl; //打印下横框
a[FrameX+i][FrameY+Frame_height]=2; //记住下横框有图案
}
for(i=1;i<Frame_height;i++)
{
gotoxy(hOut,FrameX,FrameY+i);
cout<<"║"<<endl; //打印左竖框
a[FrameX][FrameY+i]=2; //记住左竖框有图案
}
for(i=1;i<Frame_height;i++)
{
gotoxy(hOut,FrameX+2*Frame_width-2,FrameY+i);
cout<<"║"<<endl; //打印右竖框
a[FrameX+2*Frame_width-2][FrameY+i]=2; //记住右竖框有图案
}
}
4.3随机产生方块类型的序号
/******随机产生俄罗斯方块类型的序号***********/
void get_flag(struct Tetris *tetris)
{
tetris->count++; //记住产生方块的个数
srand((unsigned)time(NULL)); //初始化随机数
if(tetris->count==1)
{
tetris->flag = rand()%19+1; //记住第一个方块的序号
}
tetris->next = rand()%19+1; //记住下一个方块的序号
}
4.4制作俄罗斯方块
/******制作俄罗斯方块*************/
void make_tetris(struct Tetris *tetris)
{
a[tetris->x][tetris->y]=b[0]; //中心方块位置的图形状态:1-有,0-无
switch(tetris->flag) //共6大类,19种类型
{
case 1: //田字方块
{
a[tetris->x][tetris->y-1]=b[1];
a[tetris->x+2][tetris->y-1]=b[2];
a[tetris->x+2][tetris->y]=b[3];
break;
}
case 2: //直线方块:----
{
a[tetris->x-2][tetris->y]=b[1];
a[tetris->x+2][tetris->y]=b[2];
a[tetris->x+4][tetris->y]=b[3];
break;
}
case 3: //直线方块: |
{
a[tetris->x][tetris->y-1]=b[1];
a[tetris->x][tetris->y-2]=b[2];
a[tetris->x][tetris->y+1]=b[3];
break;
}
case 4: //T字方块
{
a[tetris->x-2][tetris->y]=b[1];
a[tetris->x+2][tetris->y]=b[2];
a[tetris->x][tetris->y+1]=b[3];
break;
}
case 5: //T字顺时针转90度方块
{
a[tetris->x][tetris->y-1]=b[1];
a[tetris->x][tetris->y+1]=b[2];
a[tetris->x-2][tetris->y]=b[3];
break;
}
case 6: //T字顺时针转180度方块
{
a[tetris->x][tetris->y-1]=b[1];
a[tetris->x-2][tetris->y]=b[2];
a[tetris->x+2][tetris->y]=b[3];
break;
}
case 7: //T字顺时针转270度方块
{
a[tetris->x][tetris->y-1]=b[1];
a[tetris->x][tetris->y+1]=b[2];
a[tetris->x+2][tetris->y]=b[3];
break;
}
case 8: //Z字方块
{
a[tetris->x][tetris->y+1]=b[1];
a[tetris->x-2][tetris->y]=b[2];
a[tetris->x+2][tetris->y+1]=b[3];
break;
}
case 9: //Z字顺时针转90度方块
{
a[tetris->x][tetris->y-1]=b[1];
a[tetris->x-2][tetris->y]=b[2];
a[tetris->x-2][tetris->y+1]=b[3];
break;
}
case 10: //Z字顺时针转180度方块
{
a[tetris->x][tetris->y-1]=b[1];
a[tetris->x-2][tetris->y-1]=b[2];
a[tetris->x+2][tetris->y]=b[3];
break;
}
case 11: //Z字顺时针转270度方块
{
a[tetris->x][tetris->y+1]=b[1];
a[tetris->x+2][tetris->y-1]=b[2];
a[tetris->x+2][tetris->y]=b[3];
break;
}
case 12: //7字方块
{
a[tetris->x][tetris->y-1]=b[1];
a[tetris->x][tetris->y+1]=b[2];
a[tetris->x-2][tetris->y-1]=b[3];
break;
}
case 13: //7字顺时针转90度方块
{
a[tetris->x-2][tetris->y]=b[1];
a[tetris->x-2][tetris->y+1]=b[2];
a[tetris->x+2][tetris->y]=b[3];
break;
}
case 14: //7字顺时针转180度方块
{
a[tetris->x][tetris->y-1]=b[1];
a[tetris->x][tetris->y+1]=b[2];
a[tetris->x+2][tetris->y+1]=b[3];
break;
}
case 15: //7字顺时针转270度方块
{
a[tetris->x-2][tetris->y]=b[1];
a[tetris->x+2][tetris->y-1]=b[2];
a[tetris->x+2][tetris->y]=b[3];
break;
}
case 16: //倒7字方块
{
a[tetris->x][tetris->y+1]=b[1];
a[tetris->x][tetris->y-1]=b[2];
a[tetris->x+2][tetris->y-1]=b[3];