欢迎来到淘文阁 - 分享文档赚钱的网站! | 帮助中心 好文档才是您的得力助手!
淘文阁 - 分享文档赚钱的网站
全部分类
  • 研究报告>
  • 管理文献>
  • 标准材料>
  • 技术资料>
  • 教育专区>
  • 应用文书>
  • 生活休闲>
  • 考试试题>
  • pptx模板>
  • 工商注册>
  • 期刊短文>
  • 图片设计>
  • ImageVerifierCode 换一换

    c语言俄罗斯方块实验报告.pdf

    • 资源ID:31937772       资源大小:97.26KB        全文页数:22页
    • 资源格式: PDF        下载积分:12金币
    快捷下载 游客一键下载
    会员登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录   QQ登录  
    二维码
    微信扫一扫登录
    下载资源需要12金币
    邮箱/手机:
    温馨提示:
    快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。
    如填写123,账号就是123,密码也是123。
    支付方式: 支付宝    微信支付   
    验证码:   换一换

     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    c语言俄罗斯方块实验报告.pdf

    1 C语言之游戏俄罗斯方块课程设计报告专业: 学生姓名: 指导教师: 完成时间:2 目录一、需求分析 . 错误! 未定义书签。二、概要设计 . 错误! 未定义书签。三、详细设计 . 错误! 未定义书签。四、调试分析 . 19 五、用户手册 . 20 六、测试数据 . 错误! 未定义书签。七、附录 . 错误! 未定义书签。3 一、需求分析1. 该程序是完成一个简易的俄罗斯方块的任务,其要完成几个重要的功能: 界面,方块下落,旋转,判断是否还能下落,左右移动,分数,速度设置,清楚满的每行,下个方块的预览等;2. 可用#include 的头文件来实用几个函数来控制并完成游戏的界面;3. 可用 7 个二维 5*5 数组去实现下落方块的全部类型, 再用随机函数使其随机下落;4. 用#include 的头文件去使用按键的控制,以保证用户能够合理操作;并用 #include 的头文件来使用 rand 函数来随机出示七种方块;完成正常的显示和下个方块的预览;5. 用 #include 来运用时针去控制时间;6. 程序执行过程:然后加上几个基本的头文件来执行函数,首先设置按键操作,用:w,a,d,s 控制,然后进行界面的初始化设置,启动,时针参数设置,开始新游戏, 开始随机下落方块, 显示下一个方块, 再行旋转, 移动,清除,加分,速度参数,最后判断是否已满,停止游戏,打出分数,结束的画面设置,游戏终止. 二、概要设计该程序中的函数设置总体主要功能大致如下1. 找到合适的方块盒子 (7 种)使其一一下落 boxMAX_C55 = /*MAX_C(7)种预定义的盒子 */ 这样用类似的 7个 5*5 二维数组来实现每个盒子方块的形状,自此就引荐两个作为介绍, 0,0,0,0,0, 0,0,0,0,0, 0,0,1,0,0, 0,1,1,1,0, 0,0,0,0,0, 4 0,0,0,0,0 , 0,0,0,0,0, 1,1,1,1,0, 0,0,0,0,0, 0,0,0,0,0 , 如此中用 1 代表显示的格子, 0 代表空。2. 设置时间指针,实现旋转,移动,消去,显示加分,改变速度分别用下面函数表示 int setTimer(Timer *t, unsigned int intv, BOOL en); /* 设置时钟 t, 参数分别为时钟指针 , 时间间隔 , 是否活动 */ void rotateBox(int box155, int box255) /* 旋转 box1 输出到 box2*/ int move(int dir) /*实现移动,返回成功与否*/ void clear() /*清除掉满行 */ void prscore() /*打印现在的分数 */ void spe()/*显示速度的改变 */ 3. 外部函数功能如下图4. 建立整个函数的流程图如下: 益智游戏俄罗斯方块判 断 最后 , 游戏 结 束的操作 ; 用prscore( ) 和界 面 设置完成开始界面界面设置void initMap 函数 和void render绘图函数随 机 显 示 方块,并建立下一个;用 rand( )与void rebuidNext 方块的旋转和移动下落;用rorate()move()与 drop ()来实现判断是否能继续下落;用 int test()函 数 来 完成;分数的改变与速度设置;用prscore ()与 spe()来完成5 N Y Y N 时间指针设定随机出示方块,并显示下个方块实现方块的旋转,移动判断是否到底加分,速度设置判断是否已满打印分数,结束处理游戏结束6 流程简介:玩家定义游戏开始,游戏显示开始界面,时针已经设定好,然后随机出示方块,玩家进行方块的旋转,左右移动,和下落控制,然后在旁边的表格中出示另一个表格显示下一个即将下落的方块,然后判断是否到达底部, 若到,继续出示方块,若没,则可继续变换,下落到低端后在进行判断,是否可以消除该行,再进行分数的变换,速度的调整,然后判断是否已经满,若未满,则继续出示下一个方块,若满,则结束游戏,打印分数,出示结束界面,游戏终止。三、详细设计1. 设置七种方块:这个用int boxMAX_C55 = /*MAX_C(7)种预定义的盒子*/ 来实现;即七个 5*5 的盒子数组,方块实体用1 表示, 0 表示空;七种如下所示,细心就会发现 0,0,0,0,0, 0,0,0,0,0, 1,1,1,1,0, 0,0,0,0,0, 0,0,0,0,0 , 0,0,0,0,0, 0,0,1,0,0, 0,1,1,1,0, 0,0,0,0,0, 0,0,0,0,0 , 0,0,0,0,0, 0,1,1,0,0, 7 0,0,1,1,0, 0,0,0,0,0, 0,0,0,0,0 , 0,0,0,0,0, 0,0,1,1,0, 0,1,1,0,0, 0,0,0,0,0, 0,0,0,0,0 , 0,0,0,0,0, 0,1,1,0,0, 0,0,1,0,0, 0,0,1,0,0, 0,0,0,0,0 , 0,0,0,0,0, 0,0,1,1,0, 0,0,1,0,0, 0,0,1,0,0, 0,0,0,0,0 , 8 0,0,0,0,0, 0,0,1,1,0, 0,0,1,1,0, 0,0,0,0,0, 0,0,0,0,0 ; 这样七种盒子的方块就被清楚的展现在你们面前。用来保证方块不会出来2. 我们要进行按键的设置 #define KEY_UP w /*定义上下左右按按键 */ #define KEY_DOWN s #define KEY_LEFT a #define KEY_RIGHT d #define KEY_ESC 27 /* 退出*/ 3. 时钟的控制,用来控制方块的下落间隔时间及速度/* 时钟结构控制 */ typedef struct /*时钟结构 */ BOOL enabled; /*时钟是否开启 */ unsigned int intervel; /*定时间隔 */ unsigned int lasttime; /*这个属于内部使用变量 */ Timer; 4.int GetTickCount() /*读取 BIOS时钟*/ int ret; ret = peek(0 x0,0 x46e); /*实际上读取了内存0:046e 处的内容 */ ret enabled = en; /*设置一个时钟罗 */ 9 t - intervel = intv; t - lasttime = GetTickCount(); /*lasttime记录的是上一个 */ /*tickcount返回的东西 */ /* 这样当再一次测试时间时新的tickcount产生了它来减去上一次的 tickcount就得出了一个时间间隔, 这个就可以和 intervel比较从而得出是否激活了 */ return 0; 实现了以上的操作后,接下来要实现界面的设置一方便盒子在界面上的显示和操作;5.void initMap(void) /*初始化地图 */ /* 我们须要一圈卫兵呵呵,全是1. 用来保证方块不会出来 */ int x, y; for(y = 0; y MAX_Y; y+) for(x = 0; x MAX_X; x+) if(x MAX_X - 3 | y MAX_Y - 3) mapyx = 1; else mapyx = 0; /*这里初始化出这个形状 */ /*当然是无盖的 .*/ void render(void) /*这里唯一的绘图函数 */ int x, y; static int cPage = 0; /*当前页 , 换页用 */ #define STARTX 50 /*定义几个常量 */ #define STARTY 0 /*数值根据自己的需要可以自己设置*/ #define LEN 18 10 setactivepage(cPage=(cPage = 0?1:0); /*选择页 */ cleardevice(); /*清屏*/ setcolor(12);/*前景颜色 */ prscore(); setcolor(15); rectangle( STARTX + LEN * 2 - 2, STARTY + LEN * 3 - 2, STARTX + LEN * (MAX_X - 2) + 2, STARTY + LEN * (MAX_Y - 2) + 2); /* 用白色画一个外框 */ setfillstyle(SOLID_FILL, 5); for(y = 3; y MAX_Y - 2; y+) /*画地图 */ for(x = 2; x MAX_X - 2; x+) if(mapyx) rectangle( x * LEN + STARTX, y * LEN + STARTY, x * LEN + STARTX + LEN, y * LEN + STARTY + LEN); bar( x * LEN + STARTX + 1, y * LEN + STARTY + 1, x * LEN + STARTX + LEN - 2, y * LEN + STARTY + LEN - 2); /* 绘图操作就不要作太复杂的介绍了, 这只写作用 */ /* 以上段 , 根据地图上的点阵情况将地图反映到屏幕上*/ for(y = 0; y 5; y+) /*画下落物 */ for(x = 0; x 2) rectangle( (x + curx) * LEN + STARTX, (y + cury) * LEN + STARTY, (x + curx) * LEN + STARTX + LEN, (y + cury) * LEN + STARTY + LEN); bar( (x + curx) * LEN + STARTX +1, (y + cury) * LEN + STARTY + 1, (x + curx) * LEN + STARTX + LEN - 2, (y + cury) * LEN + STARTY + LEN - 2); /* 以上将下落的盒子按昭它在地图上的坐标, 画到对应的区域里 */ for(y = 0; y 5; y+) /*画下一个 */ for(x = 0; x 5; x+) if(nextboxyx) rectangle( x * LEN + 320, y * LEN + 10, x * LEN + 338, y * LEN + 28); bar( x * LEN + 321, y * LEN + 11, x * LEN + 336, y * LEN + 26); 12 /* 这个画出下一个盒子的预览*/ setvisualpage(cPage); /*确认在 cPage页里画好了 */ /* 将它显示出来 */ 这样我们的初始化界面和盒子在图上的意义显示已经完成;5. 接下里我们要对即将出现的方块的形状进行预览即建立一个新的函数用来显示下一个下落的盒子; void rebuidNext() /*新建下一个形状并放到nextbox 中*/ int i, x, y; i = random(MAX_C); /*从几种方块里面选一种 */ for(y = 0; y 5; y+) /*并复制过来 */ for(x = 0; x 5; x+) nextboxyx = boxiyx; /*复制*/ void putBox() /*将 curbox 填充到地图上 */ int x, y; for(y = 0; y 5; y+) /*这个也简单 , 主要是要根 */ for(x = 0; x 5; x+) /*据 curx,cury指出位置 */ if(curboxyx) mapy + curyx + curx = curboxyx; int newfall() /*创建下落元素失败返回0*/ int x, y; curx = MAX_X / 2 - 2; /*重新指定小盒位置 */ cury = 0; for(y = 0; y 5; y+) for(x = 0; x 5; x+) curboxyx = nextboxyx;/*将 nextBox 复制过来 */ rebuidNext(); /*重建 nextBox*/ 13 return test(curx, cury, curbox); 这样一来,我们的预览盒子也就完成了。4. 完成以后,我们要进行下落的控制, 这个在开始的控制指针已经做好的下落间隔设置,然后开始随机出示方块,玩家应开始进行旋转,移动的操作, 下落的过程;void rotateBox(int box155, int box255) /* 旋转 box1 输出到 box2*/ int x, y; for(x = 0; x = 0; y-) /*编写一下才能印像深刻 */ box2yx = box1x4 - y; int rotate() /*整个旋转的操作并将盒子打印到屏幕上*/ int x, y; int newbox55; /*我们必须将当前盒子转动到新的盒子*/ /* 再对这个新的盒子的冲突作测试*/ rotateBox(curbox, newbox); /*转动到新的盒子 */ if(test(curx, cury, newbox) /* 并且新的盒子能放到地图上而不冲突*/ for(y = 0; y 5; y+) for(x = 0; x 5; x+) curboxyx = newboxyx; /*复制进来 */ return 1; else return 0; int move(int dir) /*返回成功与否 */ int newx; 14 if(dir) newx = curx + 1; /* 与 drop 一样, 准备移动后的坐标 */ else newx = curx - 1; if(test(newx, cury, curbox) /*测试是否冲突 */ curx = newx; /*可以的话切换 curx*/ return 1; return 0; 这个就完成了左右移动的操作;int drop() /*下落, 返回成功与否 */ int newy; /*盒子要下落的新位置 */ newy = cury + 1; /*为当前 Y位置+1*/ if(test(curx, newy, curbox) cury = newy; /*测试下落盒在这个位置 */ return 1; /*上是否有冲突 , 没有的话 */ /*直接设置 cury*/ return 0; int test(int mx, int my, int box55) /* 测试 box 在 map里 mx,my位置上是否能着陆 */ /* 这个是最关键的一个函数, 它判断是否产生非空冲突*/ /* 但算法还是很简单的 */ int x, y; for(y = 0; y 5; y+) for(x = 0; x 5; x+) if(mapy + myx + mx & boxyx) return 0; return 1; 15 这样就完成了旋转,移动,测试并下落的功能。6. 接下来我们要完成下落后的分数的改变速度的重新设定; void clear() /*清除掉满行 */ /*具体的算法为 : 从第 0 行开始到最后一行 , 测试地图点阵是否为满 , 如果是的话从当前行算起 , 之上的地图向下掉一行 */ int x, y; int dx, dy; int fullflag; for(y = 0; y MAX_Y - 2; y+) /*最后两行保留行 */ fullflag = 1; /*假设为满 */ for(x = 2; x 0; dy-) for(dx = 2; dx MAX_X - 2; dx+) mapdydx = mapdy - 1dx; for(dx = 2; dx MAX_X - 2; dx+) map0dx = 0; score+=10;/*输出新得分 */ /* 并清除掉第一行 */ void prscore()/*输出分数 */ char str10;setfillstyle(SOLID_FILL,YELLOW); 16 rectangle(90,15,260,35);setcolor(6); settextstyle(0,0,2);sprintf(str,score:%d,score); outtextxy(115,20,str); void spe()/*显示速度的改变 */ if(score%50=0&score!=0) setTimer(&tDown, speed-, 1); 7. 然后在主函数之前中定义以下的操作,这个应该会很容易理解 int mapMAX_Y+4MAX_X+4; /*地图 大盒子 .MAX_X,Y 是可见面积 */ /* 我已说过需要在外面布两圈 卫兵*/ int curbox55; /*当前下落的盒子 */ int curx, cury; /*保存着当前活动盒子在地图上的位置*/ int nextbox55; /*保存着下一个形状的盒子 */ 8. 接下俩用 newgame 函数将其串联起来,实现函数的内嵌; void newGame() /*新建游戏 */ int x, y; initMap(); /*初始化地图 */ srand(GetTickCount(); /*初始化随机发生器 */ rebuidNext(); /*建立下一个 */ setTimer(&tDown, speed, 1); /*启动时钟 ( 快慢两个 )*/ setTimer(&tFast, FAST_INTV, 1); newfall(); /*对下落的盒子操作一下 */ /* 这样第一个下落的方块就在地图顶部准备好了 */ 9. 接下来最为重要的主函数将要开始;int main() char key; /*记录当前按键 */ int i; int gd = VGA, gm = VGAMED; /*初始化的图形模式 */ Timer *ptDown; /*下落所指向的时钟 (有快慢 )*/ 17 Timer trender; /*为了避免渲染给程序造成过大的负担*/ /* 用一个时钟来控制渲染速度*/ /* 把它设置 interval = 1,*/ /* 这样就是 18 FPS了, 当然无法达到标 */ /* 准的 60 FPS. 毕竟这是 DOS.*/ setTimer(&trender, 1, 1); initgraph(&gd, &gm, ); /*初始化图形 */ newGame(); /*新游戏.*/ prscore(); while(1) /*主游戏循环 */ if(kbhit() /*如果键盘有按下 */ key = getch(); /*读取一个按键值到key*/ else key = 0; switch(key) /*对读到的 key 进行判断 */ case KEY_UP: rotate(); /*上, 旋转下落盒子 */ break; case KEY_DOWN: ptDown = &tFast; /*使用 tFast 时钟 */ break; case KEY_LEFT: move(0); /*左移*/ break; case KEY_RIGHT: move(1); /*右移*/ break; 18 case KEY_ESC: closegraph(); /*结束游戏 */ exit(0); default: ptDown = &tDown; /*使用原来速度 */ if(testTimer(ptDown) /*在上面已设置了下落要使用的时钟在 ptDown里*/ if(!drop() /*下落, 失败返回 0*/ putBox(); /*写到地图里 */ clear();prscore();spe();setcolor(6) ;/*清除满行 */ if(!newfall() /*新建下落 , 失败则游戏结束 */ setcolor(14); settextstyle(0,0,2); outtextxy(100,200,GAME OVER);/*游戏结束,在屏幕上打印字符串*/ outtextxy(100,240,THANK YOU); sleep(3); exit(0); if(testTimer(&trender) /*最后. 渲染.*/ render(); 10. 最后 main 函数已经介绍完毕, 只需在开始加上程序所需的头文件和值的宏定义后整个程序就全部完毕#include 19 #include #include /*这里须要读取系统运行时间来作为定时器*/ #include /*很不幸 ,TC2 的简单图形 , 让我放弃了用 */ #include /*win32+openGL来讲解 .*/ #define MAX_X 14 /*可见最大 X*/ #define MAX_Y 21 /*可见最大 Y*/ /* 我们定义了最大的可见X和 Y,那么即还有不可见的部分, 事实上地图 ( 大盒子 )里的左右两侧和底部各两行都被1 填充, 这样大大简化出界的判断 , 事实上 , 在本例中没有这样的代码 , 因为旁边有一圈 1 阻止小盒子越出大盒子的按制范围*/ #define MAX_C 7 /*最大种类 , 这个无须解释 */ #define FALSE 0 #define TRUE 1 到此为止,整个程序全部结束,详解到此完毕。四、调试分析20 1. 开始第一次运行时方块不能显示出来, 只能看到一个大白方框中几个空的白色的线,方块中间没东西, 并且这个虚方块下落时不能被控制,这是源于在初始化界面时并没有将方块内部进行填充,再加用一个setfillstyle()函数即可填充内部的空动,方块不能被控制是因为为未判断是否有键按下在main 函数中,若加上一个选择判断语句便可, char key; /*记录当前按键 */ if(kbhit() /*如果键盘有按下 */ key = getch(); /*读取一个按键值到key*/ 这样便可以解决问题。2. 运行后发现方块无法旋转, 并且反复块的出示有规律, 并不是随机的, 这个因为设定的函数有问题,重新修正后void rotateBox(int box155, int box255) /* 旋转 box1 输出到 box2*/ int x, y; for(x = 0; x = 0; y-) /*编写一下才能印像深刻 */ box2yx = box1x4 - y; 如此一来,将整个边线都逆度针旋转90度,便完成要求, 然后在 newgame 函数和 rubulid函数中中加上 rand()随机数的设置,编能使整个方块随机出示。3. 分数只是会闪一下, 但是并不能样一直显示, 并且速度不会随这分数的增加进行改变,功能不完善,原因在于prscore 函数应该在刚开始的绘图函数(即界面设置)中体现出来,然后才能将其体现到屏幕上,速度的设置在if(score%50=0&score!=0) speed-;操作中是不能起作用的, 不能单纯的进行 speed- ; 应该将其放在时针控制中, 所以应改为 if(score%50=0&score!=0) setTimer(&tDown, speed-, 1);这样既可完成每增加50 分进行速度的增加。4. 在终止程序时发生分数只能停留瞬间吗“game over”画面仅仅停留瞬间,这个只需在 main 函数结尾加上一个睡眠sleep ()即可;五、用户手册21 由于这个程序很简单,故玩家操作也很简单,再次就做个简单介绍:游戏开始,然后进入界面,方块自动下落,然后玩家用游戏键w a s d来控制左右移动和变换, w为方块的旋转, s 为加速下落, a与 d 就是方块的左右移动。完成满行的消去,分数的增加,若玩家操作不当,到达顶部,则游戏结束。22

    注意事项

    本文(c语言俄罗斯方块实验报告.pdf)为本站会员(33****8)主动上传,淘文阁 - 分享文档赚钱的网站仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知淘文阁 - 分享文档赚钱的网站(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    关于淘文阁 - 版权申诉 - 用户使用规则 - 积分规则 - 联系我们

    本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

    工信部备案号:黑ICP备15003705号 © 2020-2023 www.taowenge.com 淘文阁 

    收起
    展开