贪吃蛇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 …

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;其能反映出原始数据的大部分信息。一般来说当研究的问题涉及到…

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

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

图像清晰度评估指标

图像清晰度评估涉及多个指标&#xff0c;这些指标可用于定量测量图像的清晰度和质量。 以下是一些常见的图像清晰度评估指标&#xff1a; 均方根误差&#xff08;Root Mean Square Error&#xff0c;RMSE&#xff09;&#xff1a; 通过计算原始图像和处理后图像之间的像素差异的…

【实用工具】Gradio快速部署深度学习应用1:图像分类

前言 在AI快速发展的今天&#xff0c;我们作为算法开发人员&#xff0c;也应该有一些趁手的工具帮助我们快速开发并验证自己的想法&#xff0c;Gradio可以实现快速搭建和共享的功能&#xff0c;能够展示出一个前端界面&#xff0c;把我们的算法包裹起来&#xff0c;快速验证算…

DNS主从服务器、转发(缓存)服务器

一、主从服务器 1、基本含义 DNS辅助服务器是一种容错设计&#xff0c;考虑的是一旦DNS主服务器出现故障或因负载太重无法及时响应客户机请求&#xff0c;辅助服务器将挺身而出为主服务器排忧解难。辅助服务器的区域数据都是从主服务器复制而来&#xff0c;因此辅助服务器的数…

Vue2多入口,独立打包配置

提示&#xff1a;Vue2多入口&#xff0c;独立打包配置 文章目录 前言一、修改二、打包和效果预览三、具体操作的文件四、代码包总结 前言 需求&#xff1a;富文本编辑器 一、修改 1、复制&#xff1a;index.html文件并改名share.html。 路径&#xff1a;工程文件夹/index.html …

Android studio BottomNavigationView 应用设计

一、新建Bottom Navigation Activity项目&#xff1a; 二、修改bottom_nav_menu.xml: <itemandroid:id"id/navigation_beijing"android:icon"drawable/ic_beijing_24dp"android:title"string/title_beijing" /><itemandroid:id"i…

Excel 插件:ASAP Utilities Crack

ASAP Utilities是一款功能强大的 Excel 插件&#xff0c;填补了 Excel 的空白。在过去的 20 年里&#xff0c;我们的加载项已经发展成为世界上最受欢迎的 Microsoft Excel 加载项之一。 ASAP Utilities 中的功能数量&#xff08;300 多个&#xff09;可能看起来有点令人眼花缭乱…