C项目(贪吃蛇BUG解决及功能扩展)

简介: C项目(贪吃蛇BUG解决及功能扩展)

用C语言实现贪吃蛇游戏,虽然整体实现的逻辑比较简单,但是初写者可能会遇到一些比较棘手的问题,不知道是什么原因造成的,也不知道该怎么处理,这篇文章将列出我在编写贪吃蛇游戏时遇到的sheng去解决这些问题的方法


问题解决

问题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);


目录
相关文章
|
数据采集 机器学习/深度学习 算法框架/工具
利用Python实现基于图像识别的自动化数据采集系统
本文介绍了如何利用Python编程语言结合图像识别技术,构建一个自动化的数据采集系统。通过分析图像内容,实现对特定信息的提取和识别,并将其转化为结构化数据,从而实现高效、准确地采集需要的信息。本文将详细讨论系统的设计思路、技术实现以及应用场景。
|
机器学习/深度学习 算法 索引
LSTM(长短期记忆网络)原理介绍
LSTM算法是一种重要的目前使用最多的时间序列算法,是一种特殊的RNN(Recurrent Neural Network,循环神经网络),能够学习长期的依赖关系。主要是为了解决长序列训练过程中的梯度消失和梯度爆炸问题。简单来说,就是相比普通的RNN,LSTM能够在更长的序列中有更好的表现。
7617 0
LSTM(长短期记忆网络)原理介绍
|
算法
【计算机组成原理】(四)原码补码的加减乘除
各种码的作用: 模运算的性质:
522 0
|
9月前
|
机器学习/深度学习 供应链 搜索推荐
优化销售预测:6种模型适用的场景与实战案例
不同行业的销售预测采用什么模型比较好?3分钟了解6种销售预测模型,以及适用行业场景。
1835 2
优化销售预测:6种模型适用的场景与实战案例
|
10月前
|
敏捷开发 监控 数据可视化
实现SMART目标的工具有哪些?推荐5款适合团队和企业的目标管理工具
本文介绍了5款高效工具,包括Banli Kanban、Wrike、Airtable、Targetprocess和Basecamp,它们均能有效支持企业实现SMART目标的设定与管理。这些工具通过任务管理、进度跟踪、团队协作等功能,帮助企业确保目标的具体性、可衡量性、可达成性、相关性和时限性,提升工作效率和目标达成率。选择合适的工具需考虑企业的具体需求和规模。
实现SMART目标的工具有哪些?推荐5款适合团队和企业的目标管理工具
|
域名解析 缓存 网络协议
揭秘DNS协议:从'http://www.example.com'到IP地址的奇幻旅程,你不可不知的互联网幕后英雄!
【8月更文挑战第4天】在互联网的广袤空间里,每台设备都有唯一的IP地址,但记忆这些数字组合并不直观。因此,DNS(域名系统)作为关键桥梁出现,将易记的域名转换为IP地址。DNS协议工作于应用层,支持用户通过域名访问资源。DNS系统包含多级服务器,从根服务器到权威服务器,共同完成域名解析。查询过程始于客户端,经过递归或迭代查询,最终由权威服务器返回IP地址,使浏览器能加载目标网页。
440 12
|
前端开发 小程序
微信小程序系列——无缝引入CSS或者WXML文件
微信小程序系列——无缝引入CSS或者WXML文件
|
Java 调度
线程池如何知道一个线程的任务已经执行完成
线程池如何知道一个线程的任务已经执行完成
778 0
|
存储 SQL 关系型数据库
MySQL行格式原理深度解析
MySQL行格式原理深度解析
|
图形学 Python 容器
【PyQt5桌面应用开发】3.Qt Designer快速入门(控件详解)
【PyQt5桌面应用开发】3.Qt Designer快速入门(控件详解)
2613 0