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

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

目录

问题解决

问题1 :蛇在吃完食物的瞬间,窗口的最左上角产生了一个身体块

问题2:食物生成之后,蛇吃不了食物

问题3:蛇走起来时略有闪烁,不是很流畅

功能扩展

扩展1:实现蛇的穿墙

扩展2:音乐播放


问题解决

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

猜你喜欢

转载自blog.csdn.net/m0_61350245/article/details/126066670