easyx图形库基础4:贪吃蛇

news2025/7/19 14:52:42

贪吃蛇

  • 一实现贪吃蛇:
    • 1.绘制网格:
    • 1.绘制蛇:
    • 3.控制蛇的默认移动向右:
    • 4.控制蛇的移动方向:
    • 5.生成食物
    • 6.判断蛇吃到食物并且长大。
    • 7.判断游戏结束:
    • 8.重置函数:
  • 二整体代码:

一实现贪吃蛇:

1.绘制网格:

请添加图片描述

#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.绘制蛇:

请添加图片描述

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;
}
//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 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.控制蛇的移动方向:

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.食物是随机生成的;

//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;
		}
	}
}

//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.判断蛇吃到食物并且长大。

请添加图片描述

//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);
}
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.蛇头碰到蛇身体:

//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.重置函数:

//初始化函数
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 };
}

二整体代码:

#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;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/885210.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

今年七夕情人节,要送数码产品给对象?这几款送人不出错的数码产品

时间过的还挺快的又到了今年的七夕情人节了&#xff0c;你是否还在为送什么数码产品给对象而犯愁&#xff1f;做过功课挑选的数码好物肯定会让TA十分惊喜&#xff0c;作为一个数码发烧友&#xff0c;我盘点了几款适合送对象的数码好物&#xff0c;大家可以甄选看看。 第一款&a…

LeetCode--HOT100题(32)

目录 题目描述&#xff1a;138. 复制带随机指针的链表&#xff08;中等&#xff09;题目接口解题思路代码 PS: 题目描述&#xff1a;138. 复制带随机指针的链表&#xff08;中等&#xff09; 给你一个长度为 n 的链表&#xff0c;每个节点包含一个额外增加的随机指针 random &…

【C++】位图与布隆过滤器(内含相关高频面试题)

本篇文章会对位图和布隆过滤器进行详解。同时还会给出位图和布隆过滤器相关的高频面试题与解答。希望本篇文章会对你有所帮助。 文章目录 一、位图的引入 1、1 查找整数&#xff08;腾讯面试题&#xff09; 1、2 解决方法1 1、3 解决方法2 1、3、1 外部排序 二、位图的原理与…

电压调整器之LDO稳压器电路 士兰微SA1117B系列SA1117BH-ADJTR

关于LDO调节器&#xff08;Low Dropout Regulator&#xff09;是一种电压稳压器件&#xff0c;常用于电子设备中&#xff0c;用于将高电压转换为稳定的低电压。它能够在输入电压和输出电压之间产生较小的差异电压&#xff0c;因此被称为"低压差稳压器"。 LDO调节器通…

Llama 2免费托管及API提供

Llama 2 是 Meta 最新的文本生成模型&#xff0c;目前其性能优于所有开源替代方案。 推荐&#xff1a;用 NSDT编辑器 快速搭建可编程3D场景 1、强大的Llama 2 它击败了 Falcon-40B&#xff08;之前最好的开源基础模型&#xff09;&#xff0c;与 GPT-3.5 相当&#xff0c;仅低…

禁止特斯拉入内 — 智能驾驶引发的“争议”与“合规”之路

近日&#xff0c;湖南岳阳三荷机场停车场禁止特斯拉入内引发关注&#xff0c;原因在于车主离开车辆后&#xff0c;特斯拉自带的哨兵模式会对车身周边环境进行录像。实际上&#xff0c;之前就有网友提到军事禁区、党政机关、重点政府单位、重点国有企业等也是不允许特斯拉进入。…

电商增强现实3D模型优化需要关注的4个方面

到目前为止&#xff0c;AR技术已经发展到足以在更广泛的范围内实施。 在电子商务中&#xff0c;这项技术有望提供更令人兴奋的购物体验。 为了实现这一目标&#xff0c;在这篇博客中&#xff0c;我将介绍如何针对电子商务中的 AR 优化 3D 模型。 推荐&#xff1a;用 NSDT编辑器…

【hadoop】windows上hadoop环境的搭建步骤

文章目录 前言基础环境下载hadoop安装包下载hadoop在windows中的依赖配置环境变量 Hadoop hdfs搭建创建hadfs数据目录修改JAVA依赖修改配置文件初始化hdfs namenode启动hdfs 前言 在大数据开发领域中&#xff0c;不得不说说传统经典的hadoop基础计算框架。一般我们都会将hadoo…

LeetCode 160.相交链表

文章目录 &#x1f4a1;题目分析&#x1f4a1;解题思路&#x1f6a9;步骤一&#xff1a;找尾节点&#x1f6a9;步骤二&#xff1a;判断尾节点是否相等&#x1f6a9;步骤三&#xff1a;找交点&#x1f344;思路1&#x1f344;思路2 &#x1f514;接口源码 题目链接&#x1f449;…

九五从零开始的运维之路(其三十五)

文章目录 前言一、概述1.概念2.组成3.特点4.工作原理5.优点&#xff1a; 二、各节点及其ip地址三、构建MHA1.ssh免密登录2.构建mysql主从复制&#xff08;一&#xff09;安装mariadb数据库并启动&#xff08;二&#xff09;master服务器&#xff08;三&#xff09;slave服务器&…

【Java转Go】快速上手学习笔记(二)之基础篇一

目录 创建项目数据类型变量常量类型转换计数器键盘交互流程控制代码运算符 创建项目 上篇我们安装好了Go环境&#xff0c;和用IDEA安装Go插件来开发Go项目&#xff1a;【Java转Go】快速上手学习笔记&#xff08;一&#xff09;之环境安装篇 。 这篇我们开始正式学习Go语言。我…

【数据结构OJ题】链表中倒数第k个结点

原题链接&#xff1a;https://www.nowcoder.com/practice/529d3ae5a407492994ad2a246518148a?tpId13&&tqId11167&rp2&ru/activity/oj&qru/ta/coding-interviews/question-ranking 目录 1. 题目描述 2. 思路分析 3. 代码实现 1. 题目描述 2. 思路分析 …

数据结构的树存储结构

数据结构的树存储结构 之前介绍的所有的数据结构都是线性存储结构。本章所介绍的树结构是一种非线性存储结构&#xff0c;存储的是具有“一对多”关系的数据元素的集合。 (A) (B) 图 1 树的示例 图 …

vue树状结构以及设计思路

设计思路&#xff1a;多级数组循环遍历&#xff0c;第一层样式加三角形折叠&#xff0c;第二层在文字前方加 —&#xff08;横线&#xff09;&#xff0c;第三层加横线&#xff0c;第四层加点。给第二层第三层左侧加左边框&#xff0c;用translateY进行位移就形成了树状样式。 …

《起风了》C++源代码

使用方法 Visual Studio、Dev-C、Visual Studio Code等C/C创建一个 .cpp 文件&#xff0c;直接粘贴赋值即可。 #include <iostream> #include <Windows.h> #pragma comment(lib,"winmm.lib") using namespace std; enum Scale {Rest 0, C8 108, B7 …

SpringBoot08——前端数据模拟MockJS+vue-element-admin后台集成

感觉用到再说吧 2. vue-element-admin后台集成 3.JWT跨域认证 看自己的demo2源码吧

好用的networkx绘图包

1. NetworkX简介 NetworkX 是一个用于创建、操作和研究复杂网络的 Python 库。它可以创建、分析和可视化各种类型的网络(包括有向图和无向图)&#xff0c;例如社交网络、Web图、生物网络等。 NetworkX 提供了许多图的算法和分析工具&#xff0c;比如节点的度、网络的直径、最短…

jvm内存溢出排查(使用idea自带的内存泄漏分析工具)

文章目录 1.确保生成内存溢出文件2.使用idea自带的内存泄漏分析工具3.具体实验一下 1.确保生成内存溢出文件 想分析堆内存溢出&#xff0c;一定在运行jar包时就写上参数-XX:HeapDumpOnOutOfMemoryError&#xff0c;可以看我之前关于如何运行jar包的文章。若你没有写。可以写上…

express学习笔记8 - 文件上传 下载以及预览

一、上传 1、 安装multer (任意选其中一种) yarn add multer --S npm install multer --S 2、新建配置文件(utils/multerConfig) const multer require(multer); const mkdirp require(mkdirp); // const sd require(silly-datetime); const path require(path);con…

什么叫加杠杆投资_个人炒股如何加杠杆

加杠杆投资是指通过借款或者杠杆交易的方式&#xff0c;以较小的自有资金控制较大的资金进行投资。在加杠杆的情况下&#xff0c;投资者可以获得更高的投资回报&#xff0c;但同时也面临较高的风险。 个人炒股加杠杆可以通过以下几种方式实现&#xff1a; 1. 股票配资&#x…