贪吃蛇C语言实现(有源码)

前言

之前学了一点easyx图形库的使用,掌握一些基本用法后就用贪吃蛇来进行实战了,运行视频放在csdn视频那一栏了,之前的烟花也是。

1.头文件

#define _CRT_SECURE_NO_WARNINGS 1
#include<easyx.h>
#include<conio.h>
#include<time.h>
#include<stdlib.h>
#include<stdbool.h>
#define NODE_HIGHT 40
#define NODE_WIDTH 40
typedef enum direction
{
	up,
	down,
	left,
	right,
}direction;
typedef struct node
{
	int x, y;
}node;

2.源文件

#include"snack.h"
void Paintgrid()
{
	for (int x = 0; x < 800; x += NODE_WIDTH)
		line(x, 0, x, 600);
	for (int y = 0; y < 600; y += NODE_WIDTH)
		line(0, y, 800, y);
}
void PaintSnack(node* nodes, int n)
{
	int left, right, top, bottom;
	for (int i = 0; i < n; i++)
	{
		left = nodes[i].x * NODE_WIDTH;
		top = nodes[i].y * NODE_WIDTH;
		right = (nodes[i].x + 1) * NODE_WIDTH;
		bottom = (nodes[i].y + 1) * NODE_WIDTH;
		solidrectangle(left, top, right, bottom);
	}
}
node* SnackMove(node* nodes, int length, int direction)
{
	node x = nodes[length - 1];
	for (int i = length - 1; i > 0; i--)
	{
		nodes[i] = nodes[i - 1];
	}
	node new_head = nodes[0];
	if (direction == up)
		new_head.y--;
	if (direction == down)
		new_head.y++;
	if (direction == left)
		new_head.x--;
	if (direction == right)
		new_head.x++;
	nodes[0] = new_head;
	return &x;
}
void playerchoice(direction* dir)
{
	if (_kbhit())
		switch (_getch())
		{
		case 'A':
		case'a':
			if (*dir != left)
				*dir = left;
			break;
		case 'd':
		case'D':
			if (*dir != right)
				*dir = right;
			break;
		case 'w':
		case'W':
			if (*dir != up)
				*dir = up;
			break;
		case 's':
		case'S':
			if (*dir != down)
				*dir = down;
			break;
		}
}
void setfood(node* food,node*nodes,int length,int* flag)
{
	srand((unsigned)time(NULL));
	if (*flag == 0)
	{
	again:
		food->x = rand() % (800 / NODE_WIDTH);
		food->y = rand() % (600 / NODE_HIGHT);
		for (int i = 0; i < length; i++)
		{
			if (food->x == nodes[i].x && food->y == nodes[i].y)
				goto again;
		}
		*flag= 1;
	}
	setfillcolor(YELLOW);
	solidrectangle(food->x * NODE_WIDTH, food->y * NODE_HIGHT, (food->x + 1) * NODE_WIDTH, (food->y + 1) * NODE_HIGHT);
	setfillcolor(WHITE);
 }
 bool isover(node* nodes,int length)
{
	 if (nodes->x >= 800/NODE_WIDTH || nodes->x < 0 || nodes->y < 0 || nodes->y>=600/NODE_HIGHT)
		 return true;
	 for (int i = 1; i < length; i++)
		 if (nodes->x == nodes[i].x && nodes->y == nodes[i].y)
			 return true;
	 return FALSE;
}
 void reset(node* nodes, int* length, direction* dir,int*flag)
 {
	 nodes[0] = { 5,7 };
	 nodes[1] = { 4,7 };
	 nodes[2] = { 3,7 };
	 nodes[3] = {2,7};
	 nodes[4] = {1,7};
	 *length = 5;
	 *dir = right;
	 *flag = 0;
 }
 int main()
 {
	 srand((unsigned)time(NULL));
	 initgraph(800, 600);
	 setbkcolor(RGB(164, 225, 202));
	 direction dir = right;
	 int  length = 5;
	 node nodes[100] = { {5,7},{4,7},{3,7},{2,7},{1,7} };//从蛇头到蛇尾
	 node food = { 0 };
	 int flag = 0;
	 while (1)
	 {
		 cleardevice();
		 Paintgrid();//初始化表格

		 setfood(&food, nodes, length, &flag);
		 PaintSnack(nodes, length);
		 Sleep(500);
		 playerchoice(&dir);
		 node* end = SnackMove(nodes, length, dir);
		 if (nodes[0].x == food.x && food.y == nodes[0].y)
		 {
			 length++;
			 nodes[length - 1].x = end->x;
			 nodes[length - 1].y = end->y;
			 flag = 0;
		 }
		 if (isover(nodes, length))
		 {
			 reset(nodes, &length, &dir,&flag);
		 }
	 }
	 closegraph();
	 return 0;
 }

3.解析

0.创建环境

我使用的是vs编译环境和easyx图形库,貌似easyx也支持Dev,具体的下载方法可以去吧站搜索,easyx的使用在吧站也有相关 教程,包括vs的下载都有很详细的视频教程,所以就不再赘述了。

我们由于要用到随机数所以使用了<time.h><stdlib.h>头文件

关于随机数的使用若是不了解可以看看这篇博客

C语言rand函数,srand函数,time函数实现随机数,及猜数字小游戏-CSDN博客

图形库的使用需要<easyx.h>头文件

第一行的宏定义想必用vs的都知道,用来避免报错的

两个结构体是用来记录蛇的移动方向和坐标的。

#define _CRT_SECURE_NO_WARNINGS 1
#include<easyx.h>
#include<conio.h>
#include<time.h>
#include<stdlib.h>
#include<stdbool.h>
#define NODE_HIGHT 40
#define NODE_WIDTH 40
typedef enum direction
{
    up,
    down,
    left,
    right,
}direction;
typedef struct node
{
    int x, y;
}node;

我们只要知道以下几点就可以

1.把地图画出来

void Paintgrid()
{
    for (int x = 0; x < 800; x += NODE_WIDTH)
        line(x, 0, x, 600);
    for (int y = 0; y < 600; y += NODE_WIDTH)
        line(0, y, 800, y);
}

2.初始化并记录蛇的每个节点的坐标

void PaintSnack(node* nodes, int n)
{
    int left, right, top, bottom;
    for (int i = 0; i < n; i++)
    {
        left = nodes[i].x * NODE_WIDTH;
        top = nodes[i].y * NODE_WIDTH;
        right = (nodes[i].x + 1) * NODE_WIDTH;
        bottom = (nodes[i].y + 1) * NODE_WIDTH;
        solidrectangle(left, top, right, bottom);
    }
}

3.随机产生食物

void setfood(node* food,node*nodes,int length,int* flag)
{
    srand((unsigned)time(NULL));
    if (*flag == 0)
    {
    again:
        food->x = rand() % (800 / NODE_WIDTH);
        food->y = rand() % (600 / NODE_HIGHT);
        for (int i = 0; i < length; i++)
        {
            if (food->x == nodes[i].x && food->y == nodes[i].y)
                goto again;
        }
        *flag= 1;
    }
    setfillcolor(YELLOW);
    solidrectangle(food->x * NODE_WIDTH, food->y * NODE_HIGHT, (food->x + 1) * NODE_WIDTH, (food->y + 1) * NODE_HIGHT);
    setfillcolor(WHITE);
 }

4.蛇移动坐标随之变化

node* SnackMove(node* nodes, int length, int direction)
{
    node x = nodes[length - 1];
    for (int i = length - 1; i > 0; i--)
    {
        nodes[i] = nodes[i - 1];
    }
    node new_head = nodes[0];
    if (direction == up)
        new_head.y--;
    if (direction == down)
        new_head.y++;
    if (direction == left)
        new_head.x--;
    if (direction == right)
        new_head.x++;
    nodes[0] = new_head;
    return &x;
}
void playerchoice(direction* dir)
{
    if (_kbhit())
        switch (_getch())
        {
        case 'A':
        case'a':
            if (*dir != left)
                *dir = left;
            break;
        case 'd':
        case'D':
            if (*dir != right)
                *dir = right;
            break;
        case 'w':
        case'W':
            if (*dir != up)
                *dir = up;
            break;
        case 's':
        case'S':
            if (*dir != down)
                *dir = down;
            break;
        }
}

5.蛇吃到食物会长长

//主函数中

 if (nodes[0].x == food.x && food.y == nodes[0].y)
 {
     length++;
     nodes[length - 1].x = end->x;
     nodes[length - 1].y = end->y;
     flag = 0;
 }

6.碰到边界或自己会死,并设置游戏重开功能

 bool isover(node* nodes,int length)
{
     if (nodes->x >= 800/NODE_WIDTH || nodes->x < 0 || nodes->y < 0 || nodes->y>=600/NODE_HIGHT)
         return true;
     for (int i = 1; i < length; i++)
         if (nodes->x == nodes[i].x && nodes->y == nodes[i].y)
             return true;
     return FALSE;
}

//主函数中

 if (isover(nodes, length))
 {
     reset(nodes, &length, &dir,&flag);
 }

7.主函数调用函数

     srand((unsigned)time(NULL));
     initgraph(800, 600);
     setbkcolor(RGB(164, 225, 202));
     direction dir = right;
     int  length = 5;
     node nodes[100] = { {5,7},{4,7},{3,7},{2,7},{1,7} };//从蛇头到蛇尾
     node food = { 0 };
     int flag = 0;
     while (1)
     {
         cleardevice();
         Paintgrid();//初始化表格

         setfood(&food, nodes, length, &flag);
         PaintSnack(nodes, length);
         Sleep(500);
         playerchoice(&dir);
         node* end = SnackMove(nodes, length, dir);
         if (nodes[0].x == food.x && food.y == nodes[0].y)
         {
             length++;
             nodes[length - 1].x = end->x;
             nodes[length - 1].y = end->y;
             flag = 0;
         }
         if (isover(nodes, length))
         {
             reset(nodes, &length, &dir,&flag);
         }
     }
     closegraph();

总结

一直想写个小游戏玩玩,现在也算是小小的玩了一把,可惜最近要复习,没有时间学图形库了,不然真希望继续做点东西。最后祝愿还没考的同学考出好成绩,考完的寒假快乐,工作的早点放假,

若是觉得这篇博客对你有帮助就点个赞支持一下博主吧,感谢!

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

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

相关文章

odoo17 | 基本视图

前言 我们在上一章中已经看到Odoo能够为给定模型生成默认视图。在实践中&#xff0c;默认视图是绝对不可接受的用于商业应用程序。相反&#xff0c;我们至少应该以逻辑方式组织各种字段。 视图在带有动作和菜单的XML文件中定义。它们是ir.ui.view模型的实例。 在我们的房地产…

YOLO+SlowFast+DeepSORT 简单实现视频行为识别

前段时间刷短视频看到过别人用摄像头自动化监控员工上班状态&#xff0c;比如标注员工是不是离开了工位&#xff0c;在位置上是不是摸鱼。虽然是段子&#xff0c;但是这个是可以用识别技术实现一下&#xff0c;于是我在网上找&#xff0c;知道发现了 SlowFast&#xff0c;那么下…

Sharding-JDBC快速使用【笔记】

1 引言 最近在使用Sharding-JDBC实现项目中数据分片、读写分离需求&#xff0c;参考官方文档&#xff08;Sharding官方文档&#xff09;感觉内容庞杂不够有条理&#xff0c;重复内容比较多&#xff1b;现结合项目应用整理笔记如下供大家参考和自己回忆使用&#xff1b; 在…

苹果手机数据删除怎么恢复?这几个方法值得一试!

不小心删除了iPhone里的照片&#xff1f;别担心&#xff0c;数据恢复是有可能的&#xff01; 从这里&#xff0c;你可以找到你的备份并恢复丢失的数据。如果你没有备份&#xff0c;那么数据恢复软件可能可以帮助你。它们可以扫描你的iPhone或iTunes备份&#xff0c;找到你删除…

打字练习(Python代码模拟打字练习软件效果)

Python代码模拟打字练习软件效果&#xff0c;循环进行单行打字练习&#xff0c;结束时输出平均速度和综合正确率。 (笔记模板由python脚本于2024年01月03日 22:36:34创建&#xff0c;本篇笔记适合熟悉Python字符串和列表基本数据类型的coder翻阅) 【学习的细节是欢悦的历程】 P…

如何利用Oracle官方网站不登录账号下载和安装非最新版本的JDK(版本自由选择)

一、JDK概述 JDK&#xff08;Java Development Kit&#xff09;是Java开发工具集&#xff0c;是针对Java编程语言的软件开发环境。它包含了Java编译器、JRE&#xff08;Java运行时环境&#xff09;以及其他一些用于开发、调试和测试Java应用程序的工具&#xff0c;是Java开发人…

通用Mapper怎么开接口扫描

作者简介&#xff1a;大家好&#xff0c;我是smart哥&#xff0c;前中兴通讯、美团架构师&#xff0c;现某互联网公司CTO 联系qq&#xff1a;184480602&#xff0c;加我进群&#xff0c;大家一起学习&#xff0c;一起进步&#xff0c;一起对抗互联网寒冬 学习必须往深处挖&…

三维模型数据的几何坐标变换的点云重建并行计算技术方法分析

三维模型数据的几何坐标变换的点云重建并行计算技术方法分析 倾斜摄影三维模型数据的几何坐标变换与点云重建并行计算技术的探讨主要涉及以下几个方面&#xff1a; 1、坐标系定义与转换&#xff1a;在进行坐标变换前&#xff0c;需要确定各个参考系的定义并实现坐标系之间的转…

[Angular] 笔记 15:模板驱动表单 - 表单验证

油管视频&#xff1a; Form Validation 有三种类型的验证&#xff1a; valid, pristine(是否被编辑过&#xff0c;被改过)&#xff0c;以及 touched 相反的属性&#xff1a; invalid, dirty, untouched pokemon-template-form.component.html 代码修改&#xff1a; 任何时候…

geemap学习笔记040:GEE中样本点选择操作流程

前言 geemap中目前有一个bug&#xff0c;就是在选择样本点的时候不合理&#xff0c;选完一类样本之后&#xff0c;没法继续选择下一类&#xff0c;并且没法在线进行编辑和修改。因此目前就只能结合在线版的GEE进行样本选择&#xff0c;本节就详细的介绍一下GEE中样本点的选择过…

Transformer 架构解释

一、说明 变形金刚是机器学习的一个新发展&#xff0c;最近引起了很大的轰动。他们非常善于跟踪上下文&#xff0c;这就是为什么他们写的文本有意义。在本章中&#xff0c;我们将介绍它们的体系结构以及它们的工作原理。 amanatulla1606 Transformer 模型是机器学习中最令人兴奋…

机器学习期末复习

机器学习 选择题名词解释&#xff1a;简答题计算题一、线性回归二、决策树三、贝叶斯 选择题 机器学习利用经验 &#xff0c;须对以下&#xff08;&#xff09;进行分析 A 天气 B 数据 C 生活 D 语言 归纳偏好值指机器学习算法在学习的过程中&#xff0c;对以下&#xff08;&a…

酷开系统小酷少儿重磅升级!陪伴孩子美好童年!

孩子的成长总是匆匆太匆匆&#xff0c;父母们应该放慢脚步&#xff0c;感悟童心。用心灵和智慧陪伴孩子&#xff0c;在孩子的心中没有什么比幸福的家庭更重要&#xff0c;没有什么比父母的陪伴更美好&#xff01;酷开系统少儿频道全面升级&#xff01;让酷开系统小酷少儿陪伴成…

设计模式篇章(1)——理论基础

设计模式&#xff1a;在软件开发中会面临许多不断重复发生的问题&#xff0c;这些问题可能是代码冗余、反复修改旧代码、重写以前的代码、在旧代码上不断堆新的代码&#xff08;俗称屎山&#xff09;等难以扩展、不好维护的问题。因此1990年有四位大佬&#xff08;GoF组合&…

ant design pro 5 企业级后台前端框架自定义根路径设置,解决public文件夹下资源在打包部署后出现找不到的问题

关于ant design pro v5的开箱使用方法见&#xff1a;开箱即用的企业级数据和业务管理中后台前端框架Ant Design Pro 5的开箱使用和偏好配置-CSDN博客 在开发过程中为了方便我们可能会将部分静态资源如logo等放入public文件夹&#xff0c;但在设置站点根路径后&#xff0c;publi…

5.云原生安全之ingress配置域名TLS证书

文章目录 cloudflare配置使用cloudflare托管域名获取cloudflare API Token在cloudflare中配置SSL/TLS kubesphere使用cert-manager申请cloudflare证书安装证书管理器创建Secret资源创建cluster-issuer.yaml创建cert.yaml申请证书已经查看申请状态 部署harbor并配置ingress使用证…

iec61850规约原理和工作原理

规约下载 https://products.iec.ch/view/search/all 规约整体介绍 ** IEC104和IEC61850的区别 ** modbus和IEC61850有什么区别 IEC61850简要介绍 变电站通信体系IEC61850将变电站通信体系分为3层站控层、间隔层、过程层。 IEC61850标准的服务实现主要分为三个部分&#xff…

运输层

title: 运输层 date: 2023-12-24 14:17:55 tags: 知识总结 categories: 计算机网络 运输层和网络层的联系和区别 物理层、数据链路层以及网络层它们共同解决了将主机通过异构网络互联起来所面临的问题&#xff0c;实现了主机到主机的通信&#xff0c;但实际上&#xff0c;在计…

奋楫扬帆,奔赴新程 | 2023 年图扑大事记回顾,与您携手共迎 2024

2023.01 工信部公示了 2022 年度智能制造示范工厂揭榜单位和优秀场景名单。图扑软件和上海洲邦合作建设的宁波甬友数字孪生工厂被评为优秀场景&#xff0c;全国共有 369 个智能制造典型场景入选。 2023.01 在第十一届中国创新创业大赛全国赛&#xff08;新一代信息技术&#…

idea 弹框提示:Server‘s certificate is not trusted 解决办法

如图所示&#xff1a; 引起这个的根本原因:是因为你破解了idea&#xff0c;在本地hosts配置了映射&#xff0c;然后idea检测出来弹出警告 服务器证书不可用。所以在弹出这个框。 解决方法&#xff1a; 打开idea--->File-->Settings-->Tools-->点击Server Certifi…