贪吃蛇游戏程序设计实验报告.docx
贪吃蛇游戏程序设计实验报告 Windows编程大作业贪吃蛇设计与实现 学校:武汉轻工大学 院系: 班级: 姓名: 学号: 2022 年12月16日 目录 一、题目介绍 二、设计目的 三、详细设计 3.1贪吃蛇本体设计 3.2贪吃蛇食物设计 3.3游戏界面设计 3.3.1游戏初始化 3.3.2游戏开始 3.3.3游戏暂停 3.3.4游戏退出 3.3.5游戏总界面 3.3.6游戏区域与背景 3.3.7关于SNAKE 3.4玩法规则设计 3.5核心设计 四、功能测试 五、总结 六、参考文献 一、题目介绍: 编写一个基于MFC的小游戏。 基本要求: 1、实现一个小游戏 2、实现基本游戏控制功能 3、具有游戏数据保存功能 4、界面布局合理、美观; 二、设计目的: 通过使用vc+6.0实现一个小游戏的课程设计,进一步掌握MFC的高级使用方法和锻炼自己动手写程序的能力。了解游戏设计的整个过程,通过熟练使用MFC来设计游戏。程序主要包括:游戏界面设计,游戏菜单栏设计,游戏初始化,游戏控制等。培养和锻炼开发游戏的能力。 三、详细设计 3.1贪吃蛇的本体设计 贪吃蛇的头部拥有一个坐标(x,y),蛇体有一个长度len,蛇有一个运动方向direct,故定义一个结构体如下: struct Snake int x,y; int len; int direct; Snake50; 3.2贪吃蛇食物设计 贪吃蛇的食物有一个坐标(x,y),此食物有一个标志isfood,当isfood为0时,表示食物还没被吃,为1时,表示被吃。 struct Food int x; int y; int isfood; Food; 3.3游戏界面设计 3.3.1游戏初始化 游戏初始蛇体长度为3,颜色为灰色,食物标志为1,因为此时没有显示出食物,需要随机生成后,才置为0; void CSNAKEView:OnInitialUpdate() CView:OnInitialUpdate(); Snake0.x=10; Snake0.y=10; Snake1.x=11; Snake1.y=10; Snake2.x=12; Snake2.y=10; Snake0.direct=3; Snake0.len=3; Food.isfood=1;/初始化贪吃蛇起初有3个节点,长度为3,起始坐标;食物默认为1无0有 / TODO: Add your specialized code here and/or call the base class void CSNAKEView:oninit() CDC *pDC=GetDC(); CBrush DrawBrush=(RGB(100,100,100); CBrush *Drawbrush=pDC->SelectObject(&DrawBrush); for(int i=0;iRectangle(Snakei.x*20,Snakei.y*20,(Snakei.x+1)*20,(Snakei.y+1)*20); pDC->SelectObject(DrawBrush); 3.3.2游戏开始 点击游戏开始菜单后,出现一个对话框,提示一秒后,将开始游戏。 void CSNAKEView:OnStart() / TODO: Add your command handler code here SetTimer(1,1000,NULL); AfxMessageBox("1秒后开始游戏!"); 3.3.3游戏暂停 点击游戏暂停菜单后,出现显示“已暂停游戏”的对话框。 void CSNAKEView:OnPause() / TODO: Add your command handler code here KillTimer(1); AfxMessageBox("已暂停游戏"); 3.3.4游戏退出 点击游戏退出菜单,显示“退出游戏”的对话框,随后关闭游戏界面。 void CSNAKEView:OnExit() / TODO: Add your command handler code here AfxMessageBox("退出游戏."); exit (0); 3.3.5游戏总界面大小设计 使用CMainFrame的PreCreateWindow函数对总界面进行初始化。 BOOL CMainFrame:PreCreateWindow(CREATESTRUCT& cs) if( !CFrameWnd:PreCreateWindow(cs) ) return FALSE; / TODO: Modify the Window class or styles here by modifying / the CREATESTRUCT cs cs.style &= WS_OVERLAPPED; cs.cy = 615; cs.cx = 530; return TRUE; 3.3.6操作游戏界面大小及背景色设计 将背景色设置为黑色,并将游戏区域显示出来。 void CSNAKEView:OnDraw(CDC* pDC) CSNAKEDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); / TODO: add draw code for native data here CBrush backBrush(RGB(0,0,0);/设置画刷为希望的背景色 CBrush* pOldBrush = pDC->SelectObject(&backBrush);/保存旧画刷 CRect rect; pDC->GetClipBox(&rect);/擦除需要的区域 pDC->PatBlt(rect.left, rect.top, rect.Width(), rect.Height(),PATCOPY);/用创建的画刷绘制背景区域 pDC->SelectObject(pOldBrush); pDC->Rectangle(19,19,501,501);/设置需要区域的起始坐标和长宽。 oninit(); 3.3.7版权所有 点击帮助中的关于SNAKE,或者点击,会显示对话框-版权归刘坤炜所有。 3.4玩法规则设计 当按键盘上的“上”“下”“左”“右”键时,蛇体方向的改变。按“上”时,如果蛇的方向不是朝下的,就将direct方向置为1,使其向上运动,当然如果本身就是向上运动的,那么蛇的运动方向没有变化;如果蛇的方向朝下,按上,则不能改变它的方向。其他按法与上类似。 void CSNAKEView:OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags) / TODO: Add your message handler code here and/or call default switch(nChar) case VK_UP:if(Snake0.direct!=2)Snake0.direct=1;break;/按上时,只要不是朝下,都将方向置为上(1) case VK_DOWN:if(Snake0.direct!=1)Snake0.direct=2;break; case VK_LEFT:if(Snake0.direct!=4)Snake0.direct=3;break; case VK_RIGHT:if(Snake0.direct!=3)Snake0.direct=4;break; CView:OnKeyDown(nChar, nRepCnt, nFlags); 3.5游戏核心设计 当碰到白色区域的任何一边或者自己撞到自己的身体时,游戏结束,并输出自己所得分数。根据蛇的运动方向来改变蛇的一个个身体部分坐标。根据蛇头的坐标来判断是否吃到了食物,若吃到,将蛇的长度加1,食物的标志置为1,表示被吃,并且当食物标志为1时,随机生成下一个食物的坐标,此坐标必须要在游戏区域内,不在就循环生成,直到满足条件,并将标志置为0。 void CSNAKEView:OnTimer(UINT nIDEvent) / TODO: Add your message handler code here and/or call default CDC *pDC=GetDC(); CString soure; if(Snake0.len=2)SetTimer(1,370,NULL); if(Snake0.len=3)SetTimer(1,270,NULL); if(Snake0.len=6)SetTimer(1,200,NULL); if(Snake0.len=9)SetTimer(1,100,NULL); soure.Format("得分:%d!",(Snake0.len-3)*10); /撞界判断 if(Snake0.x*20=462) KillTimer(1); AfxMessageBox(soure); / s=0; /蛇身相撞判断 if(Snake0.len>3) for(int sn=Snake0.len-1;sn>0;sn-) if(Snake0.x*20=Snakesn.x*20&&Snake0.y*20=Snakesn.y*20) KillTimer(1); AfxMessageBox(soure); / s=0; / / pDC->SelectStockObject(WHITE_PEN); pDC->Rectangle(SnakeSnake0.len-1.x*20,SnakeSnake0.len-1.y*20,(SnakeSnake0.len -1.x+1)*20,(SnakeSnake0.len-1.y+1)*20); for(int i=Snake0.len-1;i>0;i-) Snakei.x=Snakei-1.x; Snakei.y=Snakei-1.y; /运动方向判断 if(Snake0.direct=1)Snake0.y-; if(Snake0.direct=2)Snake0.y+; if(Snake0.direct=3)Snake0.x-; if(Snake0.direct=4)Snake0.x+; pDC->SelectStockObject(BLACK_PEN); CBrush DrawBrush=(RGB(100,100,100); CBrush *Drawbrush=pDC->SelectObject(&DrawBrush); pDC->Rectangle(Snake0.x*20,Snake0.y*20,(Snake0.x+1)*20,(Snake0.y+1)*20); pDC->SelectObject(DrawBrush); /判断吃食物的条件,撞到就吃 if(Snake0.x*20=Food.x*20&&Snake0.y*20=Food.y*20) Snake0.len+; Food.isfood=1; SnakeSnake0.len-1.x=SnakeSnake0.len-2.x; SnakeSnake0.len-1.y=SnakeSnake0.len-2.y; /如果食物被吃了就生成 if(Food.isfood=1) srand(unsigned)time(NULL); do for(int isfo=Snake0.len-1;isfo>=0;isfo-) if(Snake0.x*20=Snakeisfo.x*20&&Snake0.y*20=Snakeisfo.y*20) Food.x=rand()%25; Food.y=rand()%25; while(Food.x*20430); pDC->Rectangle(Food.x*20,Food.y*20,(Food.x+1)*20,(Food.y+1)*20); Food.isfood=0; CView:OnTimer(nIDEvent); 四、功能测试 4.1游戏界面 4.2游戏开始 4.3游戏正在进行 4.4游戏暂停 4.5游戏退出 4.6最后得分 4.7关于SNAKE 五、总结 随机数生成函数rand()的应用在贪吃蛇游戏中是一个关键步骤,通过不断的循环和调用,能保证游戏的持续进行和更新,其实不止是贪吃蛇,在大多数需要随机生成元素的游戏中,都可以用rand()函数生成随机数,再控制坐标等变量实现“随机生成”功能。 通过这一次课程设计,我最大的收获就是分析问题解决问题能力的提高,发现问题,而后解决问题是生活的永续循环,这种能力会伴随我们一生;其次,程序的开发给了我很多经验,相信时间充裕的话,我能独立开发一个小游戏;最后,老师提出的对设计报告的种种要求也为我以后的各种报告的规范性做好了心理准备。 总的来说MFC程序使用了微软的基本类库,让程序设计变得简单,但是一定程度上造成了代码冗余,程序效率降低,MFC入门简单,但提升有一定难度。MFC只是C+的一部分,我并没有写了过多的C+代码,很多代码是很相似的,可能因为我是初学者的缘故,另外我比较喜欢对C+模板类或者可重用的类的设计,这更符合C+批量成产的风格。