Windows编程大作业贪吃蛇设计与实现学校:武汉轻工大学院系:班级:姓名:学号:2015 年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关于SNAKE3.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;}Snake[50];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();Snake[0].x=10;Snake[0].y=10;Snake[1].x=11;Snake[1].y=10;Snake[2].x=12;Snake[2].y=10;Snake[0].direct=3;Snake[0].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;i<=Snake[0].len-1;i++)pDC->Rectangle(Snake[i].x*20,Snake[i].y*20,(Snake[i].x+1)*20,(Snake[i]. y+1)*20);pDC->SelectObject(DrawBrush);}3.3.2游戏开始点击游戏开始菜单后,出现一个对话框,提示一秒后,将开始游戏。
void CSNAKEView::OnStart(){// TODO: Add your command handler code hereSetTimer(1,1000,NULL);AfxMessageBox("1秒后开始游戏!");}3.3.3游戏暂停点击游戏暂停菜单后,出现显示“已暂停游戏”的对话框。
void CSNAKEView::OnPause(){// TODO: Add your command handler code hereKillTimer(1);AfxMessageBox("已暂停游戏");}3.3.4游戏退出点击游戏退出菜单,显示“退出游戏”的对话框,随后关闭游戏界面。
void CSNAKEView::OnExit(){// TODO: Add your command handler code hereAfxMessageBox("退出游戏...");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 cscs.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 hereCBrush 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 defaultswitch(nChar){case VK_UP:if(Snake[0].direct!=2)Snake[0].direct=1;break;//按上时,只要不是朝下,都将方向置为上(1)case VK_DOWN:if(Snake[0].direct!=1)Snake[0].direct=2;break;case VK_LEFT:if(Snake[0].direct!=4)Snake[0].direct=3;break;case VK_RIGHT:if(Snake[0].direct!=3)Snake[0].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 defaultCDC *pDC=GetDC();CString soure;if(Snake[0].len==2)SetTimer(1,370,NULL);if(Snake[0].len==3)SetTimer(1,270,NULL);if(Snake[0].len==6)SetTimer(1,200,NULL);if(Snake[0].len==9)SetTimer(1,100,NULL);soure.Format("得分:%d!",(Snake[0].len-3)*10);//撞界判断if(Snake[0].x*20<=37||Snake[0].y*20<=37||Snake[0].x*20>=462||Snake[0].y *20>=462){KillTimer(1);AfxMessageBox(soure);// s=0;}//蛇身相撞判断if(Snake[0].len>3)for(int sn=Snake[0].len-1;sn>0;sn--){if(Snake[0].x*20==Snake[sn].x*20&&Snake[0].y*20==Snake[sn].y*20){KillTimer(1);AfxMessageBox(soure);// s=0;}}/////////////////////////////////////////////////////////////////////// ////pDC->SelectStockObject(WHITE_PEN);pDC->Rectangle(Snake[Snake[0].len-1].x*20,Snake[Snake[0].len-1].y*20,(S nake[Snake[0].len-1].x+1)*20,(Snake[Snake[0].len-1].y+1)*20);for(int i=Snake[0].len-1;i>0;i--){Snake[i].x=Snake[i-1].x;Snake[i].y=Snake[i-1].y;}//运动方向判断if(Snake[0].direct==1)Snake[0].y--;if(Snake[0].direct==2)Snake[0].y++;if(Snake[0].direct==3)Snake[0].x--;if(Snake[0].direct==4)Snake[0].x++;pDC->SelectStockObject(BLACK_PEN);CBrush DrawBrush=(RGB(100,100,100));CBrush *Drawbrush=pDC->SelectObject(&DrawBrush);pDC->Rectangle(Snake[0].x*20,Snake[0].y*20,(Snake[0].x+1)*20,(Snake[0]. y+1)*20);pDC->SelectObject(DrawBrush);//判断吃食物的条件,撞到就吃if(Snake[0].x*20==Food.x*20&&Snake[0].y*20==Food.y*20){Snake[0].len++;Food.isfood=1;Snake[Snake[0].len-1].x=Snake[Snake[0].len-2].x;Snake[Snake[0].len-1].y=Snake[Snake[0].len-2].y;}//如果食物被吃了就生成if(Food.isfood==1){srand((unsigned)time(NULL));do{for(int isfo=Snake[0].len-1;isfo>=0;isfo--)if(Snake[0].x*20==Snake[isfo].x*20&&Snake[0].y*20==Snake[isfo].y*20){Food.x=rand()%25;Food.y=rand()%25;}}while(Food.x*20<70||Food.y*20<70||Food.x*20>430||Food.y*20>430);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()函数生成随机数,再控制坐标等变量实现“随机生成”功能。