需要源码和资源请点赞关注收藏后评论区留言私信~~~

一、主游戏类的设计

主游戏类主要负责贪吃蛇及果实的显示和更新

果实出现的设计思路如下

1:采用随机数生成果实并出现坐标

2:判断当前生成的果实坐标是否在贪吃蛇身体范围内

3:如果在,重新生成直到不在为止,如果不在,则把坐标位置返回给调用对象

主游戏类的声明中包含了绘制蛇身函数,初始化游戏函数,随机分配果实函数以及设置当前游戏等级函数等的声明,代码如下

#ifndef __SNAKE_GAME_H__
#define __SNAKE_GAME_H__
//主游戏类#include "Afxtempl.h"       //插入模板头文件#define GAME_LEVEL_LOW  2
#define GAME_LEVEL_NOR  4
#define GAME_LEVEL_HIGH 8#define DIREC_UP   1
#define DIREC_DOWN  2
#define DIREC_RIGHT 3
#define DIREC_LEFT  4#define LOW_LEVEL_SLEEP        100
#define NOR_LEVEL_SLEEP     50
#define HIGH_LEVEL_SLEEP    30class CSnakeGame:public CWnd
{
public:void HeroWrite();void ReDrawBody(CPoint pt);void InitGame();CSnakeGame();virtual ~CSnakeGame();BOOL GameStart();     //游戏开始函数void InitFoods();       //初始化果实函数void SetGameLevel(int level);private:CPoint    m_psFood;       //当前食物坐标int     m_nDirect;      //当前蛇先进方向int        m_nScore;       //当前游戏分数int     m_nlevel;       //当前游戏等级int     m_nHighScore;   //当前游戏最高分CArray<CPoint,CPoint> m_body;    //蛇身向量
protected:afx_msg void OnPaint();afx_msg void OnTimer(UINT nIDEvent);afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags);DECLARE_MESSAGE_MAP()
};#endif

通过前面类的声明,已经知道主游戏类中包含的几个基本函数,如构造,析构,绘图和接收键盘输入等,这些函数是主游戏窗口类基础,用于构成对话框,处理图片的显示以及人机交互过程

#include "stdafx.h"
#include "SnakeGame.h"
#include "Resource.h"
#include "Rule.h"
#include "HeroDlg.h"CSnakeGame::CSnakeGame()
{m_nScore = 0;m_psFood.x = 30;m_psFood.y = 30;m_nHighScore = 0;
}CSnakeGame::~CSnakeGame()
{
}// 消息映射表
BEGIN_MESSAGE_MAP( CSnakeGame, CWnd )
//{{AFX_MSG_MAP(CSnakeGame)
ON_WM_PAINT()
ON_WM_TIMER()
ON_WM_KEYUP()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
//
// 初始化果实
//
void CSnakeGame::InitFoods()
{   int m_ysX,m_ysY;while(1){m_ysX=rand()%28;          //随机生成横坐标使其与贪吃蛇的身体可以接上m_ysY=rand()%28;          //随机生成纵坐标使其与贪吃蛇的身体可以接上for(int i=0;i<=m_body.GetUpperBound();i++){CPoint ysPoint1=m_body.GetAt(i);      //获取贪吃蛇的身体坐标if(ysPoint1.x!=m_ysX||ysPoint1.y!=m_ysY)//如果身体的横坐标或纵坐标与果实的横纵坐标相同{m_psFood = CPoint(m_ysX, m_ysY);//将随机出现的坐标记录为果实坐标return;}}}
}
//
// 设置游戏等级
//
void CSnakeGame::SetGameLevel(int level)
{m_nlevel = level;
}
//
// 开始游戏函数
//
BOOL CSnakeGame::GameStart()
{int nSleep = LOW_LEVEL_SLEEP;char pszTmp[128] = {0};switch(m_nlevel){case GAME_LEVEL_HIGH:nSleep = HIGH_LEVEL_SLEEP;break;case GAME_LEVEL_NOR:nSleep = NOR_LEVEL_SLEEP;break;}GetPrivateProfileString("HERO", "score", "0", pszTmp, 127, ".\\hero.ini");m_nHighScore = atoi(pszTmp);SetTimer(1, nSleep, NULL);InitGame();return TRUE;
}//
// 处理WM_PAINT消息
//
void CSnakeGame::OnPaint()
{CPaintDC dc( this );CDC MemDC;MemDC.CreateCompatibleDC( &dc );// 装载背景CBitmap bmp;CPen pen;bmp.LoadBitmap( IDB_BMP_BJ );pen.CreatePen( PS_SOLID, 1, 0xff );MemDC.SelectObject( &bmp );MemDC.SelectObject( &pen );MemDC.SetROP2( R2_NOTXORPEN );CString ysStr;                            //定义字符串用于显示游戏时间得分等字MemDC.SetBkMode(TRANSPARENT);             //设置字体背景MemDC.SetTextColor(67);                   //设置字体颜色ysStr.Format("当前得分:%d",m_nScore);     //初始化字符串MemDC.TextOut(30,50,ysStr);               //输出文本switch(m_nlevel)                     //根据等级判断{case GAME_LEVEL_LOW:                                   //如果是初级ysStr.Format("当前等级:  初 级");break;case GAME_LEVEL_NOR:                                   //如果是中级ysStr.Format("当前等级:  中 级");break;case GAME_LEVEL_HIGH:                                   //如果是高级ysStr.Format("当前等级:  高 级");break;}MemDC.TextOut(30,30,ysStr);//绘制蛇的样式CPen yspen;                          yspen.CreatePen(1,1,RGB(255,255,255));   //定义白色画笔绘制蛇的边框MemDC.SelectObject(&yspen);                CBrush ysbrush;//int k=m_body.GetUpperBound()+2;         //设置一个变量存储贪吃蛇的身体长度if(k<=10)                                 //如果小于10,那么就为绿色{ysbrush.CreateSolidBrush(RGB(0,255,0)); MemDC.SelectObject(&ysbrush);//绘制果实MemDC.Rectangle(CRect(10+m_psFood.y*10,120+m_psFood.x*10,10+(m_psFood.y+1)*10,120+(m_psFood.x+1)*10));}else if(k>10&&k<=20)                      //如果在10和20之间,那么就为绿色{ysbrush.CreateSolidBrush(RGB(0,0,255)); MemDC.SelectObject(&ysbrush);//绘制果实MemDC.Rectangle(CRect(10+m_psFood.y*10,120+m_psFood.x*10,10+(m_psFood.y+1)*10,120+(m_psFood.x+1)*10));}else if(k>20&&k<=30)                      //如果在20和30之间,那么就为绿色{ysbrush.CreateSolidBrush(RGB(255,255,0)); MemDC.SelectObject(&ysbrush);//绘制果实MemDC.Rectangle(CRect(10+m_psFood.y*10,120+m_psFood.x*10,10+(m_psFood.y+1)*10,120+(m_psFood.x+1)*10));}else                                       //其余情况均为红色{ysbrush.CreateSolidBrush(RGB(255,0,0)); MemDC.SelectObject(&ysbrush);//绘制果实MemDC.Rectangle(CRect(10+m_psFood.y*10,120+m_psFood.x*10,10+(m_psFood.y+1)*10,120+(m_psFood.x+1)*10));}//初始化点数组for(int i=0;i<=m_body.GetUpperBound();i++){CPoint ysPoint=m_body.GetAt(i);       MemDC.Rectangle(CRect(10+ysPoint.y*10,120+ysPoint.x*10,10+(ysPoint.y+1)*10,120+(ysPoint.x+1)*10));}dc.BitBlt( 0, 0, 325, 425, &MemDC,0, 0, SRCCOPY );}
//
// 处理按键消息
//
void CSnakeGame::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
{switch(nChar){case VK_UP:                   //按向上键m_nDirect=DIREC_UP;       //控制方向变量为DIREC_UPbreak;case VK_DOWN:                 //按向下键m_nDirect=DIREC_DOWN;     //控制方向变量为DIREC_DOWNbreak;case VK_LEFT:                 //按向左键m_nDirect=DIREC_LEFT;     //控制方向变量为DIREC_LEFTbreak;case VK_RIGHT:                //按向右键m_nDirect=DIREC_RIGHT;    //控制方向变量为DIREC_RIGHTbreak;default:break;}
}
//
// 定时器响应函数
//
void CSnakeGame::OnTimer(UINT nIDEvent)
{CPoint ysPoint=m_body.GetAt(0);     //获取蛇身的第一个点坐标BOOL bTag = FALSE;                   //定义判断死亡的变量CRule rule;                          //游戏规则类switch(m_nDirect)                     //根据键盘按下键来选择蛇移动的方向{case DIREC_DOWN:                       //方向变量向下ysPoint.x++;                      //点纵坐标自加break;case DIREC_UP:                         //方向变量向上ysPoint.x--;                      //点纵坐标自减break;case DIREC_RIGHT:                      //方向变量向右ysPoint.y++;                      //点横坐标自加break;case DIREC_LEFT:                       //方向变量向左ysPoint.y--;                      //点横坐标自减break;}if(rule.IsOver(ysPoint, m_body))      //游戏结束{KillTimer(1);                        //关闭定时器if(m_nScore > m_nHighScore)           //超过最高分{HeroWrite();                    //写英雄榜}else{AfxMessageBox("游戏结束,你的分数太低了,没有能进入英雄榜");}}else{m_body.InsertAt(0,ysPoint);    //将新点添加到蛇的身体中ReDrawBody(ysPoint);           //重绘蛇的身体if(ysPoint.x==m_psFood.x&&ysPoint.y==m_psFood.y) //如果蛇的身体与果实坐标重合{int nlen=m_body.GetUpperBound();//获取蛇身体的长度m_nScore = m_nlevel * (nlen-3);//统计分数InitFoods();                 //再出现下一个果实Invalidate();                 //窗口重绘}else{CPoint pt=m_body.GetAt(m_body.GetUpperBound());//将最后一个赋给ptm_body.RemoveAt(m_body.GetUpperBound());       //将移出最后一个ReDrawBody(pt);                                //重新绘制pt这点}}
}
//
// 初始化游戏
//
void CSnakeGame::InitGame()
{m_body.RemoveAll();m_body.Add(CPoint(3, 8));m_body.Add(CPoint(3, 7));m_body.Add(CPoint(3, 6));m_body.Add(CPoint(3, 5));srand((unsigned)time(NULL)); //初始化随机数生成器m_nDirect = DIREC_RIGHT;    //初始时向右m_nScore  = 0;              //初始化分数InitFoods();                 //初始化果实函数Invalidate();                //重绘窗口
}
//
//重绘指定点
//
void CSnakeGame::ReDrawBody(CPoint pt)
{InvalidateRect(CRect(10+pt.y*10,120+pt.x*10,10+(pt.y+1)*10,120+(pt.x+1)*10));
}
//
// 英雄榜写入及弹出
//
void CSnakeGame::HeroWrite()
{CHeroDlg dlg;dlg.SetWriteFlg(TRUE);        //设置可标志dlg.m_level = m_nlevel;     //设置等级dlg.m_score = m_nScore;      //设置分数dlg.DoModal();                //弹出对话框
}

二、游戏规则类的实现

游戏规则类,主要负责游戏规则的处理,在贪吃蛇游戏中,主要有如下两种规则需要实现

1:当贪吃蛇碰到四周的边界时,认定贪吃蛇死亡,游戏结束

2:当贪吃蛇碰到自己的身体时,认定贪吃蛇死亡,游戏结束

要实现这两个规则,只需要对贪吃蛇的行走路径进行判断,每走一步时对当前蛇头位置进行判断,如果蛇头的坐标超出边界或者与贪吃蛇BODY向量中的某个坐标数据相同时,就认定贪吃蛇死亡

游戏规则类实现代码如下

#ifndef __RULE_H__
#define __RULE_H__#include <afxtempl.h>#define MAX_POINT 29
#define MIN_POINT 0class CRule
{
public:BOOL IsOver(CPoint &pt, CArray<CPoint, CPoint> &body);     //判断当前点是否为游戏结束};#endif 

在游戏规则类的游戏结束判断接口函数中,通过如下办法实现L:

先对当前蛇身数组进行遍历,判断如果其中有一个纵坐标多余最下端边框或者少于最上端边框,则说明游戏结束,再判断如果其中有一个横坐标多余最右端边框或者最左端边框,也说明游戏结束,如果都不是就直接返回不是游戏结束,代码如下

#include "stdafx.h"
#include "Rule.h"BOOL CRule::IsOver(CPoint &pt, CArray<CPoint, CPoint> &body)
{if(pt.x>=MAX_POINT || pt.x<MIN_POINT)                 //如果纵坐标多于最下端边框或者少于最上端边框{return TRUE;                      //判断死亡}else if(pt.y>=MAX_POINT || pt.y<MIN_POINT)           //横坐标多于最右端边框{return TRUE;                      //判断死亡}for(int i=0;i<=body.GetUpperBound();i++){CPoint pt1 = body.GetAt(i);     //将蛇身体的坐标传递给新定义的点if(pt.x==pt1.x&&pt.y==pt1.y)   //如果两点完全相同,说明蛇碰到身体{return TRUE;                 //判断死亡}}return FALSE;
}

创作不易 觉得有帮助请点赞关注收藏~~~

Visual C++实现贪吃蛇游戏项目实战三:核心算法设计与实现(附源码和资源 可用于大作业)相关推荐

  1. Visual C++实现黑白棋游戏实战三:核心算法设计与实现(附源码和资源 可用于大作业)

    需要源码和资源请点赞关注收藏后评论区留言私信~~~ 在前面的博客中已经讲解了黑白棋游戏的菜单和各种对话框的实现,下面将对黑白棋游戏的核心算法的设计和实现进行讲解 一.棋盘窗口类的设计 黑白棋的棋盘窗口 ...

  2. Visual C++黑白棋游戏项目开发一:需求分析、系统架构设计(附源码和资源 可用于大作业)

    需要源码和资源请点赞关注收藏后评论区留言私信~~~ 一.黑白棋需求分析 黑白棋,游戏通过相互反转对方的棋子,最后以棋盘上谁的棋子多来判断胜负,其游戏规则比较简单,因此很容易学会,但是变化却又非常复杂, ...

  3. 【C#+SQL Server】实现模仿QQ的交友软件 三:申请账号窗体设计讲解(附源码和资源)

    需要源码和资源请点赞关注收藏后评论区留言私信~~~ 其他几个部分文章链接如下 [C#+SQL Server]实现模仿QQ的交友软件 一:系统简介.功能展示与数据库设计(附源码和资源) [C#+SQL ...

  4. Python自制游戏:还原经典款贪吃蛇,表弟玩着玩着都哭了(附源码)

    文章目录 一.写在前面 二.准备工作 1.用到的软件 2.用到的模块 三.来吧 展示 四.效果 五.打包成exe可执行文件 一.写在前面 贪吃蛇这个游戏,在游戏机横行的年代,基本上闲下来就会玩玩贪吃蛇 ...

  5. 【C#+Access+WindowsAPI】实现仿360的安全卫士 三:系统检测窗体设计(附源码和资源)

    需要源码和PPT请点赞关注收藏后评论区留言私信~~~ 其他部分文章链接如下 [C#+Access+WindowsAPI]实现仿360的安全卫士 一:功能展示与系统开发环境简介(附源码和资源 [C#+A ...

  6. Visual C++实现黑白棋游戏项目实战二:界面的设计与实现(附源码和资源 超详细)

    需要源码和资源请点赞关注收藏后评论区留言私信~~~ 黑白棋游戏的Visual C++工程采用MFC对话框模式进行开发,下面对它进行详细介绍 一.游戏菜单的实现 首先要在工程资源中添加一个菜单资源类,菜 ...

  7. Visual C++实现俄罗斯方块游戏实战三:核心算法设计与实现(附源码和资源)

    需要源码和资源请点赞关注收藏后评论区留言私信~~~ 一.主游戏类的设计 俄罗斯方块的主游戏类负责显示游戏界面,方块游戏等级等内容,同时还要管理游戏的输入操作 可以分为以下几个模块 1:游戏界面和方块的 ...

  8. 贪吃蛇c语言程序 简书,C语言/C++项目源码分享—贪吃蛇

    /* 项目内容:贪吃蛇 开发环境:vs2013+easyx */ 这个项目是一个小游戏-贪吃蛇项目,代码如下 #include #include //包含easyx图形库,可以使用给我们提供的一些函数 ...

  9. 【C#+SQL Server+打印组件】实现电商快递单打印系统 三:主窗体中的快捷菜单(附源码和资源)

    需要源码请点赞关注收藏后评论区留言私信~~~ 一.快捷单设置的快捷菜单 打开主窗体AppForm的设计界面,双击主窗体的标题栏,切换到主窗体的代码页,在代码页的公共变量或方法的编写区,创建CommCl ...

最新文章

  1. iOS 仿看了吗应用、指南针测网速等常用工具、自定义弹出视图框架、图片裁剪、内容扩展等源码...
  2. 机器人学习--双目视觉测距
  3. 前端必知必会--JSON.stringify()犀利的第三个参数
  4. nginx定制header返回信息模块ngx_headers_more
  5. 物联网智能网关应用系统的一般设计方法
  6. 计算机操作系统(2):OS的发展过程
  7. Asp.Net微信发布菜单,出现“invalid sub button url domain hint”错误
  8. Java基础语法之Map
  9. CC攻击(N个免费代理形成的DDOS)
  10. WatchStor观察:冰岛身陷困境也不会停止数据中心项目
  11. 记录报错:java.lang.NullPointerException org.apache.jsp.test_jsp._jspInit(test_jsp.java:23)
  12. CSocket实现端口扫描
  13. 物理学的过去、现在与未来
  14. python pdf处理工具_NB,真PDF神处理工具!
  15. c语言的矩阵怎么编程,关于矩阵的编程
  16. 宽带拨号常见错误代码解析及故障排查
  17. CentOS7(8)安装/卸载MySQL
  18. electron对接dll
  19. 手游联运平台是怎样开发的?
  20. node节点kubelet报错 node \“xxxxx“ not found

热门文章

  1. 理解RESTful风格
  2. 曾领先的中国电信落后了,净增5G用户仅有中国移动的三分之一
  3. 北冥神功与六脉神剑(一)
  4. SAP TABLES 表汇总
  5. 小程序车牌键盘的实现
  6. PMP考试报名条件有哪些
  7. 什么是工业绝缘监测仪?工业绝缘监测仪应用范围-安科瑞黄安南
  8. html中页面缩放为何不居中,浏览器窗口放大缩小后页面内容居中解决方法
  9. Virtualenv or Anaconda?Python虚拟环境最佳实践
  10. WIN10系统查看开机记录