当前位置:网站首页>贪吃蛇游戏Bug解析及功能扩展
贪吃蛇游戏Bug解析及功能扩展
2022-08-04 01:37:00 【浪雨123】
用C语言实现贪吃蛇游戏,虽然整体实现的逻辑比较简单,但是初写者可能会遇到一些比较棘手的问题,不知道是什么原因造成的,也不知道该怎么处理,这篇文章将列出我在编写贪吃蛇游戏时遇到的sheng去解决这些问题的方法
目录
问题1 :蛇在吃完食物的瞬间,窗口的最左上角产生了一个身体块
问题解决
问题1 :蛇在吃完食物的瞬间,窗口的最左上角产生了一个身体块

为什么会产生这样的结果呢?原因并不复杂,我们在定义蛇的身体时,是用数组直接给定大小的,除了我们在初始化的时候给初始化的几节身体坐标赋了初始值,该身体数组的其余节身体的坐标都是处于初始值为0的状态。
造成这种情况的原因是蛇在吃完一个食物后,此时程序判断身体数目加一,但此时,新添加的这个身体的坐标没有被赋值,此时仍然是初始的0值,然后绘制函数又将这节身体绘制出来,就跑到了左上角,解决办法就是将坐标赋值函数放到身体绘制函数之前,让新增的这一节身体的坐标先被赋值,然后再将它绘制出来,这样就恢复了正常。
问题2:食物生成之后,蛇吃不了食物
造成这个问题的主要原因是存在坐标偏差,我们开创的窗口大小一般是640,480。如果我们将蛇移动的速度控制在每循环一次走10个坐标点,而随机生成食物的坐标值不是10的倍数的话,那么蛇的身体的坐标就会与食物的坐标产生偏差,即使看着像吃到了,但实际坐标不是完全覆盖,吃到食物的判断逻辑就是蛇头坐标与食物坐标完全覆盖,所以是无法吃到的。假设蛇头的初始坐标是(320,240),食物被生成的坐标是(329,240)那么无论蛇怎么走,都吃不到这个食物,除非蛇每移动一次走九个坐标点,才能做到坐标完全覆盖
解决办法就是食物生成的坐标值必须是蛇的身体移动速度的整数倍,且蛇头的初始位置也要是移动速度的整数倍,这里还是推荐速度为10,使用起来很方便
//创造食物
void Creatfood()
{
while (1)
{
food.x = rand() % 62 * 10;
food.y = rand() % 46 * 10;
if (food.x >= 20 && food.y >= 20)
{
food.state = false;
break;
}
}
}
//我这里加循环的原因是不想食物生成在边界问题3:蛇走起来时略有闪烁,不是很流畅
略有闪烁是因为绘制图形时一个一个绘制,然后清空,再重新一个一个图案绘制,在不断绘制清空的过程中,留下的一些清空的痕迹。
解决这个问题的方法就是换一种绘图方式,用批量绘图来绘制游戏画面。批量绘制就是把需要绘制的图案先放到缓冲区里,然后逐步绘制一张画面的内容,把需要绘制的都绘制完成后就呈现在一张画面上,同时第二个缓冲区开始绘制下一次循环后所产生的画面,把绘制完的画面以人眼适应的频率(即帧率)播放到窗口,然后不断刷新,放置,这样我们看到的画面就很流畅了

批量绘图需要两个函数
BeginBatchDraw() //开始批量绘图
.......
//需要绘制的图案放中间
.......
EedBatchDraw() //结束批量绘图这里需要注意的是如果设置了游戏结束的画面,不要将游戏结束画面放到批量绘图函数中间,因为批量绘制结束后会刷新屏幕,游戏结束界面无法显示出来。
功能扩展
扩展1:实现蛇的穿墙
蛇的穿墙就是蛇走到窗口某边界后,再将蛇从该边界的对面边界传过来,这样可以防止蛇跑没了,需要注意的是边界传送的判定要小于边界值,不能等于,不然会出现一半身体传到对面去,另一半还在这边的bug
//穿墙
void Throughwell()
{
if (snake.szb[0].x < 0 || snake.szb[0].x > LENGTH)
{
if (snake.szb[0].x < 0)
{
snake.szb[0].x = LENGTH;
}
else if (snake.szb[0].x > LENGTH)
{
snake.szb[0].x = 0;
}
}
else if (snake.szb[0].y > WIDTH || snake.szb[0].y < 0)
{
if (snake.szb[0].y > WIDTH)
{
snake.szb[0].y = 0;
}
else if (snake.szb[0].y < 0)
{
snake.szb[0].y = WIDTH;
}
}
}扩展2:音乐播放
玩游戏没有音乐,总会感觉少了点什么,那必须加上音乐,音乐素材大家自行寻找
添加音乐的方法首先要包含库
#pragma comment(lib,"winmm.lib")
在输入播放音乐的指令就可
mciSendString("open xxx.mp3 alias BGM", 0, 0, 0);
mciSendString("play BGM repeat", 0, 0, 0);边栏推荐
- 计算首屏时间
- 多渠道打包
- 持续投入商品研发,叮咚买菜赢在了供应链投入上
- Promise 解决阻塞式同步,将异步变为同步
- FeatureNotFound( bs4.FeatureNotFound: Couldn't find a tree builder with the features you requested:
- C语言:学生管理系统(链表版)
- jmeter distributed stress test
- LDO investigation
- redis中常见的问题(缓存穿透,缓存雪崩,缓存击穿,redis淘汰策略)
- Sticker Spelling - Memory Search / Shape Pressure DP
猜你喜欢

Slipper —— 虚点,最短路

lombok注解@RequiredArgsConstructor的使用

特征值与特征向量

【日志框架】

nodejs+express实现数据库mysql的访问,并展示数据到页面上

MongoDB数据接入实践

Continuing to invest in product research and development, Dingdong Maicai wins in supply chain investment

Flask Framework Beginner-05-Command Management Manager and Database Use

typescript53 - generic constraints

阿里云技术专家邓青琳:云上跨可用区容灾和异地多活最佳实践
随机推荐
esp32发布机器人电池电压到ros2(micro-ros+CoCube)
【虚拟化生态平台】虚拟化平台搭建
安全至上:落地DevSecOps最佳实践你不得不知道的工具
【日志框架】
无代码7月热讯 | 微软首推数字联络中心平台;全球黑客马拉松...
typescript53 - generic constraints
idea中diagram使用
jmeter distributed stress test
Thinkphp commonly used techniques
typescript58 - generic classes
Quickly build a website with static files
Sky map coordinate system to Gaode coordinate system WGS84 to GCJ02
Continuing to pour money into commodities research and development, the ding-dong buy vegetables in win into the supply chain
What warehouse management problems can WMS warehouse management system solve in the electronics industry?
贴纸拼词 —— 记忆化搜索 / 状压DP
【虚拟户生态平台】虚拟化平台安装时遇到的坑
快速入门EasyX图形编程
一篇文章看懂JS闭包,从执行上下文角度解析有趣的闭包
数组_滑动窗口 | leecode刷题笔记
天地图坐标系转高德坐标系 WGS84转GCJ02