MFC贪吃蛇小游戏Word格式.docx
《MFC贪吃蛇小游戏Word格式.docx》由会员分享,可在线阅读,更多相关《MFC贪吃蛇小游戏Word格式.docx(19页珍藏版)》请在冰豆网上搜索。
5.总结
时间安排:
消化资料、系统调查、形式描述1天
系统分析、总体设计、实施计划3天
撰写课程设计报告书1天
指导教师签名:
2010年月日
系主任(或责任教师)签名:
2010年月日
目录
1游戏说明4
2.功能描述4
3.重要的MFC4
4.总体设计说明6
4.1设计思路:
6
4.2程序框图6
4.2数据结构7
4.3主要算法8
5.代码实现8
6.运行结果14
7.小结16
8.参考文献17
MFC实现贪吃蛇小游戏
1游戏说明
贪食蛇是一个深受大众喜爱的简单游戏,玩家通过按键上的四个光标控制蛇的上下左右四个方向移动,蛇头碰撞到食物则表示食物被蛇吃掉,这时蛇的身长长一节,接着出现食物,等待被蛇吃掉,如果蛇在移动过程中,撞到墙壁或者身体交叉蛇头撞到自己的身体游戏结束。
游戏运行环境:
设计环境:
MicrosoftWindowsXP
开发工具:
VisualStudio2008
运行环境:
MicrosoftWindows XP及以上版本
2.功能描述
游戏规则如下:
●点击游戏->
开始菜单游戏开始;
●通过方向键控制蛇的运动方向,吃掉随机出现的豆子,若不小心碰到墙壁或者与自身相交,则该轮游戏结束;
●点击游戏->
暂停按钮,暂停游戏;
点击游戏->
继续菜单,继续游戏;
●点击设置->
难度菜单,设定游戏难易程度;
结束菜单退出游戏。
●单击帮助->
游戏规则查看游戏规则
3.重要的MFC
1.CWnd:
窗口,它是大多数“看得见的东西”的父类(Windows里几乎所有看得见的东西都是一个窗口,大窗口里有许多小窗口),比如视图CView、框架窗口CFrameWnd、工具条CToolBar、对话框CDialog、按钮CButton,etc;
一个例外是菜单(CMenu)不是从窗口派生的。
该类很大,一开始也不必学,知道就行了。
2. CDocument文档,负责内存数据与磁盘的交互。
最重要的是OnOpenDocument(读入),OnSaveDocument(写盘),Serialize(读写)
3. CView视图,负责内存数据与用户的交互。
包括数据的显示、用户操作的响应(如菜单的选取、鼠标的响应)。
最重要的是OnDraw(重画窗口),通常用CWnd:
:
Invalidate()来启动它。
另外,它通过消息映射表处理菜单、工具条、快捷键和其他用户消息。
你自己的许多功能都要加在里面,你打交道最多的就是它。
4. CDC设备文本。
无论是显示器还是打印机,都是画图给用户看。
这图就抽象为CDC。
CDC与其他GDI(图形设备接口)一起,完成文字和图形、图像的显示工作。
把CDC想象成一张纸,每个窗口都有一个CDC相联系,负责画窗口。
CDC有个常用子类CClientDC(窗口客户区),画图通常通过CClientDC完成。
5. CDialog对话框
6. CWinApp应用程序类。
似于C中的main函数,是程序执行的入口和管理者,负责程序建立、消灭,主窗口和文档模板的建立。
最常用函数InitInstance():
初始化。
7. CGdiObject及子类,用于向设备文本画图。
它们都需要在使用前选进DC。
8. CPen笔,画线
9. CBrush刷子,填充
10. CFont字体,控制文字输出的字体
11. CBitmap位图
12. CPalette调色板
13. CRgn区域,指定一块区域可以用于做特殊处理。
14. CFile文件。
最重要的不外是Open(打开),Read(读入),Write(
15. CString字符串。
封装了C中的字符数组,非常实用。
16. CPoint点,就是(x,y)对
17. CRect矩形,就是(left,top,right,bottom)
4.总体设计说明
在数据结构上,用数组存储蛇以及蛇的运动区域。
在数组中,每个元素有四个云感动方向,分别为RIGHT,LEFT,UP,DOWN.在没有蛇身的区域,数组的元素值为0。
在蛇身的每个节点,用一个数组元素存储当前蛇节点的运动方向。
通过改变数组中元素的值来表示蛇身的移动。
在程序中运用定时器来保证蛇的持续移动。
每个一定的时间间隔,蛇移动一格。
在设计界面时。
在VisualStudio2008的环境下,建立基于对话框的工程,在工程下设计游戏界面,实现贪食蛇运行算法。
在对话框中画出一个矩形,在大矩形中,用20x20的像素单位表示每一个蛇的节点。
当数组节点的值不为0的时候,在大矩形中画出相应的蛇的节点矩形。
并在蛇每移动一小格的时候,重绘整个窗口。
在对蛇身进行绘画时。
通过数组元素的值将蛇身在对话框的矩形中显示出来。
在蛇身运动时,首先在蛇头位置蛇身增长一个节点,然后判断蛇头是否到达食物所在位置,若在食物所在位置,则蛇尾不减一,蛇身继续移动,若蛇头不再食物位置,则蛇尾减一,蛇身继续移动。
若蛇头越界或者蛇头与蛇身重叠,则游戏结束。
4.2程序框图
1.游戏控制模块框图
2.“开始游戏”控制模块
moveSuccessful方法的流程图
4.2数据结构
在程序中定义一个蛇的类,结构如下:
classSnake
{
public:
//boolgameStart;
voidinitData();
//初始化蛇蛇的运动区域以及蛇身,蛇尾,
//蛇头
voidsetFood();
//随机产生食物的方法
boolmove(constint&
dir);
//蛇的移动方法
Snake();
//构造函数
virtual~Snake();
//析构函数
voidgame();
intm_SnakeMap[ROW][COL];
//存储蛇的运动区域,用表示蛇身不再此区
//域
boolm_gameStart;
//蛇开始运动标志
boolm_gameEnd;
//游戏结束
CPointm_Tail;
//蛇尾位置
CPointm_Head;
//蛇头位置
CPointm_Food;
//食物位置
intm_Dir;
//蛇的运动方向
intm_Time;
//通过改变m_Time的值改变蛇的运动速度,
//达到改变游戏难度的目的
};
另外程序中还有MFC自动生成的对话框类,不一一列出。
4.3主要算法
voidSnake:
initData()初始化SnakeApp的数据,设置蛇运动的区域。
设置蛇头,蛇尾,以及食物的位置。
boolSnake:
move(constint&
dir)
蛇的运动算法,当蛇运动时,蛇头没有碰壁或和没有和蛇身重叠时,返回true,否则,放回false。
当蛇头碰到食物时,蛇身增长一节。
setFood()
随机设置食物的位置,当食物与蛇头或蛇身重叠时,重新设置。
voidCSnake1Dlg:
OnKeyUp(UINTnChar,UINTnRepCnt,UINTnFlags)
通过键盘上的上下键控制蛇的运动方向。
OnPaint()
当对话框的显示发生改变时,重绘窗口
OnTimer(UINT_PTRnIDEvent)
定时器,在设定的时间执行move()函数。
5.代码实现
//随机放置食物
{
srand(time(NULL));
m_Food.x=rand()%ROW;
m_Food.y=rand()%COL;
//产生随机位置
while((m_SnakeMap[m_Food.y][m_Food.x])||(m_Head==m_Food))
//判断食物位置是否与蛇身重合
//若重合则重新生成新的位置
{
m_Food.x=rand()%ROW;
m_Food.y=rand()%COL;
}
}
//初始化数据
initData()
m_gameStart=true;
//游戏开始
m_gameEnd=false;
inti=0;
intk=0;
for(i=0;
i<
ROW;
i++)
for(k=0;
k<
COL;
k++)
{
m_SnakeMap[i][k]=0;
//初始化贪吃蛇运动区域
}
//初始化贪吃蛇的运动方向
m_SnakeMap[0][0]=RIGHT;
m_SnakeMap[0][1]=RIGHT;
//初始化蛇头位置
m_Head.x=2;
m_Head.y=0;
//初始化蛇尾
m_Tail.x=0;
m_Tail.y=0;
//随机放置食物
setFood();
//初始化蛇的运动方向
m_Dir=RIGHT;
//贪食蛇的移动函数
switch(dir)
caseRIGHT:
//方向向右m_SnakeMap[m_Head.y][m_Head.x]=RIGHT;
m_Head.x++;
break;
caseLEFT:
m_SnakeMap[m_Head.y][m_Head.x]=LEFT;
m_Head.x--;
caseUP:
m_SnakeMap[m_Head.y][m_Head.x]=UP;
m_Head.y--;
caseDOWN:
m_SnakeMap[m_Head.y][m_Head.x]=DOWN;
m_Head.y++;
default:
if(m_SnakeMap[m_Head.y][m_Head.x]||m_Head.x>
=ROW||m_Head.x<
0||m_Head.y<
0||m_Head.y>
=COL)
//蛇头碰壁或者与蛇身重叠,死//亡
m_gameEnd=true;
returnfalse;
if(m_Head==m_Food)
//吃到食物
m_Head=m_Food;
setFood();
returntrue;
else
inttemp=m_SnakeMap[m_Tail.y][m_Tail.x];
m_SnakeMap[m_Tail.y][m_Tail.x]=0;
switch(temp)
m_Tail.x--;
break;
m_Tail.x++;
m_Tail.y--;
m_Tail.y++;
//方向键控制蛇的运动方向
//TODO:
在此添加消息处理程序代码和/或调用默认值
switch(nChar)
//按↑键
caseVK_UP:
if(SnakeApp.m_Dir==UP||SnakeApp.m_Dir==DOWN)return;
KillTimer
(1);
//if(!
SnakeApp.move(UP))break;
SnakeApp.m_Dir=UP;
SetTimer(1,SnakeApp.m_Time,NULL);
caseVK_DOWN:
//按↓键
SnakeApp.move(DOWN))break;
SnakeApp.m_Dir=DOWN;
SetTimer(1,SnakeApp.m_Time,NULL);
caseVK_RIGHT:
//按→键
if(SnakeApp.m_Dir==LEFT||SnakeApp.m_Dir==RIGHT)return;
SnakeApp.move(RIGHT))break;
SnakeApp.m_Dir=RIGHT;
caseVK_LEFT:
//按←键
SnakeApp.move(LEFT))break;
SnakeApp.m_Dir=LEFT;
break;
CDialog:
OnKeyUp(nChar,nRepCnt,nFlags);
//窗口重绘函数,收到WM_PAINT消息重绘窗口
OnPaint()
if(IsIconic())
CPaintDCdc(this);
//devicecontextforpainting
SendMessage(WM_ICONERASEBKGND,(WPARAM)dc.GetSafeHdc(),0);
//Centericoninclientrectangle
intcxIcon=GetSystemMetrics(SM_CXICON);
intcyIcon=GetSystemMetrics(SM_CYICON);
CRectrect;
GetClientRect(&
rect);
intx=(rect.Width()-cxIcon+1)/2;
inty=(rect.Height()-cyIcon+1)/2;
//Drawtheicon
dc.DrawIcon(x,y,m_hIcon);
CDialog:
OnPaint();
CClientDCdc(this);
//画出蛇运动的矩形区域
dc.Rectangle(50,50,450,450);
//三个不同颜色的画刷
CBrushbrush(RGB(255,0,0));
CBrushbrush1(RGB(0,255,0));
CBrushbrush2(RGB(0,0,255));
CBrushbrush3(RGB(0,255,255));
dc.FillRect(CRect(50,50,450,450),&
brush3);
if(SnakeApp.m_gameStart)
if(SnakeApp.m_gameEnd)
//游戏结束
MessageBox("
很遗憾,游戏结束!
!
"
"
GameOver"
0);
return;
if(SnakeApp.m_gameEnd==false)
CBrush*pOldBrush;
pOldBrush=dc.SelectObject(&
m_Bsh[0]);
intxLeftTop,yLeftTop;
for(inti=0;
i<
++i)
{
for(intj=0;
j<
COL;
++j)
{
if(SnakeApp.m_SnakeMap[i][j])
{
//画出蛇身,绘为红色
xLeftTop=51+j*20;
yLeftTop=51+i*20;
dc.Rectangle(xLeftTop,yLeftTop,xLeftTop+19,yLeftTop+19);
dc.FillRect(CRect(xLeftTop,yLeftTop,xLeftTop+19,yLeftTop+19),&
brush);
}
}}
//brush=brush(RGB(0,255,0));
//画出蛇头,绘为绿色
xLeftTop=51+SnakeApp.m_Head.x*20;
yLeftTop=51+SnakeApp.m_Head.y*20;
dc.Rectangle(xLeftTop,yLeftTop,xLeftTop+19,yLeftTop+19);
dc.FillRect(CRect(xLeftTop,yLeftTop,xLeftTop+19,yLeftTop+19),&
brush1);
//画出食物,绘为蓝色
xLeftTop=51+SnakeApp.m_Food.x*20;
yLeftTop=51+SnakeApp.m_Food.y*20;
brush2);
}}}
6.运行结果
1.初始界面
2.开始游戏时的界面
3.游戏运行时界面
4游戏结束
7.小结
本次能力扩展训练,我选择了通过运用MFC程序设计来编写一个贪食蛇的程序。
在编写程序之前,我只有很少的关于MFC的程序设计知识,因此,在刚开始,我根本不知道从哪里下手开始解决我的问题。
因此,首先我查阅许多关于贪食蛇的资料,也在网上看了许多关于贪食蛇的算法。
做好了准备之后,才开始写我的贪食蛇。
但是,在完成能力拓展训练的过程中还是遇到了许多问题。
首先就是对于MFC不是很熟悉,在进行程序设计的过程中遇到了许多问题。
首先我遇到的第一个问题是如何将存储贪食蛇节点的数组与显示相结合起来。
在开始的两天,我一直没有能够解决这个问题,知道后来,我在网上查资料才找到一个比较好的解决方法。
通过将数组的下标和对话框汇中点的坐标关联起来,从而绘制贪食蛇的节点。
另一个问题是如何将菜单导入到对话框中,这个问题是通过请教MFC学的比较好的同学解决的。
另外我还在程序设计的过程中碰到了如何让蛇身隔在每个给定的时间间隔内移动一个的问题,这也是通过和同学讨论解决的。
以及这次能力拓展训练锻炼了我的动手能力。
通过完成贪食蛇游戏的程序设计,增加了我的实际编程经验。
提高了我独立解决问题的能力。
8.参考文献
[1]孙鑫.余安萍编著.VC++深入详解.北京.电子工业出版社.2007.11
[2]谭浩强.C++程序设计.北京.清华大学出版社.2004.06
[3]刘春辉.徐建飞编著.VisualC++程序设计学习笔记.北京.电子工业出版社.2008.05
[4]CharlesPetzold著.Windows程序设计(第五版).北京.北京大学出版社.1999.03
本科生课程设计成绩评定表
班级:
软件工程0704班 姓名:
彭圣龙 学号:
序号
评分项目
满分
实得分
1
学习态度认真、遵守纪律
10
2
设计分析合理性
3
设计方案正确性、可行性、创造性
20
4
设计结果正确性
40
5
设计报告的规范性
6
设计验收
总得分/等级
评语:
注:
最终成绩以五级分制记。
优(90-100分)、良(80-89分)、中(70-79分)、
及格(60-69分)、60分以下为不及格
指导教师签名:
2010年 7月 日