C语言贪吃蛇

主要是对easyx图形库的使用。
按键说明:空格暂停,R重新开始,esc退出游戏,撞墙或头和尾相碰结束游戏。WASD和方向键都可以使用,不分大小写
在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>
#include <graphics.h>
#include <conio.h>//使用_getch()函数要包含的头文件
#include <mmsystem.h>
#pragma comment(lib,"winmm.lib")


#define SNAKE_NUM 500
#define RADIUS 5 //蛇和食物半径
char cgrade[10];//转换游戏得分
int end_flag = 0;//游戏结束标志位

int main(void);

struct Snake
{
	int size;//蛇的节数
	int dir;//蛇的方向
	int speed;//蛇的速度
	POINT coor[SNAKE_NUM];//POINT是定义好的xy坐标,coor是蛇的最大节数,每一节蛇都要有坐标所以用数组

}snake;

struct Food
{
	int x;
	int y;
	int r;//食物半径
	bool flag;//食物是否被吃
	DWORD color;//食物颜色
}food;

enum DIR
{
	UP = 72,
	DOWN = 80,
	RIGHT = 77,
	LEFT = 75,
	ESC=27
};


//数据的初始化
void Game_Init()
{
	//播放背景音乐
	mciSendString("open ./res/1.mp3 alias BGM", 0, 0, 0);
	mciSendString("play BGM repeat", 0, 0, 0);
	//初始化图形窗口 SHOWCONSOLE显示控制台
	initgraph(640, 520);
	//设置随机数种子 GetTickCount()获取系统开机到现在所经过的毫秒数 
	srand(GetTickCount());
	//初始化蛇
	snake.size = 3;
	snake.speed = 8;
	snake.dir = RIGHT;

	for (int i = 0; i < snake.size; i++)
	{
		snake.coor[i].x = 40-snake.speed*i;//coor[0]是蛇头
		snake.coor[i].y = 10;
	}
	
	//初始化食物 rand()随机产生一个整数,如果没有设置随机数种子,每次产生的都是固定的整数
	//设置种子需要头文件stdlib.h,一般把时间作为种子,因为时间在不断变化
	food.x = rand() % 580+20;
	food.y = rand() % 420+20;
	food.color = RGB(rand() % 256, rand() % 256, rand() % 256);
	food.r = RADIUS;
	food.flag = true;
}

void Key_Control()
{
	if (_kbhit())//判断是否有按键按下
	{
		switch (_getch())//判断按下的是哪个按键
		{
		case 'W':
		case 'w':
		case UP:
			if (snake.dir != DOWN)
			{
				snake.dir = UP;
			}
			break;
		case 'S':
		case 's':
		case DOWN:
			if (snake.dir != UP)
			{
				snake.dir = DOWN;
			}
			break;
		case 'A':
		case 'a':
		case LEFT:
			if (snake.dir != RIGHT)
			{
				snake.dir = LEFT;
			}
			break;
		case 'D':
		case 'd':
		case RIGHT:
			if (snake.dir != LEFT)
			{
				snake.dir = RIGHT;
			}
			break;
		case ' ':
			while (1)//按一次进入while里死循环,相当于暂停
			{
				if (_getch() == ' ')//再按一次进入这里,return退出Key_Control函数,执行行Snake_Move函数,相当于又开始游戏
				{
					return;
				}
			}
			break;
		case 'r':
		case 'R':
			system("cls");
			main();//重新开始
			break;
		case ESC: //退出
			system("cls"); //清空屏幕
			exit(0);

		}
	}

}

void Game_Draw()
{
	BeginBatchDraw();//双缓冲绘图,防止闪频
	//设置背景颜色
	setbkcolor(RGB(128, 128, 192));
	cleardevice();//覆盖默认背景颜色
		//画线段
	setlinecolor(BLACK);//表示设立线段的颜色
	line(0, 480, 640, 480);//绘画线段

	settextstyle(20, 0, _T("微软雅黑"));
	settextcolor(BLACK);//设置文字颜色
	outtextxy(10, 490, "当前得分:");//设置文本起始坐标,输出文本。 
	sprintf(cgrade, "%d", snake.size - 3);
	outtextxy(95, 490, cgrade);//设置文本起始坐标,输出文本。 
	if (end_flag == 1)
	{
		settextstyle(40, 0, _T("微软雅黑"));
		settextcolor(RED);//设置文字颜色
		outtextxy(200, 150, "游戏结束");//设置文本起始坐标,输出文本。
		outtextxy(200, 190, "重新开始请按R");//设置文本起始坐标,输出文本。
	}

	for (int i = 0; i < snake.size; i++)
	{
		solidcircle(snake.coor[i].x, snake.coor[i].y, RADIUS);//画实心圆代表蛇的节
		if (abs(snake.coor[0].x - snake.coor[i + 1].x) <= 5 && abs(snake.coor[0].y - snake.coor[i + 1].y) <= 5)
		{
			end_flag = 1;
		}
	}

	//绘制食物
	if (food.flag)
	{
		solidcircle(food.x, food.y, RADIUS);//画实心圆代表蛇的节
	}

	EndBatchDraw();
}

//通过按键改变蛇的方向
void Snake_Move()
{
	//身体跟着头动
	if (end_flag == 0)
	{
		for (int i = snake.size - 1; i > 0; i--)
		{
			snake.coor[i] = snake.coor[i - 1];
		}
	}
	else//蛇头碰到蛇身就暂停
	{
		return;
	}

	//蛇头改变坐标,蛇身从蛇尾一个个往前
	switch (snake.dir)
	{
		case UP:
			if (snake.coor[0].y <= 5) //snake.coor[0].y是圆心,圆心等于5的时候就是碰到墙了
			{
				end_flag = 1;
				return;
				//snake.coor[0].y = 480;
			}
			snake.coor[0].y -= snake.speed;
			break;
		case DOWN:
			if (snake.coor[0].y >= 475) //snake.coor[0].y是圆心,圆心等于5的时候就是碰到墙了
			{
				end_flag = 1;
				return;
				//snake.coor[0].y = 0;
			}
			snake.coor[0].y += snake.speed;
			break;		
		case RIGHT:	
			if (snake.coor[0].x >= 635) //snake.coor[0].y是圆心,圆心等于5的时候就是碰到墙了
			{
				end_flag = 1;
				return;
			}
			snake.coor[0].x += snake.speed;
			break;		
		case LEFT:
			if (snake.coor[0].x <= 5) //snake.coor[0].y是圆心,圆心等于5的时候就是碰到墙了
			{
				end_flag = 1;
				return;

			}
			snake.coor[0].x -= snake.speed;
			break;
	}
}


void Eat_Food()
{

	if (food.flag==true&&abs(snake.coor[0].x - food.x)<food.r && abs(snake.coor[0].y - food.y) <food.r)
	{
		food.flag = false;
		snake.size++;
	}
	if (!food.flag)
	{
		food.x = rand() % 580 + 20;
		food.y = rand() % 420 + 20;
		food.color = RGB(rand() % 256, rand() % 256, rand() % 256);
		food.r = RADIUS;
		food.flag = true;
	}

}


//_getch是阻塞函数
//做界面1,创建一个窗口,图形窗口
int main(void)
{
	end_flag = 0;
	memset(cgrade, 0, 10);//数组清零
	Game_Init();
	while (1)
	{
		Key_Control();
		Game_Draw();
		Snake_Move();
		Eat_Food();
		Sleep(60);
	}

	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值