C++课程设计实验报告(俄罗斯方块)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一、需求分析
1.1系统概述
该游戏在DOS下为玩家提供传统俄罗斯方块游戏的基本功能,玩家可以通过键盘控制在游戏区中堆积软件随机提供的由四个小方块不同组合的7种类型不同颜色的方块,每个小方格的颜色也是随机的,并且在整个下落的过程中,其颜色也呈动态变化。游戏过程中,每在游戏区堆满一行后,自动消除并记分。同时消去的行数越多,那一次性所加的分数也就越多。一行是100,两行是200,三行是400,四行是500分。为了得到更多的分,那么我们游戏者就要想办法一次尽可能多的消去方块。当游戏区不能再堆积新来的方块时,游戏结束。游戏设定3个级别,初级,中级和高级,每个级别有分三个小的级别,级别越高,方块下降的速度越快、难度越大。为了避免游戏频发枯燥,增加游戏的趣味性,该游戏为游戏者插入了音乐,对该功能有实现暂停的控制。该游戏的以“英雄榜”来判断玩家水平的高低,如果玩家的得分大于了保存的最高分,则将玩家的的得分写入文件,如果得分不大于最高分,则保持不变。游戏以最终玩家获得的分数来判断玩家水平的高低。
1.2功能需求描述
这次实验以及部分功能的实现都是一次小小的尝试,获得不错的效果。
这个游戏,不仅可以满足游戏爱好者对游戏的要求,同时我们增加了趣味性,让游戏有一个比较好听的背景音乐,在玩游戏的同时,让玩家饱享视听大宴。
这有别于常规的俄罗斯方块算法,游戏中,玩家依靠自己消层来得分,而且保证了玩家对游戏趣味性的追求,并且游戏的英雄榜功能为玩家提供了一个良好的测试水平的平台。当玩家游戏池中的砖块累积到顶端时游戏失败。
二、系统设计
2.1 数据流程图
数据流图是对系统数据流向的一种描述,并从本质上让程序的使用者,大致了解系统的使用方法。本俄罗斯游戏的大致流程图如下:
2.2 程序功能模块
2.3程序流程图
三、关键代码描述
3.1 程序模块详细设计
3.1.1 界面初始化
程序界面程序在启动运行时,系统会通过调用视图类中的重绘图函数对界面进行界面的初始化。其界面如图所示:
实现该功能的代码如下:
void ViewWindows :: draw()
{
initgraph(640, 480);
srand((unsigned)time(NULL));
// 显示操作说明
setfont(14, 0, _T("宋体"));
outtextxy(20, 330, _T("操作说明"));
outtextxy(20, 350, _T("上:旋转"));
outtextxy(20, 370, _T("左:左移"));
outtextxy(20, 390, _T("右:右移"));
outtextxy(20, 410, _T("下:下移"));
outtextxy(20, 430, _T("空格:沉底"));
outtextxy(20, 450, _T("ESC:退出"));
// 设置坐标原点
setorigin(220, 20);
// 绘制游戏区边界
rectangle(-1, -1, WIDTH * SIZE, HEIGHT * SIZE);
rectangle((WIDTH + 1) * SIZE - 1, -1, (WIDTH + 5) * SIZE, 4 * SIZE); }
void ViewGameinfo :: draw(int Score, int Level, int Higest_score)
{
char sc[10], sl[10], sr[10];
int Higest_num;
ifstream file_in("d:\\Higest_score.txt");
if(!file_in)
{
ofstream file_ou("d:\\Higest_score.txt");
file_ou<<0< return; } file_in>>Higest_num; Higest_score =Higest_num; sprintf(sc, "%4d", Score); sprintf(sl, "%4d", Level); sprintf(sr, "%4d", Higest_score); outtextxy(-200, 100, _T("Score")); outtextxy(-200, 120, sc); outtextxy(-200, 140, _T("Level")); outtextxy(-200, 160, sl); outtextxy(-200, 180, _T("Higest_score")); outtextxy(-200, 200, sr); } void ViewBlock :: DrawBlock(BLOCKINFO _block, DRAW _draw) { WORD b = g_Blocks[_block.getID()].dir[_block.getDir()]; int x, y; int color = BLACK; switch(_draw) { case SHOW: color = g_Blocks[_block.getID()].color; break; case HIDE: color = BLACK; break; case FIX: color = g_Blocks[_block.getID()].color / 3; break; } setfillstyle(color); for(int i=0; i<16; i++) { if (b & 0x8000) { x = _block.getX() + i % 4; y = _block.getY() - i / 4; if (y < HEIGHT) { if (_draw != HIDE) bar3d(x * SIZE + 2, (HEIGHT - y - 1) * SIZE + 2, (x + 1) * SIZE - 4, (HEIGHT - y) * SIZE - 4, 3, true); else bar(x * SIZE, (HEIGHT - y - 1) * SIZE, (x + 1) * SIZE - 1, (HEIGHT - y) * SIZE - 1); } } b <<= 1; } } 3.1.2游戏随机获取新方块的实现如下: void Control :: NewGame() { // 清空游戏区