贪吃蛇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();

总结

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

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

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

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

相关文章

【Vue2+3入门到实战】(21)认识Vue3、使用create-vue搭建Vue3项目、熟悉项目和关键文件

目录 一、认识Vue31. Vue2 选项式 API vs Vue3 组合式API2. Vue3的优势 二、 使用create-vue搭建Vue3项目1. 认识create-vue2. 使用create-vue创建项目 三、 熟悉项目和关键文件四、总结 一、认识Vue3 1. Vue2 选项式 API vs Vue3 组合式API <script> export default {…

力扣题:高精度运算-1.2

力扣题-1.2 [力扣刷题攻略] Re&#xff1a;从零开始的力扣刷题生活 力扣题1&#xff1a;415. 字符串相加 解题思想&#xff1a;从后往前遍历两个字符串,然后进行相加即可 class Solution(object):def addStrings(self, num1, num2):""":type num1: str:type …

Liunx Top命令

Top 是 Linux 下常用的性能分析工具&#xff0c;能够实时动态显示当前系统负载情况、内存使用情况&#xff0c;以及各个进程资源占用情况。 通过 top 命令显示系统整体情况。示例如下&#xff1a; top - 17:51:14 up 69 days, 20:06, 2 users, load average: 71.81, 71.99,…

2024年网络安全合规建设的发展预测

文章目录 前言一、网络安全合规运营工作迎来巨大变革的原因二、网络安全合规运营发展变化的预测预测一 :网络安全合规运营会成为企业业务发展的驱动因素预测二 :企业对网络安全合规运营的投入将继续增加预测三 : 第三方供应商和服务提供商需要为企业分担更多的网络安全风险预…

Navicat 技术干货 | 如何查看关系型数据库(MySQL、PostgreSQL、SQL Server、 Oracle)查询的运行时间

在数据库优化中&#xff0c;理解和监控查询运行时间是至关重要的。无论你是数据库管理员、开发人员或是参与性能调优的人员&#xff0c;知道如何查看查询运行时间能为你的数据库操作提供有价值的参考。本文中&#xff0c;我们将探索几款热门的关系数据库&#xff08;如 MySQL、…

ubuntu下快速安装使用docker

一、ubuntu下安装docker 1、命令行终端内直接输入docker 可以看到安装docker的命令提示 2、安装需要注意的几个点 (1)需要管理员权限 (2)更新软件源后再进行安装 命令行输入命令 sudo apt-get update #更新软件源 sudo apt install docker.io #安装docker 如图所示 二…

PostgreSQL荣获DB-Engines 2023年度数据库

数据库流行度排名网站 DB-Engines 2024 年 1 月 2 日发布文章宣称&#xff0c;PostgreSQL 荣获 2023 年度数据库管理系统称号。 PostgreSQL 在过去一年中获得了比其他 417 个产品更多的流行度增长&#xff0c;因此获得了 2023 年度 DBMS。 DB-Engines 通过计算每种数据库 2024 …

性能优化-OpenMP基础教程(一)

本文主要介绍OpenMP并行编程技术&#xff0c;编程模型、指令和函数的介绍、以及OpenMP实战的几个例子。希望给OpenMP并行编程者提供指导。 &#x1f3ac;个人简介&#xff1a;一个全栈工程师的升级之路&#xff01; &#x1f4cb;个人专栏&#xff1a;高性能&#xff08;HPC&am…

Mysql count统计去重的数据

不去重&#xff0c;是4 &#xff1a; SELECT COUNT(NAME) FROM test2 明显里面包含了2个 name 等于 mike的数据&#xff0c; 所以需要做去重 &#xff1a; 通过结合 count 函数和 DISTINCT 关键字 SELECT COUNT(DISTINCT NAME) FROM test2 好了就到这。

消息中间件 —— ActiveMQ 使用及原理详解

目录 一. 前言 二. JMS 规范 2.1. 基本概念 2.2. JMS 体系结构 三. ActiveMQ 使用 3.1. ActiveMQ Classic 和 ActiveMQ Artemis 3.2. Queue 模式&#xff08;P2P&#xff09; 3.3. Topic 模式&#xff08;Pub/Sub&#xff09; 3.4. 持久订阅 3.5. 消息传递的可靠性 …

数模学习day06-主成分分析

主成分分析(Principal Component Analysis,PCA)主成分分析是一种降维算法&#xff0c;它能将多个指标转换为少数几个主成分&#xff0c;这些主成分是原始变量的线性组合&#xff0c;且彼此之间互不相关&#xff0c;其能反映出原始数据的大部分信息。一般来说当研究的问题涉及到…

C#64位程序调用32位C/C++库方法

步骤 1、编写32位控制台程序2、实现字符串传参3、封装Process类库4、获取进程调用的返回值 在实际的项目中经常使用一些第三方C/C库&#xff0c;于历史原因&#xff0c;有的C库是32位的&#xff0c;由于没有源代码&#xff0c;所以一般很难修改为64位的类库&#xff0c;但又需要…

Global Mapper SDK 19 中文开发文档(十三)完结

7.4 委托的详细描述 7.4.1 GM_Change3DViewCallbackFunc public delegate void GM_Change3DViewCallbackFunc(GM_Rectangle_t aNewViewBounds, //new 3D view boundsIntPtr aUserData //user data passed into GM_3DSetChangeViewCallback function ) 7…

TCM - 紧耦合内存

ARM 的ram包括静态ram&#xff0c;动态ram&#xff0c;TCM---紧耦合内存(TCM: Tightly Coupled Memories)。 TCM是一个固定大小的RAM&#xff0c;紧密地耦合至处理器内核&#xff0c;提供与cache相当的性能&#xff0c;相比于cache的优点是&#xff0c;程序代码可以精确地控制…

当hashCode相同时,equals是否也相同?

在Java中&#xff0c;理解对象的这两个基本方法—hashCode和equals对于编码是至关重要的&#xff0c;尤其是在处理集合类如HashMap和HashSet时。然而&#xff0c;一个常见的误解是&#xff0c;如果两个对象有相同的哈希码&#xff08;hashCode&#xff09;&#xff0c;那么它们…

SQL WHERE 语句(条件选择)

WHERE 子句用于过滤记录。 SQL WHERE 子句 WHERE 子句用于提取那些满足指定条件的记录。 SQL WHERE 语法 SELECT column1, column2, ... FROM table_name WHERE condition; 参数说明&#xff1a; column1, column2, ...&#xff1a;要选择的字段名称&#xff0c;可以为多…

iec104和iec61850

iec104和iec61850 IEC104 规约详细解读(一) 协议结构 IEC104 规约详细解读(二)交互流程以及协议解析 61850开发知识总结与分享【1】 Get the necesarry projects next to each other in the same directory; $ git clone https://github.com/robidev/iec61850_open_server.g…

ES(Elasticsearch)的基本使用

一、常见的NoSQL解决方案 1、redis Redis是一个基于内存的 key-value 结构数据库。Redis是一款采用key-value数据存储格式的内存级NoSQL数据库&#xff0c;重点关注数据存储格式&#xff0c;是key-value格式&#xff0c;也就是键值对的存储形式。与MySQL数据库不同&#xff0…

DNS安全与访问控制

一、DNS安全 1、DNSSEC原理 DNSSEC依靠数字签名保证DNS应答报文的真实性和完整性。权威域名服务器用自己的私有密钥对资源记录&#xff08;Resource Record, RR&#xff09;进行签名&#xff0c;解析服务器用权威服务器的公开密钥对收到的应答信息进行验证。如果验证失败&…

数字信号处理期末复习——计算小题(二)

个人名片&#xff1a; &#x1f981;作者简介&#xff1a;一名喜欢分享和记录学习的在校大学生 &#x1f42f;个人主页&#xff1a;妄北y &#x1f427;个人QQ&#xff1a;2061314755 &#x1f43b;个人邮箱&#xff1a;2061314755qq.com &#x1f989;个人WeChat&#xff1a;V…