课程设计报告-俄罗斯方块MFC_第1页
课程设计报告-俄罗斯方块MFC_第2页
课程设计报告-俄罗斯方块MFC_第3页
课程设计报告-俄罗斯方块MFC_第4页
课程设计报告-俄罗斯方块MFC_第5页
已阅读5页,还剩8页未读 继续免费阅读

付费下载

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

南京理工大学VC++课程设计报告PAGEPAGE3南京理工大学VC++课程设计报告课程:VC++课程设计系别:计算机科学与工程学院班级:91210xx学号:91210xx姓名:xxx选题1名称:俄罗斯方块(MFC版)选题1难易级别:选题2名称:选题2难易级别:自报成绩:A起止时间:9月3—9月22指导教师:严悍2013年9月目录1课题目标利用c++和mfc编写一个俄罗斯方块游戏,实现游戏在一个游戏窗口中显示,实现游戏等级的设定、背景音乐的播放、烟花效果、快捷键的使用和玩家对方块的各种操作等功能。2程序具体实现原理2.1总体方案首先应用mfc来绘制游戏的界面,然后把游戏的核心函数和代码封装在一个类中。在这个类中实现方块的绘制,方块的移动、翻转、消行等功能。用不同的消息响应函数来响应玩家的各种输入。为不同的资源定义不同的类来管理。最后在主对话框类中调用相应的函数,来实现游戏在对话框界面内的运行。2.1.1开发平台Windows7、VC++6.0、Photoshopcs62.1.2基本原理首先,打开游戏,进行游戏初始化。显示游戏的开始动画,播放背景音乐,背景音乐一直播放到窗口关闭。然后进入游戏的开始菜单界面,界面中有三个按钮,玩家可以根据自己的意愿选择按下按钮。当按下操作按钮时,显示操作说明。当按下设置按钮时,显示设置对话框,玩家可以选择游戏难度和是否显示烟花效果。当按下开始按钮,绘制游戏背景,边框以及随机产生方块。然后判断方块是否可以下落,若不可以则继续判断:是否可以消行,若是则消行加分,然后判断加分多少,并据此确定是否显示烟花;接着判断总分的多少,确定是否分数足够升级。若不能消行,则显示“Gameover”。若可以下落,则扫描玩家的按键,根据不同的按键执行不同的操作:当玩家按Esc键时,退出游戏,返回开始菜单界面。当玩家按向上键时,首先判断是否可以变形,若可以则方块在下落的同时顺时针旋转;若不可以则方块继续下落而不旋转。当玩家按向下键时,则方块直接下落到碰到底端或其他的方块。当玩家按向左向右键时,首先判断是否可以移位,若可以则方块在下落的同时向左移或向右移;若不可以则继续垂直下落。按键操作实现后,然后返回到判断是否可以下落处重复操作。在游戏的同时可以判断玩家是否按下快捷键:F2、F3、F4显示不同程度的烟花效果;F12则使方块下落速度加快,9级未满级。流程图如下:俄罗斯方块MFC版流程图Esc左右下上左右移位加速下落变形俄罗斯方块进入菜单,进行选择操作设置显示操作显示设置开始刷新界面,随机产生方块方块下落,扫描按键扫描按键是否可下落是否按下按键消行,计分游戏结束是是否是否是是2.2程序各个功能说明2.2.1程序结构由于我的程序是使用mfc写的,并且是基于对话框的应用程序,所以会自动生成CAboutDlg类,CSquareM1Dlg类以及CSquareM1App类。然后我又为游戏添加了两个对话框,分别是操作说明对话框和设置对话框,并且分别将它们与CDlgHelp类以及CDlgSet类相关联。然后我设计了GAMEBOX类,用来包含游戏中具体操作的函数,例如:变换,移动,产生方块,判断是否能移动等操作。我又添加了MYBITMAP类、MYBUTTON类来管理游戏中的位图,按钮以及对他们的操作。并且设置了MYCLOCK类,来实现游戏中的时钟处理。GAMEBOX类:类中函数有:public: GAMEBOX(); ~GAMEBOX(); voidShow();//显示图片 intCheck();//时钟处理 voidMouseMove(intx,inty);//鼠标移动处理 intLButtonUp(intx,inty);//鼠标单击 voidKeyProc(intiKey);//按键处理 voidInitFont();//初始化字体数组 voidShowInfoNow();//分数 voidClearMap();//清除数组 voidCreateNext();//创建新的方块public: voidBeginBomb(intisize);//初始化特效 voidShowBomb();//播放焰火 voidShowSet();//设置速度 voidShowHelp();//显示操作信息 voidShowFail();//显示gameover //旋转、移动 voidRotate(); voidMoveDown(); voidClearRow(); voidMoveRight(); voidMoveLeft(); voidPutSpare();//一个方块落底,写入数组 intCanMove();//是否能移动 voidCheckGame();//游戏中检测 voidShowSquare();//游戏中绘制 intiState;//游戏数据 //画笔,画刷 HBRUSHhBrush; HPENhPen,hPenWhite; //字体 HFONThf[10];intiAni;//动画 //游戏数据 intgamemap[20][10];structSQUAREsquareNow; structSQUAREsquareNext; intiSpeed;//游戏中的方块降落速度 intiTime; intiScore;//玩家数据 intiSpeedSet;//在设置菜单中,设置的速度 intiStartBomb; intiScene; structMAGICmagicobj[MAGIC_NUM]; intiScale;//粒子数量intiUseMagic;MYBITMAP类:类中函数有:public: MYBITMAP(); ~MYBITMAP(); //初始化 voidInit(HINSTANCEhInstance,intiResource); voidSetDevice(HDChdest,HDChsrc); //设置图像大小 voidInitSizeList(intnum,intw,inth); voidInitSizeList(intnum,intw,inth,intismask); voidInitSizeList(intnum,int*pw,int*ph,intismask); //显示 voidShow(intid,intx,inty); //去背显示 voidShowNoBack(intid,intx,inty); voidShowNoBack(intid,intx,inty,intframe); //拉伸显示 voidStretch(intid,intx,inty,intwdest,intydest);public: //位图句柄 HBITMAPhBm; // HDChdcdest; HDChdcsrc; //宽度高度纵坐标 intwlist[20]; inthlist[20]; intylist[20];};MYBUTTON类:类中函数有:public: MYBUTTON() ~MYBUTTON() voidInitButton(intnum,RECT*pRect);//初始化按钮矩形 voidShow(intid);//显示 intMouseOver(intx,inty);//鼠标检测 voidHide(intid);public: voidShow2(intid); voidHideAll(); intidMouseOver;//鼠标在哪一个按钮上 RECT*pRect; intiBtNum; intIsShow[10];//是否可见MYCLOCK类:类中函数有:public: MYCLOCK() ~MYCLOCK() intclockcount()//统计时间片 //计时:iNumClip变化过程0,1,2,...,24,0,1,2 intclipcount();//从0到24表示1秒 voidReStart(inttimetotal) { iNumDest=timetotal; iNumClip=0; } //windows定时器 voidInit(HWNDhWnd,inttimetotal) { SetTimer(hWnd,1,40,NULL);//每40ms刷新一次 iNumDest=timetotal; iNumClip=0; hWndClock=hWnd; } //显示 voidShow(HDChDC){ chartemp[20]={0}; sprintf(temp,"D%d,C%d",iNumDest,iNumClip); TextOut(hDC,50,50,temp,strlen(temp)); }public: intiNumClip; intiNumDest; clock_ttimenow; inttimeclip; //windows HWNDhWndClock;};2.2.2课程设计要求的实现1.游戏界面的绘制:游戏界面的绘制是用mfc中的函数实现的。首先将黑色画刷选入设备描述表内,然后用黑色画刷填充背景。然后设置画笔颜色为白色,用画笔在游戏背景上绘制矩形,将游戏界面分为三个区域:一是主游戏区,二是下一个方块提示区,三是文本区。然后用TextOut函数在特定位置显示分数以及速度。主要函数原型如下://黑色背景 SelectObject(hdccanvas,hBrush); SelectObject(hdccanvas,hPenWhite); Rectangle(hdccanvas,0,0,GAMEWIDTH,GAMEHEIGHT); // Rectangle(hdccanvas,20,18,244,462); Rectangle(hdccanvas,LEFT_RECT_X,LEFT_RECT_Y,242,460); //右上角 Rectangle(hdccanvas,RIGHT_RECT_X,RIGHT_RECT_Y, RIGHT_RECT_X+132,RIGHT_RECT_Y+132); ShowInfoNow();//分数,速度文字 ShowSquare();//方块 ShowBomb();//特效方块显示本游戏中一共有七种不同形状的方块,而方块的形成主要是使用GAMEBOX类的成员函数ShowSquare函数来实现的,函数定义如下:voidGAMEBOX::ShowSquare(){ inti; intx0,y0;//坐标原点 intm,n; //右上角显示下一个 x0=RIGHT_RECT_X+2*ITEM_EDGE; y0=RIGHT_RECT_Y+2*ITEM_EDGE; for(i=0;i<4;i++) { bmSquare.Show(squareNext.icolor, x0+squareNext.chip[i].x*ITEM_EDGE, y0+squareNext.chip[i].y*ITEM_EDGE); } //当前移动的方块 x0=LEFT_RECT_X+squareNow.pos.x*ITEM_EDGE; y0=LEFT_RECT_Y+squareNow.pos.y*ITEM_EDGE; if(squareNow.id!=INVALID) { for(i=0;i<4;i++) { //方块在界面内,则显示 if(squareNow.pos.y+squareNow.chip[i].y>=0) { bmSquare.Show(squareNow.icolor, x0+squareNow.chip[i].x*ITEM_EDGE, y0+squareNow.chip[i].y*ITEM_EDGE); } } } //已经放置的方块,20行,10列 for(m=0;m<20;m++) { for(n=0;n<10;n++) { if(VALID==gamemap[m][n]) { bmSquare.Show(PIC0, LEFT_RECT_X+n*ITEM_EDGE, LEFT_RECT_Y+m*ITEM_EDGE); } } }}方块变形俄罗斯方块的特点就在于通过方块的变形拼满整行来消去该行方块从而使游戏可以继续下去,很难想象不能变形的俄罗斯方块是什么样子。而变形的过程就是根据当前方块形状改变方块的相对位置,这样就可以改变方块的形状了。在程序中每当按下“↑”键,调用GAMEBOX类的成员函数Rotate函数来实现旋转,具体代码为:voidGAMEBOX::Rotate(){ inti; intm,n;//行列 intiCan=1; inttemp; //正方形不旋转 if(ID_SQAURE==squareNow.id) return; //判断是否能旋转 for(i=0;i<4;i++) { //旋转后的小块坐标 //旋转公式(x,y)旋转90度变为(-y,x),再加上当前位置 m=squareNow.pos.y+squareNow.chip[i].x; n=squareNow.pos.x-squareNow.chip[i].y; if(n<0||n>9 ||m<0||m>19 ||VALID==gamemap[m][n]) { iCan=0; break; } }//使用旋转公式 if(iCan) { for(i=0;i<4;i++) { temp=squareNow.chip[i].x; //旋转后的小块坐标 squareNow.chip[i].x=-squareNow.chip[i].y; squareNow.chip[i].y=temp; } }}方块移动游戏中方块的移动主要是调用GAMEBOX类的成员函数MoveLeft,MoveRight,Movedown来实现的,当玩家按下相应的按键时执行相应的操作。函数代码如下:voidGAMEBOX::MoveLeft(){ inti; intm,n;//行列 intiCan=1; for(i=0;i<4;i++) { m=squareNow.pos.y+squareNow.chip[i].y; n=squareNow.pos.x+squareNow.chip[i].x-1;//左移 if(n<0||VALID==gamemap[m][n]) { iCan=0; break; } } if(iCan) squareNow.pos.x--;}voidGAMEBOX::MoveRight(){ inti; intm,n;//行列 intiCan=1; for(i=0;i<4;i++) { //右移 m=squareNow.pos.y+squareNow.chip[i].y; n=squareNow.pos.x+squareNow.chip[i].x+1; if(n>9||VALID==gamemap[m][n]) { iCan=0; break; } } if(iCan) squareNow.pos.x++;}voidGAMEBOX::MoveDown(){ inti; for(i=0;i<19;i++) { if(!CanMove()) { return; } else { squareNow.pos.y++; } }}消行计分游戏玩家拼满一行后,游戏消去满行,并计分。当一个方块不能下落后,程序检查方块是否充满了游戏区域,如果是结束游戏。不是,则判断是否构成消行条件,从下落方块的最低点依次向上检查是否可以消行,根据消去行数分数增加。若消去行数在两行以上,则产生烟花特效。并且当分数达到一定程度,等级提升。程序中消行是通过调用GAMEBOX类的成员函数ClearRow来实现的,代码如下:voidGAMEBOX::ClearRow(){ inti; intm,n;//行列 intiNum; intiScoreRow[]={0,10,30,60,100};//分值,1行10分,2行30,3行60,4行100 intiRow;//消去多少行 iRow=0; //第19行,是最底一行 for(m=19;m>0;m--) { iNum=0; for(n=0;n<10;n++) { iNum+=gamemap[m][n]; } //消去一行 if(iNum==10) { iRow++;//统计消去多少行 for(i=m;i>0;i--) { //移动 memcpy(gamemap[i],gamemap[i-1],10*sizeof(int)); } memset(gamemap[0],0,10*sizeof(int)); m++;//重要,再次检测这一行 } if(iNum==0) { //空行,不再判断 break; } } iScore+=iScoreRow[iRow];//增加分数 if(iRow>=2) { //消除两行以上 BeginBomb(iRow); }}游戏退出在我的这个游戏中

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论