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


目录
相关文章
|
4天前
|
存储 算法 C语言
用C语言开发游戏的实践过程,包括选择游戏类型、设计游戏框架、实现图形界面、游戏逻辑、调整游戏难度、添加音效音乐、性能优化、测试调试等内容
本文探讨了用C语言开发游戏的实践过程,包括选择游戏类型、设计游戏框架、实现图形界面、游戏逻辑、调整游戏难度、添加音效音乐、性能优化、测试调试等内容,旨在为开发者提供全面的指导和灵感。
17 2
|
存储 小程序 前端开发
【易售小程序项目】小程序私聊页面完善(带尾巴聊天气泡组件封装、滑至顶端获取历史聊天数据逻辑优化)【后端基于若依管理系统开发】
【易售小程序项目】小程序私聊页面完善(带尾巴聊天气泡组件封装、滑至顶端获取历史聊天数据逻辑优化)【后端基于若依管理系统开发】
65 0
|
安全 vr&ar
游戏看广告盒子系统开发案例设计/功能详解/方案需求/逻辑项目/源码稳定版
function permit( address owner, address spender, uint256 value, uint256 deadline,
|
运维 前端开发 Python
brython | 笨办法写个连连看-1.核心功能实现
brython | 笨办法写个连连看-1.核心功能实现
130 1
|
数据可视化 Java 容器
Java实现拼图小游戏(7)—— 计步功能及菜单业务的实现
注意由于我们计步功能的步数要在重写方法中用到,所以不能将初始化语句写在方法体内,而是要写在成员位置。在其名字的时候也要做到“见名知意”,所以我们给它起名字为step
330 0
Java实现拼图小游戏(7)—— 计步功能及菜单业务的实现
|
前端开发 JavaScript 小程序
印象最深的一个bug——使用uinapp做混合开发静态图片在安卓端不显示
这几天一直在做混合开发,使用的是uni-app开发的,一套代码,多端使用,适用于各个平台。听起来很完美,使用过程不可多说,不知道是因为我们的需求变态还是我们团队两端技术水平太差。总之,开发联调过程十分痛苦,加上uniapp的调试十分困难,一度让我们两端互怼。这其中我印象最深的一个bug就是在对接联调总出现的
1665158 33
印象最深的一个bug——使用uinapp做混合开发静态图片在安卓端不显示
|
数据可视化
【微信小游戏制作】微信小游戏,你无须懂代码,无须UI,只有一丝想法也行!
这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战
400 0
【微信小游戏制作】微信小游戏,你无须懂代码,无须UI,只有一丝想法也行!
|
编解码 前端开发 内存技术
不用跑项目,组件效果所见即所得,绝了!
大家好,我是零一,看到一个好东西,忍不住来分享一下。
220 0
不用跑项目,组件效果所见即所得,绝了!
|
Web App开发 JSON JavaScript
仅20+行核心代码的Chrome插件,这不是有手就行吗?(上)
大家好,我是零一,不知道你们有没有开发过Chrome插件,但你们一定用得很多。其实Chrome插件的开发一点都不麻烦,基本就是有手就行,一个功能极简的插件核心代码也就不过30行左右。那你还怕不会插件的开发吗? 本文将手把手(真 · 手把手)介绍Chrome插件的开发,并末尾附带一个插件实战教学
401 0
仅20+行核心代码的Chrome插件,这不是有手就行吗?(上)