easyx图形库基础4:贪吃蛇

贪吃蛇

一实现贪吃蛇:

1.绘制网格:

c 复制代码
#define wide 800
#define high 600

#define Frame 20

//1.绘制边框
void DrawFrame()
{
	setlinecolor(BLACK);
	setlinestyle(PS_SOLID, 1);
	for (int i = 1; i < wide / Frame; i++)
	{
		line(Frame * i, 0, Frame * i, 600);
	}
	for (int i = 1; i < high / Frame; i++)
	{
		line(0, Frame * i,800 , Frame * i);
	}
}

1.绘制蛇:

c 复制代码
int main()
{
	initgraph(wide,high);

	setbkcolor(RGB(188, 227, 245));
	cleardevice();

	//初始化蛇的长度
	int length = 5;
	//初始化蛇的坐标:
	sn snake[5] = { {7,6} ,{6,6}, {5,6},{4,6},{3,6} };
	while (1)
	{
		cleardevice();
		BeginBatchDraw();
		//1.绘制边框
		DrawFrame();
		//2.绘制蛇
		DrawSnake(snake,length);
		FlushBatchDraw();

		Sleep(40);
	}
	EndBatchDraw();
	getchar();
	closegraph();
	return 0;
}
c 复制代码
//2.绘制蛇
void DrawSnake(sn* snake,int length)
{
	setfillcolor(GREEN);
	for (int i = 0; i < length; i++)
	{
		//先绘制头
		int x1 = snake[i].x;
		int y1 = snake[i].y;
		solidrectangle(x1 * Frame, y1 * Frame, (x1 + 1) * Frame, (y1 + 1) * Frame);
	}
}

3.控制蛇的默认移动向右:

c 复制代码
void SnakeMove(sn* snake, int length)
{
	//默认蛇一开始是一直向右移动的;
	sn newsnake = { (snake->x)+1,(snake->y)};
	//2.绘制蛇
	DrawSnake(snake, length);
	FlushBatchDraw();
	


	//进行蛇的移动;
	for (int i = length - 1; i >= 1; i--)
	{
		snake[i] = snake[i - 1];
	}
	snake[0] = newsnake;
}

4.控制蛇的移动方向:

c 复制代码
void SnakeMove(sn* snake, int length,int* vx,int* vy)
{
	//默认蛇一开始是一直向右移动的;
	//2.绘制蛇
	DrawSnake(snake, length);
	FlushBatchDraw();
	//进行蛇的移动;
	if (_kbhit())
	{
		char ch = _getch();
		//蛇是不可以直接走回头路的:
		switch (ch)
		{
			case'A':
			case'a':
				if (*vx == 1 && vy == 0)
					break;
				*vx = -1;
				*vy = 0;
				break;
			case'W':
			case'w':
				if (*vx == 0 && *vy == 1)
					break;
				*vx = 0;
				*vy = -1;
				break;
			case'D':
			case'd':
				if (*vx == -1 && *vy == 0)
					break;
				*vx = 1;
				*vy = 0;
				break;
			case'S':
			case's':
				if (*vx == 0 && *vy == -1)
					break;
				*vx = 0;
				*vy = 1;
				break;
		}
	}
	//控制蛇节点变化
	sn newsnake = { (snake->x)+(*vx) ,(snake->y)+(*vy)};
	for (int i = length - 1; i >= 1; i--)
	{
		snake[i] = snake[i - 1];
	}
	snake[0] = newsnake;
}

5.生成食物

1.食物不可以生成到画布的外面;

2.不可以生成在蛇的身体上面;

3.食物是随机生成的;

c 复制代码
//4.生成食物:
void DrawFeeFood(sn* snake, int length, FD* food)
{		
	int fx = 0;
	int fy = 0;
	int flag = 0;
	while (1)
	{
		//食物坐标的随机生成:
		food->x = rand() % (wide / Frame);
		food->y= rand() % (high / Frame);
		//2.不可以生成在蛇的身体上面,遍历蛇的身体。
		for (int i = 0; i < length; i++)
		{
			if (((food->x) == (snake[i].x)) && ((food->y) == (snake[i].y)))
			{
				flag++;
			}
		}

		if (flag == 0)
		{
			break;
		}
	}
}
c 复制代码
//3.控制蛇的移动
void SnakeMove(sn* snake, int length,FD* food,int* vx,int* vy)
{
	//默认蛇一开始是一直向右移动的;
	//2.绘制蛇
	DrawSnake(snake, length);
	//2.绘制食物:
	if (food->x == 0 && food->y == 0)
	{
		DrawFeeFood(snake, length, food);
	}
	setfillcolor(YELLOW);
	solidrectangle((food->x) * Frame, (food->y) * Frame, (food->x+1) * Frame, (food->y+1) * Frame);
	FlushBatchDraw();
	//进行蛇的移动;
	if (_kbhit())
	{
		char ch = _getch();
		//蛇是不可以直接走回头路的:
		switch (ch)
		{
			case'A':
			case'a':
				if (*vx == 1 && vy == 0)
					break;
				*vx = -1;
				*vy = 0;
				break;
			case'W':
			case'w':
				if (*vx == 0 && *vy == 1)
					break;
				*vx = 0;
				*vy = -1;
				break;
			case'D':
			case'd':
				if (*vx == -1 && *vy == 0)
					break;
				*vx = 1;
				*vy = 0;
				break;
			case'S':
			case's':
				if (*vx == 0 && *vy == -1)
					break;
				*vx = 0;
				*vy = 1;
				break;
		}
	}
	//控制蛇节点变化
	sn newsnake = { (snake->x)+(*vx) ,(snake->y)+(*vy)};
	for (int i = length - 1; i >= 1; i--)
	{
		snake[i] = snake[i - 1];
	}
	snake[0] = newsnake;
}

6.判断蛇吃到食物并且长大。

c 复制代码
//3.控制蛇的移动
void SnakeMove(sn* snake, int* length,FD* food,int* vx,int* vy)
{
	//默认蛇一开始是一直向右移动的;
	//2.绘制蛇
	DrawSnake(snake, *length);
	//3.绘制食物:
	if (food->x == 0 && food->y == 0)
	{
		DrawFeeFood(snake, length, food);
	}
	setfillcolor(YELLOW);
	solidrectangle((food->x) * Frame, (food->y) * Frame, (food->x+1) * Frame, (food->y+1) * Frame);
	FlushBatchDraw();
	//进行蛇的移动;
	if (_kbhit())
	{
		char ch = _getch();
		//蛇是不可以直接走回头路的:
		switch (ch)
		{
			case'A':
			case'a':
				if (*vx == 1 && vy == 0)
					break;
				*vx = -1;
				*vy = 0;
				break;
			case'W':
			case'w':
				if (*vx == 0 && *vy == 1)
					break;
				*vx = 0;
				*vy = -1;
				break;
			case'D':
			case'd':
				if (*vx == -1 && *vy == 0)
					break;
				*vx = 1;
				*vy = 0;
				break;
			case'S':
			case's':
				if (*vx == 0 && *vy == -1)
					break;
				*vx = 0;
				*vy = 1;
				break;
		}
	}
	//控制蛇节点变化
	sn newsnake = { (snake->x)+(*vx) ,(snake->y)+(*vy)};
	for (int i = *length - 1; i >= 1; i--)
	{
		snake[i] = snake[i - 1];
	}
	snake[0] = newsnake;

	//判断蛇是否吃到了食物和生长:
	Grow(snake, length, food);
}
c 复制代码
void Grow(sn* snake, int* length, FD* food)
{
	//保存一下尾的数值
	sn end = snake[(*length) - 1];

	if ((snake[0].x == food->x) && (snake[0].y == food->y))
	{
		//重置食物数值
		food->x = 0;
		food->y = 0;
		//添加尾节点;
		*length = (*length) + 1;
		snake[*length] = end;
	}
}

7.判断游戏结束:

1.蛇头碰到墙壁:

2.蛇头碰到蛇身体:

c 复制代码
//5.判断游戏结束
bool Gameover(sn* snake, int* length)
{
	//1.碰到墙壁
	if ((snake[0].x >= wide / Frame) || (snake[0].x < 0) || (snake[0].y >= high / Frame) || (snake[0].y < 0))
	{
		return true;
	}
	else
	{
		//2.碰到身体
		for (int i = 1; i < (*length); i++)
		{
			if (((snake[0].x)==(snake[i].x))&&((snake[0].y) == (snake[i].y)))
				return true;
		}
	}
	return false;
}

8.重置函数:

c 复制代码
//初始化函数
void initgame(int* length,int* vx,int* vy,sn* snake,FD* food)
{
	//初始化蛇的长度
	*length = 5;
	//初始化蛇的水平初始速度
	*vx = 1;
	*vy = 0;
	//初始化蛇的坐标:
	snake[0] = { 7,6 };
	snake[0] = { 6,6 };
	snake[0] = { 5,6 };
	snake[0] = { 4,6 };
	snake[0] = { 3,6 };
	//初始化食物的坐标;
	*food = { 0,0 };
}

二整体代码:

c 复制代码
#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>
#include<easyx.h>
#include<math.h>
#include<stdbool.h>
#include<conio.h>
#include<time.h>

#define wide 800
#define high 600
#define Frame 20

typedef struct snake {
	int x;
	int y;
}sn;
typedef struct Food {
	int x;
	int y;
}FD;
//1.绘制边框
void DrawFrame()
{
	setlinecolor(BLACK);
	setlinestyle(PS_SOLID, 1);
	for (int i = 1; i < wide / Frame; i++)
	{
		line(Frame * i, 0, Frame * i, 600);
	}
	for (int i = 1; i < high / Frame; i++)
	{
		line(0, Frame * i,800 , Frame * i);
	}
}

//2.绘制蛇
void DrawSnake(sn* snake,int length)
{
	setfillcolor(GREEN);
	for (int i = 0; i < length; i++)
	{
		//先绘制头
		int x1 = snake[i].x;
		int y1 = snake[i].y;
		solidrectangle(x1 * Frame, y1 * Frame, (x1 + 1) * Frame, (y1 + 1) * Frame);
	}
}

//3.生成食物:
void DrawFeeFood(sn* snake, int *length, FD* food)
{		
	int fx = 0;
	int fy = 0;
	int flag = 0;

	while (1)
	{
		//食物坐标的随机生成:
		food->x = rand() % (wide / Frame);
		food->y= rand() % (high / Frame);
		//2.不可以生成在蛇的身体上面,遍历蛇的身体。
		for (int i = 0; i < *length; i++)
		{
			if (((food->x) == (snake[i].x)) && ((food->y) == (snake[i].y)))
			{
				flag++;
			}
		}

		if (flag == 0)
		{
			break;
		}
	}
}

//4判断蛇吃到食物并且长大。
void Grow(sn* snake, int* length, FD* food)
{
	//保存一下尾的数值
	sn end = snake[(*length) - 1];

	if ((snake[0].x == food->x) && (snake[0].y == food->y))
	{
		//重置食物数值
		food->x = 0;
		food->y = 0;
		//添加尾节点;
		*length = (*length) + 1;
		snake[*length] = end;
	}
}

//初始化函数
void initgame(int* length,int* vx,int* vy,sn* snake,FD* food)
{
	//初始化蛇的长度
	*length = 5;
	//初始化蛇的水平初始速度
	*vx = 1;
	*vy = 0;
	//初始化蛇的坐标:
	snake[0] = { 7,6 };
	snake[0] = { 6,6 };
	snake[0] = { 5,6 };
	snake[0] = { 4,6 };
	snake[0] = { 3,6 };
	//初始化食物的坐标;
	*food = { 0,0 };
}
//5.判断游戏结束
bool Gameover(sn* snake, int* length)
{
	//1.碰到墙壁
	if ((snake[0].x >= wide / Frame) || (snake[0].x < 0) || (snake[0].y >= high / Frame) || (snake[0].y < 0))
	{
		return true;
	}
	else
	{
		//2.碰到身体
		for (int i = 1; i < (*length); i++)
		{
			if (((snake[0].x)==(snake[i].x))&&((snake[0].y) == (snake[i].y)))
				return true;
		}
	}
	return false;
}

//6.控制蛇的移动
void SnakeMove(sn* snake, int* length,FD* food,int* vx,int* vy)
{
	//默认蛇一开始是一直向右移动的;
	//2.绘制蛇
	DrawSnake(snake, *length);
	//3.绘制食物:
	if (food->x == 0 && food->y == 0)
	{
		DrawFeeFood(snake, length, food);
	}
	setfillcolor(YELLOW);
	solidrectangle((food->x) * Frame, (food->y) * Frame, (food->x+1) * Frame, (food->y+1) * Frame);
	FlushBatchDraw();
	//进行蛇的移动;
	if (_kbhit())
	{
		char ch = _getch();
		//蛇是不可以直接走回头路的:
		switch (ch)
		{
			case'A':
			case'a':
				if (*vx == 1 && vy == 0)
					break;
				*vx = -1;
				*vy = 0;
				break;
			case'W':
			case'w':
				if (*vx == 0 && *vy == 1)
					break;
				*vx = 0;
				*vy = -1;
				break;
			case'D':
			case'd':
				if (*vx == -1 && *vy == 0)
					break;
				*vx = 1;
				*vy = 0;
				break;
			case'S':
			case's':
				if (*vx == 0 && *vy == -1)
					break;
				*vx = 0;
				*vy = 1;
				break;
		}
	}
	//控制蛇节点变化
	sn newsnake = { (snake->x)+(*vx) ,(snake->y)+(*vy)};
	for (int i = *length - 1; i >= 1; i--)
	{
		snake[i] = snake[i - 1];
	}
	snake[0] = newsnake;

	//判断蛇是否吃到了食物和生长:
	Grow(snake, length, food);
	//判断蛇是否碰到了墙壁和自己
	if (Gameover(snake, length))
	{
		initgame(length, vx, vy, snake, food);
		//Sleep(100);
	}

}

int main()
{
	initgraph(wide,high);
	setbkcolor(RGB(188, 227, 245));
	//获取当前时间作为随机数种子:
	srand((unsigned int)time(NULL));
	cleardevice();

	//初始化蛇的长度
	int length = 5;
	//初始化蛇的水平初始速度
	int vx = 1;
	int vy = 0;
	//初始化蛇的坐标:
	sn snake[100] = { {7,6} ,{6,6}, {5,6},{4,6},{3,6} };
	//初始化食物的坐标;
	FD food = {0,0};


	while (1)
	{
		cleardevice();
		BeginBatchDraw();
		//1.绘制边框
		DrawFrame();
		//2.控制蛇的移动和节点的变化;
		SnakeMove(snake, &length,&food,&vx,&vy);
		Sleep(150);
	}
	EndBatchDraw();
	getchar();
	closegraph();
	return 0;
}
相关推荐
Python大数据分析@3 分钟前
python操作CSV和excel,如何来做?
开发语言·python·excel
上海_彭彭28 分钟前
【提效工具开发】Python功能模块执行和 SQL 执行 需求整理
开发语言·python·sql·测试工具·element
3345543236 分钟前
element动态表头合并表格
开发语言·javascript·ecmascript
沈询-阿里41 分钟前
java-智能识别车牌号_基于spring ai和开源国产大模型_qwen vl
java·开发语言
AaVictory.1 小时前
Android 开发 Java中 list实现 按照时间格式 yyyy-MM-dd HH:mm 顺序
android·java·list
残月只会敲键盘1 小时前
面相小白的php反序列化漏洞原理剖析
开发语言·php
ac-er88881 小时前
PHP弱类型安全问题
开发语言·安全·php
ac-er88881 小时前
PHP网络爬虫常见的反爬策略
开发语言·爬虫·php
爱吃喵的鲤鱼1 小时前
linux进程的状态之环境变量
linux·运维·服务器·开发语言·c++
LuckyLay1 小时前
Spring学习笔记_27——@EnableLoadTimeWeaving
java·spring boot·spring