当前位置:网站首页>贪吃蛇游戏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);
边栏推荐
- Variable string
- nodejs+express realizes the access to the database mysql and displays the data on the page
- 特征值与特征向量
- [store mall project 01] environment preparation and testing
- 字符串的排列
- typescript52 - simplify generic function calls
- 螺旋矩阵_数组 | leecode刷题笔记
- 2022 中国算力大会发布“创新先锋”优秀成果
- Quickly build a website with static files
- How to find the cause of Fiori Launchpad routing errors by single-step debugging
猜你喜欢
敏捷交付的工程效能治理
2022 中国算力大会发布“创新先锋”优秀成果
The 600MHz band is here, will it be the new golden band?
nodejs切换版本使用(不需要卸载重装)
Slipper —— 虚点,最短路
持续投入商品研发,叮咚买菜赢在了供应链投入上
lombok注解@RequiredArgsConstructor的使用
Deng Qinglin, Alibaba Cloud Technical Expert: Best Practices for Disaster Recovery across Availability Zones and Multiple Lives in Different Locations on the Cloud
Electronics manufacturing enterprise deployment WMS what are the benefits of warehouse management system
持续投入商品研发,叮咚买菜赢在了供应链投入上
随机推荐
Multithreading JUC Learning Chapter 1 Steps to Create Multithreading
【QT小记】QT中信号和槽的基本使用
[store mall project 01] environment preparation and testing
KunlunBase 1.0 发布了!
Continuing to invest in product research and development, Dingdong Maicai wins in supply chain investment
typescript48 - type compatibility between functions
Use nodejs switch version (no need to uninstall and reinstall)
.NET Static Code Weaving - Rougamo Release 1.1.0
nodejs+npm的安装与配置
boot issue
Web3 security risks daunting?How should we respond?
Apache DolphinScheduler新一代分布式工作流任务调度平台实战-中
Observability:你所需要知道的关于 Syslog 的一些知识
工程制图复习题(带答案)
Tanabata festival coming, VR panoramic look god assists for you
MongoDB数据接入实践
typescript57 - Array generic interface
appium软件自动化测试框架
nodejs 安装多版本 版本切换
【store商城项目01】环境准备以及测试