1、 2012 2013 学年 第 2 学期 课程名称 可视化编程 (VC) 学 院 计算机科学与技术学院 专 业 软件工程专业 班 级 姓 名 指导教师 1 目录 1、 课程设计要求 - 2 2、 系统功能实现与操作 - 2 3、 系统设计概述 - 2 3.1 添加结构体说明 - 2 3.2 模块说明 - 3 3.3 主要功能函数代码及注释 - 3 4、调试过程 -11 4.1添加功能说明 - 11 4.2错误及解决方案 - 11 5、 程序运行结果 - 12 附:主要类 Cview 的成员函数代码 -15 2 1、课程设计要求 题目:基于 MFC 的贪吃蛇游戏设计与实现。 要求: 1.游戏界面
2、设计 2.食物的初始化 3.游戏开始以及具体实现 2、系统功能实现与操作 本系统运用 API 函数的相关功能进行界面设计和功能实现。通过 Rectangle()函数绘制操作区域及障碍物。通过连续的小矩形实现蛇身的绘制。通过srand()函数和 rand()函数生成随机数,完成生成食物功能的实现。综合运用多种 if 条件判断和for 循环的嵌套使用的算法完成各种条件判断。 该系统功能简单,操作简易。打开程序后,点击菜单栏的游戏按钮,点击开始游戏,系统弹出对话框,提示还有 3 秒开始。游戏开始后,贪吃蛇开始移动,通过操作键盘上的上下左右方向键控制蛇的移动,躲避障碍物并吃掉食物。当吃掉的食物累计到达
3、一定数量后,蛇行速度加快。直至撞到边界或障碍物或撞到自身,游戏结束。此时弹出对话框,提示所得分数。游戏中途可通过暂停和继续按钮执行相应操作。 3、 系统设计概述 3.1 添加结构体说明 struct Snake int x,y; int len; int direct; Snake50; struct Food int x; int y; int food; Food; Snake 结构体数组用于存放贪吃蛇的相关数据,其中 x, y 存放当前节点矩形左上角的坐标,( Snake0为蛇头), len存放当前蛇身的长度, direct 存放蛇的行进方向,可在 14 取值。 3 Food 结构体用于
4、存放食物的位置信息。其中 x, y存放食物小矩形左上角左标, food 存放食物存在的布尔判断值。 3.2 模块说明 系统代码部分主要分为三个模块,界面控制模块、初始化模块和功能模块。 界面控制模块 包括函数: OnStart(), OnPause(), OnContinue(), OnExit() 初始化模块包括函数: OnInitialUpdate(), OnDraw(), oninit() 功能模块包括函数: OnKeyDown(), OnTimer() 3.3 主要功能函数代码及注释 OnStart() void CSnakeView:OnStart() / TODO: Add you
5、r command handler code here SetTimer(1,3000,NULL); AfxMessageBox(“还有 3 秒开始 ! “); 点击开始游戏触发,设置定时器控制三秒后开始游戏。 OnPause() void CSnakeView:OnPause() / TODO: Add your command handler code here KillTimer(1); AfxMessageBox(“不要让人家等太久 “); 关闭定时器,暂停游戏 OnContinue() void CSnakeView:OnContinue() / TODO: Add your com
6、mand handler code here SetTimer(1,10,NULL); 重启定时器,恢复游戏 4 OnExit() void CSnakeView:OnExit() / TODO: Add your command handler code here AfxMessageBox(“欢迎下次再来! “); exit(0); 弹出对话框提示退出。 OnInitialUpdate() void CSnakeView:OnInitialUpdate() CView:OnInitialUpdate(); / TODO: Add your specialized code here and
7、/or call the base class Snake0.x=10; Snake0.y=10; Snake1.x=10; Snake1.y=10; Snake2.x=10; Snake2.y=10; Snake0.direct=2; Snake0.len=3; Food.food=1;/初始化蛇的长度和位置 用这个函数进行蛇的初始化工作。 初始化贪吃蛇起初有 3 个节点,长度为 3,起始坐标 存入数组, 食物为 1 无 0 有 。 OnDraw() void CSnakeView:OnDraw(CDC* pDC) CSnakeDoc* pDoc = GetDocument(); ASSER
8、T_VALID(pDoc); / TODO: add draw code for native data here CBrush backBrush(RGB(111,111,111); CBrush* pOldBrush = pDC-SelectObject( CRect rect; pDC-GetClipBox( pDC-PatBlt(rect.left, rect.top, rect.Width(), rect.Height(),PATCOPY); pDC-SelectObject(pOldBrush); 5 pDC-Rectangle(9,9,401,401); CBrush zaBru
9、sh(RGB(111,111,111); pDC-SelectObject(zaBrush); for(int m=0;mRectangle(150,(100+m*10),160,(110+m*10); for(int n=0;nRectangle(250+n*10),200,(260+n*10),210); oninit(); 窗口创建时架构调用的函数,通过此函数完成界面初始化。创建灰色画刷选入设备环境,通过绘图函数绘制用户区。用两个 for 循环逐次绘制矩形的算法绘制出场景中的障碍物。 oninit() void CSnakeView:oninit() CDC *pDC=GetDC();
10、CBrush DrawBrush=(RGB(255,0,0); CBrush *Drawbrush=pDC-SelectObject( for(int i=0;iRectangle(Snakei.x*10,Snakei.y*10,(Snakei.x+1)*10,(Snakei.y+1)*10); pDC-SelectObject(DrawBrush); /利用 for 循环绘制起始的蛇身 该函数为自己添加的成员函数,用于绘制开始时的蛇身(长度为 3)。 OnKeyDown() void CSnakeView:OnKeyDown(UINT nChar, UINT nRepCnt, UINT nF
11、lags) / TODO: Add your message handler code here and/or call default switch(nChar) 6 case VK_UP:if(Snake0.direct!=2) Snake0.direct=1;break; 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.dire
12、ct=4;break; /通过键盘设置转头方向 CView:OnKeyDown(nChar,nRepCnt,nFlags); CView:OnKeyDown(nChar,nRepCnt,nFlags); 该函数为键盘消息的接收函数。从键盘得到的上下左右的不同按键,会根据switch判断语句的 case 改变 Snake。 direct 的值,从而改变蛇的行进方向。 OnTimer() void CSnakeView:OnTimer(UINT nIDEvent) / TODO: Add your message handler code here and/or call default CDC
13、*pDC=GetDC(); CString soure; int j=0; if(Snake0.len=3)SetTimer(1,170,NULL); if(Snake0.len=9)SetTimer(1,130,NULL); if(Snake0.len=14)SetTimer(1,95,NULL); if(Snake0.len=18)SetTimer(1,60,NULL); /根据蛇的长度进行速度的设定 soure.Format(“得分 :%d!“,(Snake0.len-3)*10); /设置每个食物 100 分 /撞墙判断 if(Snake0.direct=3)/用来控制直接结束当前函数
14、 KillTimer(1); AfxMessageBox(soure); /分四种情况撞障碍判断 ,k 为循环控制标识 - if(Snake0.direct=3) 7 for(int k=0;k3) for(int sn=Snake0.len-1;sn0;sn-) if(Snake0.x*10=Snakesn.x*10 KillTimer(1); AfxMessageBox(soure); 9 /对尾节点用白笔涂掉 if(j!=1) pDC-SelectStockObject(WHITE_PEN); pDC-Rectangle(SnakeSnake0.len-1.x*10,SnakeSnake
15、0.len-1.y*10,(SnakeSnake0.len-1.x+1)*10,(SnakeSnake0.len-1.y+1)*10); for(int i=Snake0.len-1;i0;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
16、); CBrush DrawBrush=(RGB(255,0,0); CBrush *Drawbrush=pDC-SelectObject( if(j!=1) pDC-Rectangle(Snake0.x*10,Snake0.y*10,(Snake0.x+1)*10,(Snake0.y+1)*10); pDC-SelectObject(DrawBrush); /判断吃食物的条件 if(Snake0.x*10=Food.x*10 Food.food=1; SnakeSnake0.len-1.x=SnakeSnake0.len-2.x; SnakeSnake0.len-1.y=SnakeSnake0.len-2.y; /生成食物 int o=1;/控制生成食物成功时跳出循环 if(Food.food=1)