C语言实现贪吃蛇[内附详细步骤]

article/2025/10/26 8:41:31

C语言贪吃蛇项目

今天给分享一下使用C语言写个贪吃蛇小游戏,主要包含以下10部分内容:

1、windows光标定位与隐藏

2、欢迎界面

3、打印围墙

4、产生食物

5、初始化蛇身

6、响应按键

7、蛇身运动

8、碰撞检测

9、结束界面

10、程序运行

  1. windows光标定位与隐藏

COORD 是window API中定义的一种结构体,表示一个字符在控制台屏幕上的坐标。定义为:

typedef struct_COORD{

SHORT X;  横坐标

SHORT Y;  纵坐标

}COORD;

定位函数gotoxy,gotoDelete

void gotoprint(int x, int y)

{

    gotoxy(x, y);

    printf("■");

}

// 删除蛇尾

void gotoDelete(int x, int y)

{

    gotoxy(x, y);

    printf("  ");

}

2. 欢迎界面

使用gotoxy函数将光标定义到页面相应的位置输出欢迎信息,页面左上角为(0,0)坐标。

将用户输入的姓名信息保存下来以便后面使用。

用户输入姓名后清屏,进入游戏界面。

void welcome()

{

    gotoxy(10, 5);

    printf("/**********************************************/");

    gotoxy(14, 8);

    printf("WELCOME TO THE GAME OF RETRO SNAKE");

    gotoxy(14, 12);

    printf("wasd控制蛇身上下左右运动,反向移动等同于吃到自己导致游戏结束,除了wasd任意键暂停");

    gotoxy(10, 20);

    printf("/**********************************************/");

    gotoxy(14, 16);

    printf("请输入姓名:");

    scanf("%s",username);

    system("cls");        

}

​​​​​​​3.打印围墙

贪吃蛇围墙只需要定位到相应位置输出"■"即可,本次游戏的围墙为57*27

坐标图如下图所示:

 

void creatgraph()

{

int i;

// 横向围墙 58 / 2 == 29列

for (i = 0; i < 58; i += 2)

    {

        gotoprint(i, 0);

        gotoprint(i, 26);

    }

    // 竖向围墙  1-25中间有25行 + 头尾两行  27行

    for (i = 1; i < 26; i++)

    {

        gotoprint(0, i);

        gotoprint(56, i);

    }

    

    // 游戏信息

gotoxy(60,5);

printf("hello,%s",username);

gotoxy(60,15);

printf("您当前的得分为:");

gotoxy(76,15);

printf("%d",score);

}

打印完后显示一下游戏信息。

注意:

汉字宽度是字符宽度的两倍,高度相等。即一个汉字占两个字节,一个英文字母占一个字节。

因此,"■"输出一次占两个字节,纵向上占一个字节,底部自身携带一些空隙。

​​​​​​​4.产生食物

1、构造食物

struct Food

{

    int x;

    int y;

}food;

2、定位食物

保证食物必须在围墙内:

x坐标范围: [2,54] -- 并且只要偶数部分,不是偶数部分需要转化为接近的偶数

y坐标范围: [1,25]

保证食物和蛇身没有重合,如果重合需要再次生成新的位置。

3、输出食物

void creatfood()

{

// 随机产生一个食物的位置

int flag = 0;

while(!flag)

{

srand((unsigned int)time(NULL));

food.y = rand() % 25 + 1; // [1,25]

food.x = rand() % 53 + 2; // [2,54] -- 只要偶数部分

if(food.x % 2 != 0)

{

food.x = food.x+1; // 不是偶数部分转化为接近的偶数

}

// 不能与蛇身重复

snake *p = head;

while(p)

{

if(p->x == food.x && p->y == food.y)

{

// 重复 -- 重新生成坐标

break;

}

p = p->next;

}

flag = 1;  

}

gotoxy(food.x, food.y);

    printf("吃");

}

​​​​​​​5.初始化蛇身

蛇身构造

typedef struct Snakes

{

    int x;

    int y;

    struct Snakes* next;

}snake;

snake* head;    // 声明蛇头指针

绘制初始化的蛇身

void initSnake()

{

head = (snake*)malloc(sizeof(snake));

    snake* p = (snake*)malloc(sizeof(snake));

    snake* q = (snake*)malloc(sizeof(snake));

    head->x = 16;

    head->y = 15;    

    p->x = 16;

    p->y = 16;

   

    q->x = 16;

    q->y = 17;

    head->next = p;

    p->next = q;

    q->next = NULL;

    

    //绘制初始蛇身

gotoprint(16,15);

gotoprint(16,16);

gotoprint(16,17);    

}

​​​​​​​6.响应按键

getch()为输入字符函数,但是是阻塞的,如果用户不输入进步向下进行,不满足蛇身自动向前运动的需求,因此替换为_kbhit()进行非阻塞的输入监听,监听到键盘输入后,使用_getch从缓冲区中将输入的字符读出来放入全局变量ch中。

另外,当程序执行时,循环一次需要进行一次碰撞检测,没有碰撞时,还需要进行蛇身的移动。

int clickControl()

{

while(1)

{

// 检测是否碰撞边界

if(collisionDetect() == 1) return 0;

// _kbhit监听键盘有输入-非阻塞

if(_kbhit())

{

ch = _getch();  

}

// 移动身体

movingBody();  

}

return 1;

}

​​​​​​​7.蛇身运动

蛇身运动即:消除蛇尾节点,根据按键方向确定好新节点坐标,将新节点添加到蛇头位置即可。

移动后可以加一些延迟,使用Sleep(xx); xx以ms为单位。

void movingBody()

{

// 坐标修改

int x = head->x;

int y = head->y;

switch(ch)

{

case UP:

y-=1;

break;

case DOWN:

y+=1;

break;

case LEFT:

x-=2;

break;

case RIGHT:

x+=2;

break;

default:

ch = 0;

break;

}

if(ch)

{

// 消除尾节点

snake *p = head;

while(p->next->next != NULL)

{

p = p->next;

}

snake *q = p->next;

gotoDelete(q->x,q->y);

free(q);

p->next = NULL;

// 新坐标结点置为头结点

snake* newNode = (snake*)malloc(sizeof(snake));

newNode->x = x;

newNode->y = y;

newNode->next = head;

head = newNode;

// 绘制蛇头

gotoprint(x,y);

// 延迟

Sleep(500);

}

}

注意:如果用户输入的是除了 wasd以外的按键则暂停游戏。

​​​​​​​8.碰撞检测

碰撞检测主要有三种:

  1. 蛇身和边界
  2. 蛇头和蛇身
  3. 蛇头碰到食物

                重新生成一个食物

                在蛇身后面添加一个尾巴,可以不给x,y,因为下次移动的时候会直接将它释放掉。

                加分

                在分值位置更新分数

int collisionDetect()

{

// 检测蛇头和边界

if(head->x == 0 || head->x == 56 || head->y == 0 || head->y == 26)

{

Finish();

return 1;

}

// 蛇头和蛇身

snake *p = head->next;

while(p != NULL)

{

if(head->x == p->x && head->y == p->y)

{

// 碰撞-结束

Finish();

return 1;

}

p = p->next;

}

// 碰到食物

if(head->x == food.x && head->y == food.y)

{

creatfood();

// 添加一个尾巴

snake* newNode = (snake*)malloc(sizeof(snake));

newNode->next = NULL;

snake *p = head;

while(p->next != NULL)

{

p = p->next;

}

p->next = newNode;

score += 10;

gotoxy(76,15);

printf("%d",score);

}

return 0;

}

​​​​​​​9.结束界面

清屏

显示用户名和得分

void Finish()

{

system("cls");

    gotoxy(10, 10);

    printf("/**********************************************/");

    gotoxy(10, 20);

    printf("/**********************************************/");

    gotoxy(15, 14);

    printf("GAME   OVER      o(* ̄▽ ̄*)o");    

    gotoxy(18, 16);

    printf("%s,    你的得分 %d ",username, score);

    gotoxy(15, 18);

    printf("还不错哦,     继续努力O(∩_∩)O");

    gotoxy(0, 27);

    // 释放空间

    snake* p = head, *q;

    while (p != NULL) {

        q = p->next;

        free(p);

        p = q;

    }

    system("pause");

}

​​​​​​​10.运行程序

int main()

{

welcome();

creatgraph();

creatfood();

initSnake();

clickControl();

return 0;

}


http://chatgpt.dhexx.cn/article/sc7V4Aq4.shtml

相关文章

C语言实现贪吃蛇小游戏!(超简单详细)详细思路+源码分享

贪吃蛇&#xff08;也叫做贪食蛇&#xff09;游戏是一款休闲益智类游戏&#xff0c;有PC和手机等多平台版本。既简单又耐玩。该游戏通过控制蛇头方向吃蛋&#xff0c;从而使得蛇变得越来越长。 我们的今天的目标就是&#xff1a;用C语言来实现一个贪吃蛇项目&#xff0c;也不用…

C语言 贪吃蛇

基于C语言编写的贪吃蛇 编写环境&#xff1a;VS2019x86 这是一个基于C语言链表开发的贪吃蛇游戏 其实贪吃蛇游戏要解决的主要问题就是 1、这个游戏的基本组成元素和数据结构 2、如何初始化贪吃蛇并正常行走 3、如何判断事件发生 代码中运用到了键盘虚拟键判断、终端窗口大小的…

游戏贪吃蛇(c语言)

游戏贪吃蛇&#xff08;c语言&#xff09; 一、项目背景二、设计目的三、项目功能需求1、初始化游戏2、控制蛇的运行轨迹3、控制蛇的长度4、控制食物生成5、计算分数6、结束条件 四、系统的功能结构图五、总体设计1、初始化模块2、游戏控制模块3、运行控制模块4、食物生成模块 …

C语言实现贪吃蛇(详细版)

一、需要掌握的知识&#xff1a; C语言基础语法&#xff08;结构体、指针、链表&#xff09;、<windows.h>库、<stdlib.h>库、<time.h>库中的一些函数&#xff08;不需要额外学习&#xff0c;本文后面会讲贪吃蛇需要用到的相关函数&#xff09; 由于作者水平…

贪吃蛇(C语言实现)

文章目录 游戏说明游戏效果展示游戏代码游戏代码详解游戏框架构建隐藏光标光标跳转初始化界面颜色设置初始化蛇随机生成食物打印蛇与覆盖蛇移动蛇游戏主体逻辑函数执行按键判断得分与结束从文件读取最高分更新最高分到文件主函数 游戏说明 游戏界面当中没有打印相关的按键说明…

SDRAM控制器(初始化)

SDRAM控制器&#xff08;初始化&#xff09; 文章目录 SDRAM控制器&#xff08;初始化&#xff09;初始化模块时序逻辑图代码仿真结果 初始化模块 SDRAM 在上电之后&#xff0c;执行正常操作之前需要被初始化&#xff0c;实际上就是对上文提到的SDRAM 内部逻辑控制单元进行初始…

SDRAM 控制器设计基本完结

项目可以拓展的地方&#xff1a; 1、接口为AXI 2、接口为AXI与AXI DMA 交互 2、优化读写时序&#xff0c;使得SDRAM输出效率最大&#xff1b; 总结&#xff1a; 项目不足&#xff1a;没有进行效率的优化&#xff0c;无地址映射&#xff0c;无外接交互接口&#xff0c;功能单一…

SDRAM读写控制

SDRAM读写控制器&#xff0c;这里分为三个部分&#xff0c;分别是SDRAM的基本操作实现&#xff0c;SDRAM控制器&#xff0c;封装成FIFO,以方便使用。 一、SDRAM的基本操作&#xff1a;初始化模块、自动刷新模块、写操作模块、读操作模块、SDRAM仲裁模块&#xff0c;顶层模块。 …

SDRAM 控制器(二)——初始化模块

1、初始化模块 SDRAM 的初始化是芯片上电后必须进行的一项操作&#xff0c;只有进行了初始化操作的 SDRAM 芯片才可被正常使用。SDRAM 的初始化是一套预先定义好的流程&#xff0c;除此之外的其 他操作会导致 SDRAM 出现不可预知的后果。 初始化时序图&#xff1a; CK&#xf…

SDRAM详细介绍

概念介绍&#xff1a; SDRAM&#xff1a;Synchronous Dynamic Random Access Memory&#xff0c;同步动态随机存储器。同步是指其时钟频率和CPU前端总线的系统时钟相同&#xff0c;并且内部命令的发送与数据的传输都以它为基准&#xff1b;动态是指存储阵列需要不断的刷新来保证…

sdram简易控制器设计

耗时一周&#xff0c;终于完成sdram简易控制器的所有代码设计&#xff0c;其中感谢开源骚客 – 邓堪文老师在b站发布的相关视频学习教材&#xff1b;其中仿真模块及所使用到的sdram仿真文件来源于开源骚客&#xff1b; 因为时间较为紧迫&#xff0c;其中就不做代码的一些注释&…

基于FPGA的SDRAM控制器设计(一)

基于FPGA的SDRAM控制器设计&#xff08;一&#xff09; 1. SDRAM控制器整体框架2.UART_RX模块3.UART_TX模块4. RX与TX模块的整合5.需要注意的问题6.代码7.参考资料 1. SDRAM控制器整体框架 图1.1整体框架 PC端通过串口模块UART_RX发送读写命令以及数据到Cmd_encode模块&#xf…

基于FPGA的SDRAM控制器设计(1)

基于FPGA的SDRAM初始化配置 SDRAM简述SDRAM的引脚及作用SDRAM初始化时序控制SDRAM上电时序代码SDRAM测试模块的代码仿真测试结果参考文献总结 SDRAM简述 SDRAM&#xff08; Synchronous Dynamic Random Access Memory&#xff09;&#xff0c;同步动态随机存储器。同步是指 Me…

FPGA进阶(3):SDRAM读写控制器的设计与验证

文章目录 第50讲&#xff1a;SDRAM读写控制器的设计与验证理论部分设计与实现1. sdram_ctrlsdram_initsdram_a_refsdram_writesdram_readsdram_arbitsdram_ctrl 2. sdram_topfifo_ctrlsdram_top 3. uart_sdramuart_rxuart_txfifo_readuart_sdram 第50讲&#xff1a;SDRAM读写控…

SDRAM

简介、优缺点、历史 1、译为“同步动态随机存取内存”&#xff0c;区别于异步DRAM。SRAM是异步静态存储器。 2、同步(Synchronous)&#xff1a;与通常的异步 DRAM 不同&#xff0c; SDRAM 存在一个同步接口&#xff0c;其工作时钟的时钟频率与对应控制器(CPU/FPGA上的读写控制…

关于SDRAM存储器

一、对SDRAM的初步认识 1.1 什么是SDRAM SDRAM&#xff08;Synchronous Dynamic Random Access Memory&#xff09;&#xff0c;同步动态随机存取存储器。 同步&#xff1a;工作频率与对应控制器的系统时钟频率相同&#xff0c;且内存内部的命令以及数据的传输都以此为基准 …

内存控制器与SDRAM

内存接口概念&#xff1a; 通常ARM芯片内置的内存很少&#xff0c;要运行Linux&#xff0c;需要扩展内存。ARM9扩展内存使用SDRAM内存&#xff0c;ARM11使用 DDR SDRAM。S3C2440通常外接32位64MBytes的SDRAM&#xff0c;采用两片16位32M的SDRAM芯片&#xff0c;SDRAM芯片通过地…

SDRAM驱动篇之简易SDRAM控制器的verilog代码实现

在Kevin写的上一篇博文《SDRAM理论篇之基础知识及操作时序》中&#xff0c;已经把SDRAM工作的基本原理和SDRAM初始化、读、写及自动刷新操作的时序讲清楚了&#xff0c;在这一片博文中&#xff0c;Kevin来根据在上一篇博文中分析的思路来把写一个简单的SDRAM控制器。 我们在上一…

FPGA之SDRAM控制器设计(一)

MT48LC128M4A2 – 32 Meg x 4 x 4 banks是512M SRAM&#xff0c;总体概述如下图 分别从上电初始化&#xff0c;刷新&#xff0c;写&#xff0c;读四个部分进行设计&#xff0c;此外还包含主控状态机&#xff0c;一个顶层。 1&#xff1a;上电初始化 整体架构&#xff1a;从控…

内存控制器与SDRAM【赞】

原文链接&#xff1a;https://blog.csdn.net/qq_31216691/article/details/87115697 内存接口概念&#xff1a; 通常ARM芯片内置的内存很少&#xff0c;要运行Linux&#xff0c;需要扩展内存。ARM9扩展内存使用SDRAM内存&#xff0c;ARM11使用 DDR SDRAM。S3C2440通常外接32位6…