vc++贪吃蛇实习报告
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
贪吃蛇程序程序设计报告
【1】游戏介绍
产生一个固定大小有边界的游戏区域,蛇从区域的中心开始,由玩家通过键盘控制蛇的运动方向,用蛇头去吃随机分布在游戏区域内的食物;蛇的运动限制在游戏区域内,游戏区域有边界,所以蛇在区域内作循环运动;蛇的运动方向为直线运动,只走横和竖的方向,不走斜线;蛇身体的长度从4开始每吃掉一份食物就增加一个长度;食物的出现安照随机分布的原则,蛇吃掉一份后随即在游戏区域内放一份新的食物;每吃掉一份食物得分为1,游戏结束后统计全部的得分;游戏结束的条件为:在控制蛇的过程中蛇头碰到蛇的身体的任何部位或者碰到四壁。
【2】基本概念,要点分析
蛇的活动区域是由若干个小方格组成的。当这些小方格呈现灰色时,便显示蛇身。设整个区域由由m×n个方格组成,最左角上的方格坐标为(0,0),蛇由若干个相邻的方格组成的,将这些方格的坐标依蛇头至蛇尾的次序存入到一个数组中便代表了蛇身。当蛇在游戏区域中游动一格时,所对应的数组操作应该是将新的位置坐标插入到数组头部,同时将数组中最后一个元素删除,这项工作可以用一个一般的数组来完成,但当进行插入操作时需要自己移动数组中的元素;也可以使用CArray来完成这些工作,CArray的成员函数提供了需要的操作,这样做更简单一些。
游戏使用四个方向键来控制它的前进方向,在OnKeyDown消息处理函数中,根据不同的方向键设置成员变量m_nDirect的值。当在菜单中选择开始时,启动了定时器,游戏开始,在定时器消息处理函数中,根据m_nDirect的值判断出蛇的下个位置,如果没有超出边界或碰到自身,则它可以移到新的位置。如果吃到了食物,则在CArray中只插入而不删除最后一个元素,蛇身长度增加。
另外值得注意的是,当蛇移动一格时,只有蛇头和蛇身的位置需要重绘,为此专门编写了成员函数ReDisplay来刷新一个小格。
【3】程序概要设计
程序流程图如下:
【4】详细设计过程:
(1)新建工程Snake,在MFC的向导第一步选择Single Document,按Finishi结束。
(2)选择Resource View 窗口,打开菜单编辑器,在顶层菜单上添加一个名为“游戏”的弹出式菜单,该菜单下再添加一个名为“开始”的子菜单,其ID为ID_GAME_START,如下图所示。
(3)在ClassWizard中为刚才编辑好的菜单添加消息处理函数,打开ClassWizard,选中Message Maps 页。在Class Name中选择CSnakeView,在Object ID中选择ID_Game_START,在Messages中选择COMMAND,添加消息处理函数。
(4)在ClassWizard中添加键盘消息处理函数。打开ClassWizard,选中Message Maps 页。在Class Name中选择CSnakeView,在Object ID中选择CSnake View,在Messages中选择WM_KeyDown,添加消息处理函数。
(5)在ClassWizard中添加定时器消息处理函数。打开ClassWizard,选中Message Maps页。在Class Name中选择CSnakeView,在Object ID中选择CSnake View,在Messages 中选择WM_Timer , 添加消息处理函数。
(6)编辑生成代码,完成程序。
【5】利用MFC类向导添加代码步骤如下:
(1)选择Class View 窗口,双击CSnake View 类,添加如下成员变量。并添加头文件:
#include
class CSnakeView : public CView
{
private:
void ReDispilay(CPoint pPoint);
void IniAim();
void IniGame();
int m_nLeft,m_nTop,m_nWidth,m_nHeight,m_nSize; //起始坐标,宽高(格数0),每格大小
int m_nDirect; //当前方向
CPoint m_pAim; //当前坐标
CArray
int m_nGameStatus; //游戏状态:0-未开始,1-开始
int m_nCount; //吃掉目标数
int m_nTime,m_nTime1; //用掉的时间
protected: // create from serialization only
CSnakeView();
DECLARE_DYNCREATE(CSnakeView)
// Attributes
public:
CSnakeDoc* GetDocument();
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CSnakeView)
public:
virtual void OnDraw(CDC* pDC); // overridden to draw this view
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CSnakeView();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected:
// Generated message map functions
protected:
//{{AFX_MSG(CSnakeView)
afx_msg void OnGameStart();
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
afx_msg void OnTimer(UINT nIDEvent);
afx_msg void OnPaint();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
(2)在CSnakeView.Cpp文件中添加3个成员函数IniAim(),IniGame() 和ReDisplay()://该函数随机产生一个供蛇吃的目标,如果该目标恰巧与蛇身重合,则重新产生一个
void CSnakeView::IniAim()
{
int uX,uY; //目标位置
while(1)
{
uX=rand()%m_nHeight;
uY=rand()%m_nWidth;
int uTag=0;
for(int i=0;i<=m_aBody.GetUpperBound();i++)
{
CPoint uPoint=m_aBody.GetAt(i);