easyx图形库基础4:贪吃蛇

贪吃蛇

  • 一实现贪吃蛇:
    • 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;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

springboot里 运用 easyexcel 导出

引入pom <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.2.6</version> </dependency>运用 import com.alibaba.excel.EasyExcel; import org.springframework.stereotype.Contr…

【算法篇C++实现】常见排序算法

文章目录 &#x1f680;一、选择排序&#x1f680;二、冒泡排序&#x1f680;三、插入排序&#x1f680;四、希尔排序&#x1f680;五、堆排序&#x1f680;六、归并排序&#x1f680;七、快速排序⛳总结&#xff1a; &#x1f680;一、选择排序 算法精炼每趟从待排序的记录中…

Ceph分布式存储系统优化分析

Ceph支持多种存储访问接口&#xff0c;现有的多种性能测试工具都可用于Ceph的性能测试&#xff0c;如测试块接口性能的fio&#xff0c;iometer等&#xff1b;测试CephFS接口的filebench&#xff0c;fio等;测试对象接口的cosbench等。Ceph有专用的基准测试集CBT&#xff0c;其包…

web实现酷炫的canvas粒子动画背景

文章目录 前言一、particle-bg1. git地址&#xff1a;2. 安装3. 使用4. 完整demo 二、tsParticles1. 源码地址&#xff1a;2. 安装3. 引入4. 使用5. 几个例子5.1 ts粒子五彩纸屑烟花5.2 多粒子产卵器-用tsParticles制作5.3 ts粒子鼠标吸引力5.4 粒子烟花 源码地址完结 前言 粒…

【RP2040】香瓜树莓派RP2040之自定义的短按、双击、长按按键

本文最后修改时间&#xff1a;2022年09月15日 11:02 一、本节简介 本节介绍如何编写一个可以自己选择引脚的短按、双击、长按三种方式的按键驱动。 二、实验平台 1、硬件平台 1&#xff09;树莓派pico开发板 ①树莓派pico开发板*2 ②micro usb数据线*2 2&#xff09;电脑…

【运维】linkis安装dss保姆级教程与踩坑实践

文章目录 一. 安装准备二. 创建用户三. 准备安装包四. 修改配置1. 修改config.sh2. 修改db.sh 五、安装和使用1. 执行安装脚本2. 启动服务3. 查看验证是否成功 六. 报错处理报错一&#xff1a;The user is not logged in报错二&#xff1a;dss接口报错报错三&#xff1a;执行没…

IDEA常用工具配置

IDEA常用工具&配置 如果发现插件市场用不了&#xff0c;可以设置Http Proxy&#xff0c;在该界面上点击”Check connection“并输入的地址&#xff1a;https://plugins.jetbrains.com/ 。 一、常用插件 1、MybatisX Mybaits Plus插件&#xff0c;支持java与xml互转 2、F…

TCP/IP协议组

TCP/IP通信协议是目前最完整、使用最广泛的通信协议。它的魅力在于可使不同硬件结构、不同操作系统的计算机相互通信。TCP/IP协议既可用于广域网&#xff0c;也可用于局域网&#xff0c;它是Internet/Intranet的基石。TCP/IP通信协议事实上是一组协议。 TCP/IP协议可分为5层也可…

日志系统——日志格式化模块设计

一&#xff0c;模块主要成员 该模块的主要作用是对日志消息进行格式化&#xff0c;将日志消息组织成制定格式的字符串。 该模块主要成员有两个&#xff1a;1.格式化字符串。 2.格式化子项数组 1.1 格式化字符串 格式化字符串的主要功能是保存日志输出的格式字符串。其格式化字…

机器学习赋能乳腺癌预测:如何使用贝叶斯分级进行精确诊断?

一、引言 乳腺癌是女性最常见的恶性肿瘤之一&#xff0c;也会发生在男性身上。每年全球有数百万人被诊断出乳腺癌&#xff0c;对患者的生活和健康造成了巨大的影响。早期的乳腺癌检测和准确的诊断对于提高治疗的成功率至关重要。然而&#xff0c;乳腺癌的早期诊断面临着许多挑战…

大语言模型与语义搜索;钉钉个人版启动内测,提供多项AI服务

&#x1f989; AI新闻 &#x1f680; 钉钉个人版启动内测&#xff0c;提供多项AI服务 摘要&#xff1a;钉钉个人版正式开始内测&#xff0c;面向小团队、个人用户、高校大学生等人群。该版本具有AI为核心的功能&#xff0c;包括文生文AI、文生图AI和角色化对话等。用户可通过…

整理mongodb文档:find方法查询数据

个人博客 整理mongodb文档:find方法查询数据 求关注&#xff0c;求批评&#xff0c;求指出&#xff0c;如果哪儿不清晰&#xff0c;请指出来&#xff0c;谢谢 文章概叙 如题&#xff0c;本文讲的是如何用find查询数据&#xff0c;如何在数组、字段、对象中查询&#xff0c;以…

Git 常用操作

一、Git 常用操作 1、Git 切换分支 git checkout命令可以用于三种不同的实体&#xff1a;文件&#xff0c;commit&#xff0c;以及分支。checkout的意思就是对于一种实体的不同版本之间进行切换的操作。checkout一个分支&#xff0c;会更新当前的工作空间中的文件&#xff0c;…

Web菜鸟教程 - Springboot接入认证授权模块

网络安全的重要性不言而喻&#xff0c;如今早已不是以前随便弄个http请求就能爬到数据的时代&#xff0c;而作为一个架构师&#xff0c;网络安全必须在产品开发之初就考虑好。因为在产品开发的后期&#xff0c;一方面是客户增多&#xff0c;压力变大&#xff0c;可供利用的时间…

JupyterHub实战应用

一、JupyerHub jupyter notebook 是一个非常有用的工具&#xff0c;我们可以在浏览器中任意编辑调试我们的python代码&#xff0c;并且支持markdown 语法&#xff0c;可以说是科研利器。但是这种情况适合个人使用&#xff0c;也就是jupyter notebook以我们自己的主机作为服务器…

iOS设计规范是什么?都有哪些具体规范

iOS设计规范是苹果为移动设备操作系统iOS制定的设计指南。iOS设计规范的制定保证了苹果应用在外观和操作上的一致性和可用性&#xff0c;从而提高了苹果界面设计的用户体验和应用程序的成功性。本文将从七个方面全面分析iOS设计规范。 1.iOS设计规范完整版分享 由「即时设计」…

容器和云原生(二):Docker容器化技术

目录 Docker容器的使用 Docker容器关键技术 Namespace Cgroups UnionFS Docker容器的使用 首先直观地了解docker如何安装使用&#xff0c;并快速启动mysql服务的&#xff0c;启动时候绑定主机上的3306端口&#xff0c;查找mysql容器的ip&#xff0c;使用mysql -h contain…

设计模式——建造者(Builder)模式

建造者模式&#xff08;Builder Pattern&#xff09;&#xff0c;又叫生成器模式&#xff0c;是一种对象构建模式 它可以将复杂对象的建造过程抽象出来&#xff0c;使这个抽象过程的不同实现方法可以构造出不同表现的对象。建造者模式是一步一步创建一个复杂的对象&#xff0c;…

Python文件操作教程,Python文件操作笔记

文件的打开与关闭 想一想&#xff1a; 如果想用word编写一份简历&#xff0c;应该有哪些流程呢&#xff1f; 打开word软件&#xff0c;新建一个word文件写入个人简历信息保存文件关闭word软件 同样&#xff0c;在操作文件的整体过程与使用word编写一份简历的过程是很相似的…

使用 BERT 进行文本分类 (01/3)

摄影&#xff1a;Max Chen on Unsplash 一、说明 这是使用 BERT 语言模型的一系列文本分类演示的第一部分。以文本的分类作为例&#xff0c;演示它们的调用过程。 二、什么是伯特&#xff1f; BERT 代表 来自变压器的双向编码器表示。 首先&#xff0c;转换器是一种深度学习模…