没有合适的资源?快使用搜索试试~ 我知道了~
用visul c++开发的贪吃蛇游戏.pdf
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 92 浏览量
2022-11-14
23:16:05
上传
评论
收藏 518KB PDF 举报
温馨提示
试读
17页
。。。
资源推荐
资源详情
资源评论
贪吃蛇完整设计过程和完整源代码
简介
一直在学 VC 编程,但是感觉自己的进步甚微,还是什么都不懂,还是什么都不会编,
再加上身心不适,学习总是断断续续的。期中考试过后,放六天假,闲来无事,在网上看到
了别人编的贪吃蛇游戏,自己下载两个源代码,一个界面做的太不人性化,感觉那蛇不像蛇,
都是断断续续的小点,感觉不是很好;另一个是在 TC 中编的,好像现在很少有人用 TC,
我想大家都应该跟我一样,都是用 VC,没办法,需要画图,这个程序在 VC 中没办法运行,
一 DEBUG 错误连篇,看都不想看了。
所以自己有了编写这个游戏的念头。
首先自己看了看别人编写贪吃蛇的思路(其实这就是这个游戏的精髓,我很惭愧啊)。就是
使用链表来实现的。-----到这里,是不是很感慨我们学过的数据结构原来是这么有用途啊?
链表?用链表就可以实现吗?------没错!就是用链表(队列)实现的,在这个游戏程序中除
了画图,定时,产生随机数之外,那就是链表的创建,扫描,入队和出队了。如果你懂链表
的这些基本的操作,那没问题,这个游戏程序编写出来是没有问题的。当然还是得知道点(一
点点)WIN32(API,我是用 API,没用 MFC,相比较 API 开始比 MFC 好学些哦)应用程
序的基本框架的基本知识。比方说某些消息,WM_CREATE , WM_PAINT , WM_CHAR ,
WM_TIMER ;HPEN (画笔), HBRUSH(画刷),HDC(设备上下文环境) ;某些设置画
笔、画刷的函数:CreatePen() , SelectObject() ;获取 DC 的函数,在 WM_PAINT 中要使用:
BeginPaint() ..... EndPaint() ,在其他地方就要使用 GetDC() ......ReleaseDC() ;设置定时器函
数 SetTimer() ,销毁定时器函数 KillTimer() 。好了,这就是编写出此程序所需要的全部知识,
下面的过程要看个人的逻辑思维能力,编程经验。经验丰富,逻辑缜密的走的弯子肯定要少
很多,否则,那当然会走完一个又一个弯子之后....还得继续走弯子,不过肯定会做出来的,
只要坚持!不过也不排除人品大爆发的,用不了多久就编出来了。不过还是强烈建议多走走
弯子,只有经历过,你才知道某段代码为什么要那么编,不那么编会出现什么样的情况。
嗯~~~~废话说完了,进入正题吧。
首先看看我们这个程序的运行效果吧,很是简陋,但是麻雀虽小,五脏俱全啊。
界面
设计这个游戏,那第一步要思考的当然是如何将格子画出来了。
我们先确定下每一个格子的大小吧。我这里的大小为 16*16,总共有 20 行 20 列。
先 定 义 宏 #define RowOfFrame 20 #define ColumnOfFrame 20 #define Width 16
#define Height 20 字面意思已经很清楚了。
您可能恍然大悟,画这格子不很简单吗!对!不就是画 20 条横线,20 条竖线吗!查下 MSDN ,
MoveToEx()是用来设定起始点的,LineTo()是用来画起点到终点的线。当然画线是用
画笔去画的。那得创建具有这些要求的画笔了。两句话就搞定了:
HPEN hpen=CreatePen(PS_SOLID,1,RGB(255,0,0));
SelectObject(hdc,hpen);
接下来画 20 条横线 20 条竖线吧。这个就是 Design()函数所完成的功能。
当然这里需要给每个格子一个定位坐标 ,程序中已经默认使用了。也很简单,就是我们在
脑子里面给它一个坐标系就行了。比方说(0,0)代表的是左上角第一个格子,而(19,19)
代表的是右下角的格子。假如一个格子的坐标为(x ,y),那么这个格子的左上顶点的实际坐
标是多少呢?能想出来吧,不行就在纸上画画,是(x*Width , y*Height)。 这个我们在后面
产生随机数,记录蛇节点,食物的位置等的时候要用到的。
看到这里想必敏感的人可能已经知道怎么画蛇了吧,不也是用画笔画线吗,只不过线粗点而
已,是不是?画食物也是一样的道理,简单得来吧~~~ 具体的操作参考一下函数 DrawSnake
(),DrawFood()。
到这里,游戏所涉及的画图的知识就这么多。相信你可以用画笔画线、画矩形了吧。这在这
里就足够了。是不是很简单呢?的确,这游戏一点都不难,要不然我这个阿斗怎么就编出来
了呢?Believe yourself! Let's continue...
数据结构
下面得说说所涉及到的链表这个数据结构了。
我们这里的蛇是一个个连续的格子组合在一起的,我们只要定义一个结构体记录格子的位
置,那么蛇就是这些结构体所组成的链表了。结构体定义如下:
Struct Node
{
Int x;
Int y;
Node * next;
};
Struct snake
{
Node * head;
Node * tail;
Int length;
};
功能模块
我们在初始的时候,规定蛇的长度是 1,所在的位置是(0,0)格子中。这是 Init()函数
所完成的功能。
先不管蛇每隔 1 秒钟就按照原来的方向向前移动一个格子,也不管蛇吃到食物后长度增壹。
这些统统都先不管,因为我们有比这还迫切的任务需要解决,这个问题解决不了,前面两个
问题是怎么也实现不好的。您知道是什么问题吗?想想自己是怎么玩贪吃蛇游戏的?啊 ~~
上下左右控制蛇的运动方向啊!是吧。。。
这里为了方便,我使用的不是箭头,而是 w(上)、s(下)、a(左)、d(右),我现在需要完
成的功能是:蛇的初始位置在(0,0)格子,初始的方向是右。我每按一次 d(是小写的啊),
蛇就向前移动一个格子,我不按 d(也没按 w、s、a 或者....你懂的)蛇就不动。
这个问题的本质就是将先前的窗口内图形擦除,然后再重新绘制一幅图形(画格子,画食物,
画蛇新的位置)。
首先说将先前窗口内图形擦除掉的方法。也很简单,入门的都应该知道,我用背景色画一个
窗口客户区那么大的矩形把它覆盖掉不就完事了吗!嗯~~~至少我用的就是这个方法。
同样也是几行代码而已:
RECT rect;
GetClientRect(hdc,&rect);
SelectObject(hdc,(HBRUSH)GetStockObject(WHILE_BRUSH));
Rectangle(hdc,rect.left,rect.top,rect.right,rect.bottom);
擦掉了吧?但是您肯定会说我只是想把蛇向前挪一个位置,如果硬要擦除的话,也仅仅把蛇
擦掉不就行了吗,为什么还要把整个画好的格子跟食物也擦掉呢?你不多此一举,画蛇添足
吗!
哎,您说的真的没错,但是我这不也是仅仅图个简单吗(但是这个简单真的代价大了点,等
运行的时候您就可以看到了,蛇每每前进一步,窗口就抖动一下下,就是这个原因)。
擦 掉 之 后 需 要 重 绘 界 面 , 画 食 物 , 画 蛇 。 调 用 的 函 数 都 是 一 样 的 ,
Design(),DrawFood(),DrawSnake() ,不过此时的蛇肯定变了!它已经按照原来的方向向前移动
一个格子了。蛇向前移动一个格子,也就是新的节点入队,再将队列的最后一个节点从链表
中删掉就可以了。(这里我需要说明下,因为我编程的疏忽,一不小心将蛇头变成蛇尾,蛇
尾变成蛇头了,什么意思呢?就是蛇吃食物的那个格子是蛇尾,屁股后面的是蛇头,也就是
这里删掉的节点其实是蛇头节点。不过也没什么影响,就是逻辑上有点怪怪的而已,大家迁
就点吧。)
有关蛇根据原来移动的方向 CurrentDirection 和所按下的控制键来判断下一步移动的位置,
请参考函数 NextNode()的代码。
那如果考虑蛇吃到食物呢?是不是蛇的长度增加一个格子,并且蛇头(注意:我这里的蛇头
就是您逻辑中的蛇尾,理由上面已经讲过了)格子保留下来就可以了。
上面的功能如果您实现了,您会发现又有个问题出现了,那就是越界问题。其实在我们最初
设计贪吃蛇游戏的时候早就考虑到了,就是一直没把它考虑进去而已。现在来考虑这个问题
是再好不过的了。
想想 NextNode()是计算下一个蛇即将要运动到的节点,肯定得判断下这个节点是不是越
界了?是不是碰到蛇它自己了?也很简单,判断越界就是看看按照 NextNode()计算出来
的下一个格子的坐标是否符合要求就行了(0<=x<20 && 0<=y<20),判断是不是碰到蛇,也
就是判断这个节点是不是在蛇身上(链表上面)。具体参考函数 Hit()。
既然这里讲到越界问题,有个与此类似的问题也就出现了。那就是每次随机生成的食物位置,
它也是有所限制的。它也不能越界,也不能在蛇的身上,要不然继续生成随机数,具体操作
步骤参考函数 randomize()。
好像问题解决的差不多了吧,不过如果您已经完成了以上的功能,运行程序发现如果你不按
键,蛇就不动,那怎么行呢!我们需要每隔一秒无论按不按键蛇头自动向前运动一个格子,
那这个怎么实现呢?到 MSDN 上查查下面两个函数,您可能就瞬间明白该怎么实现这个功
能了:SetTimer(),KillTimer(),我们只需要在游戏开始的时候,也就是 WM_CREATE
中设置一个定时器,开始计时,然后每隔 1 秒钟(如果您设置的间断时间是1 秒钟的话)就
会产生 WM_TIMER 消息,这样只需要在 WM_TIMER 消息下编写处理代码就行了,这里
的处理代码也是重绘窗口,把蛇新的位置给画出来。
至此,这个游戏应该算是完成了。上面只是简单地说说当时我编写该程序时的渐近过程,只
是参考而已。这个程序执行起来会有很多的问题。我在编出来之后想使它变的更花哨一点的
时候,发现了种种的问题,比方说我在画蛇的时候,每一个蛇节我都用一种随机颜色去画,
刚开始的时候运行的好好的,等蛇长度达到一定规模的时候,程序不能正常运行了。有关这
些问题,以及前面提到的屏幕抖动的问题,在这里就不再讨论了,小问题而已,相信您可以
很好的解决!
总之,我觉得贪吃蛇游戏不难,可以作为 VC 初学者很好的练习素材。
剩余16页未读,继续阅读
资源评论
不吃鸳鸯锅
- 粉丝: 8295
- 资源: 2万+
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功