用c语言写贪吃蛇(有Easyx图形库版)

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<graphics.h>           //图形库头文件
#include<conio.h>
#include<mmsystem.h>       //包含多媒体文件接口头文件
#pragma comment(lib,"winmm.lib")     //加载静态库
#define WIDE 720            //定义窗体宽度
#define HIGH 480            //定义窗体高度
#define R 7                       //定义蛇的半径
#define SNAKEmax 600             //定义蛇的最大长度

int score = 0;                        //初始得分;
int flag;                       //判断程序是否暂停
void Food_Create();
void Game_init();
void Game_Draw();
void Snake_Move();
void change();
void Keycontrol();
void EateFood();
void main_fuction();
bool GameOver();
void Music1();
void Music2();
void Music3();
void Music4();
void Music_bgm();

enum DIR      //方向枚举(其中的元素都为整数值,默认为0开始)
{
	UP,                             //向上
	DOWN,                       //向下
	RIGHT,                      //向右
	LEFT,                        //向左
};
struct  SnakeHead     //蛇的结构体
{
	int size;                //长度
	int dir;                 //方向
	int speed;            //速度
	POINT coor[SNAKEmax];          //用来放蛇的坐标
}snake;
struct Body                 //得分蛇身的长度
{
	POINT coor[SNAKEmax];
}body;
struct Food              //食物得结构体
{
	int x;                    //食物坐标
	int y;
	int r;                    //食物半径
	bool flag;            //判断食物是否被吃
	DWORD color;     //食物颜色 Double Word, 每个word为2个字节的长度,
	//DWORD 双字即为4个字节,每个字节是8位,共32位
}food;

int main()                                      //主函数入口
{
	char choice;
	printf_s("---------------开始菜单----------------\n");
	printf_s("游戏介绍:贪吃蛇,是一款经典的休闲小游戏\n在游戏中你可以通过按下W,S,A,D来上下左右移动\n");
	printf_s("---------------------------------------------------------\n ");
	printf_s("---------------- 空格键暂停 --------------------------\n");
	printf_s("-----------你是否现在开始游戏?---------------------\n");
	printf_s("---------------------YES / NO--------------------------------\n");
	printf_s("   确定输入y,取消输入n...............\n");
	scanf_s("%c", &choice);
	if (choice == 'y')
	{
			//Game_init();
			//change();
			//Music1();
			//while (1)
			//{
			//	while (!GameOver())
			//	{
			//		Snake_Move();
			//		Game_Draw();
			//		Keycontrol();
			//		if (flag == -1)                      //游戏暂停
			//		{
			//			while (1)
			//			{
			//				Keycontrol();
			//				if (flag == 1)             //游戏继续
			//				{
			//					break;
			//				}

			//			}
			//		}
			//		EateFood();
			//		Sleep(100);                //操作延迟100毫秒,防止蛇移动过快
			//	}
			//}*/
			main_fuction();
	}
	else if (choice == 'n')
	{
		exit(0);
	}
		return 0;
}
void Food_Create()        //生成食物
{

	food.x = rand() % (WIDE - R - 24);            //随机函数,并限制生成范围(rand函数随机生成大于0小于1的数)
	food.y = rand() % (HIGH - R - 54);
	food.color = RGB(rand() % 256, rand() % 256, rand() % 256);
	//用随机函数来得到颜色
	food.r = R + 1;
	food.flag = true;
}
void Game_init()            //游戏初始化      
{
	initgraph(WIDE, HIGH);        //初始化窗口
	score = 0;                             //初始化分数
	flag = 1;                                //游戏开始 
	srand(GetTickCount());       //srand也是取随机数函数,不过他可以得到随机种子,
	//gettickcount()为获得系统开机时间毫秒数,以这个时间为种子
	//每次程序打开得时间不同那么得到的随机数也不同
	snake.size = 3;                    //初始化蛇的长度
	snake.speed = 2 * R;          //初始化蛇的速度
	snake.dir = RIGHT;             //初始化蛇的方向
	snake.coor[snake.size - 1].x = (2 * R + 2) * (snake.size - 1) + (2 * R - 2);  //初始化蛇头坐标
	snake.coor[snake.size - 1].y = 2 * R;
	for (int i = snake.size - 2; i >= 0; i--)
	{
		snake.coor[i].x = 2 * R * i + 2 * R;
		snake.coor[i].y = 2 * R;                                                          //蛇身的坐标
	}

	Food_Create();                         //初始化食物
}

void Game_Draw()                         //绘制游戏
{
	Music_bgm();
	BeginBatchDraw();                                       //双缓冲绘图,防止闪屏
	setbkcolor(RGB(128, 128, 128));                  //设置背景颜色(灰色)
	cleardevice();                                               //清屏
	setfillcolor(BLUE);                                        //设置边框颜色 
	for (int i = 0; i < 450 / 3; i++)
	{
		solidrectangle(0, i * 3, 3, (i + 1) * 3);
	}
	for (int i = 1; i < (WIDE / 3); i++)
	{
		solidrectangle(i * 3, 0, (i + 1) * 3, 3);              //利用四个for循环绘制边框
	}
	for (int i = 1; i < 450 / 3; i++)
	{
		solidrectangle(717, i * 3, 720, (i + 1) * 3);
	}
	for (int i = 1; i < (WIDE / 3) - 1; i++)
	{
		solidrectangle(i * 3, 447, (i + 1) * 3, 450);
	}
	int x = 0;
	outtextxy(50, 465, "Score Now: ");                        //显示得分
	outtextxy(410, 465, "History score: ");


	setfillcolor(RED);                                      // 设置蛇头颜色
	solidcircle(snake.coor[snake.size - 1].x, snake.coor[snake.size - 1].y, R + 1);
	setfillcolor(YELLOW);                               //设置蛇身颜色
	for (int i = 0; i < snake.size - 1; i++)
	{
		solidcircle(snake.coor[i].x, snake.coor[i].y, R);         //绘制蛇身
	}
	for (int i = 0; i < score; i++)
	{
		solidcircle(body.coor[i].x, body.coor[i].y, R);             //绘制得分部分

	}
	if (food.flag)                                                                  //食物存在    solidrectangle(矩形函数)
	{
		solidcircle(food.x, food.y, food.r);

	}

	EndBatchDraw();
}
void main_fuction()                                                       //将主函数功能放入该函数以此来重新调用
{                                                                                     //主函数
	Game_init();
	//change();
	Music1();
	while (1)
	{
		while (!GameOver())
		{
			Snake_Move();
			Game_Draw();
			Music_bgm();
			Keycontrol();
			if (flag == -1)                      //游戏暂停
			{
				while (1)
				{
					Keycontrol();
					if (flag == 1)             //游戏继续
					{
						break;
					}

				}

			}
			EateFood();
			Sleep(100);                //操作延迟100毫秒,防止蛇移动过快
		}
		Sleep(1000);                                      //延迟
		mciSendString("close bgm", 0, 0, 0);
	//	cleardevice();

		mciSendString("play ./fail.mp3 ", 0, 0, 0);
		change();
	    mciSendString("stop ./fail.mp3", 0, 0, 0);
	 //   int isok=MessageBox(NULL, "你撞墙死了是否要重新游戏?", "提示", MB_OKCANCEL);
	 
		//if (isok == IDOK)
		//{
		//	main_fuction();
		//}
		//if (isok == IDCANCEL)
		//{
		//	exit(0);
		//}
	}
}

void Snake_Move()                                            //蛇的移动
{
	if (score > 0)                                                //得分
	{
		for (int i = 0; i < score - 1; i++)
		{
			body.coor[i] = body.coor[i + 1];            //得分的蛇身
		}
		body.coor[score - 1] = snake.coor[0];
	}
	for (int i = 0; i < snake.size - 1; i++)
	{
		snake.coor[i] = snake.coor[i + 1];                      //蛇身的移动
	}

	switch (snake.dir)                                           //判断当前蛇的移动方向(移动蛇头)
	{
	case UP:                                                                           //向上
		snake.coor[snake.size - 1].y -= snake.speed;
		break;
	case DOWN:
		snake.coor[snake.size - 1].y += snake.speed;             //向下
		break;
	case RIGHT:
		snake.coor[snake.size - 1].x += snake.speed;            //向右

		break;
	case LEFT:
		snake.coor[snake.size - 1].x -= snake.speed;              //向左
		break;
	}
}
void change()
{
	HWND head = GetHWnd();
	SetWindowTextW(head, L"Snake--2.0");
	int isok=MessageBox(head, "你撞墙死了是否重新开始?", "提示", MB_OKCANCEL);
	if (isok == IDOK)
	{
		mciSendString("stop ./fail.mp3", 0, 0, 0);
		main_fuction();
	}
	else if (isok == IDCANCEL)
	{
		exit(0);
	}
}
void Keycontrol()                                     //键盘控制
{
	if (_kbhit())                                         //判断是否使用键盘
	{
		switch (_getch())
		{
		case 'w':
		case 'W':
			if (snake.dir != DOWN)                //如果原来方向不为下,则可以改为向上
			{
				snake.dir = UP;
			}
			break;
		case 's':
		case 'S':
			if (snake.dir != UP)
			{
				snake.dir = DOWN;                    //如果原来方向不为上,则可以改为向下
			}
			break;
		case 'a':
		case 'A':
			if (snake.dir != RIGHT)
			{
				snake.dir = LEFT;                        //如果原来方向不为右,则可以改为向左
			}
			break;
		case 'd':
		case 'D':
			if (snake.dir != LEFT)
			{
				snake.dir = RIGHT;                     //如果原来方向不为左,则可以改为向右
			}
			break;
		case ' ':                                                      //空格,游戏暂停

			//MessageBox(NULL, "你干嘛哎呦", "食不食油饼", MB_OKCANCEL);
			bool isflag = false;
			mciSendString("close bgm", 0, 0, 0);
			flag = -flag;
			mciSendString("open ./你干嘛.mp3 alias ikun", 0, 0, 0);
			while (1) {
				if (flag == -1)
				{
					mciSendString("play ikun  ", 0, 0, 0);
				}
				break;
			}


		}
	}
}
void EateFood()                                              //吃掉食物
{
	if (food.flag == true && abs(snake.coor[snake.size - 1].x - food.x) <= 8 && abs(snake.coor[snake.size - 1].y - food.y <= 8))
	{                                                                   //判断食物是否被吃掉,如果被吃掉
		food.flag = false;                                    //标记食物被吃
		score++;                                                  //得分加1
		char str[10];                                           //定义字符数组存放得分
		sprintf_s(str, "%d", score);
		outtextxy(150, 465, str);
		Food_Create();                                        //重新生成食物
	}

}
void Music1()
{
	mciSendString("open ./真的是你.mp3 alias BGM1", 0, 0, 0);
	mciSendString("play BGM1 ", 0, 0, 0);
}
void Music2()
{                                                                                                             //导入音乐
	mciSendString("open ./厉不厉害.mp3 alias BGM2", 0, 0, 0);
	mciSendString("play BGM2 ", 0, 0, 0);
}
void Music3()
{
	mciSendString("open ./你干嘛.mp3 alias BGM3", 0, 0, 0);
	mciSendString("play BGM3", 0, 0, 0);
}
void Music_bgm()
{
	mciSendString("open ./背景.mp3 alias bgm", 0, 0, 0);
	mciSendString("play bgm repeat", 0, 0, 0);
}
void Music4()
{
	mciSendString("open ./fail.mp3 alisa Fail", 0, 0, 0);
	mciSendString("play Fail repeat", 0, 0, 0);
}
bool GameOver()                                      //判断游戏是否结束(触碰墙壁)
{
	if (snake.coor[snake.size - 1].y <= 3 && snake.dir == UP)         //向上撞墙
	{
		return true;
	}
	if (snake.coor[snake.size - 1].y >= 447 && snake.dir == DOWN)           //向下撞墙
	{
		return true;
	}
	if (snake.coor[snake.size - 1].x <= 3 && snake.dir == LEFT)                      //向左撞墙
	{
		return true;
	}
	if (snake.coor[snake.size - 1].x >= 717 && snake.dir == RIGHT)              //向右撞墙
	{
		return true;
	}

	return false;
}

以上是源代码,但其中还有一些bug(虽然我设置了分数记录但是不知到为什么他显示的时候会一闪而过,还有就是我没有保存得分。。)

要说明的是游戏中添加了音乐使用的mciSendString()函数,具体用法大家自行搜索这里就不赘述了。这里是我下载音频的网址音效 音效网 声音网 音效素材 音效下载 游戏音效 - 爱给网 (aigei.com)

如有问题欢迎指正。

 

 

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值