乐趣c语言——贪吃蛇

article/2025/10/25 21:53:15

目录

1.游戏介绍与思路

1.1介绍:

1.2游戏区思路

1.2.1围墙

1.2.2游戏区域

1.2.3蛇头与蛇身

1.3游戏逻辑思路

2.正式实现贪吃蛇

2.1在开始前我们先包头文件和宏定义

2.2创建游戏区并且初始化

2.3初始化蛇头与蛇身

2.4打印与覆盖蛇

2.5实现蛇的移动

 2.6蛇移动

2.7食物的随机生成

2.8判断游戏是否结束

3.整体游戏逻辑

4.完整代码


1.游戏介绍与思路

1.1介绍:

小键盘上下左右来控制方向,开始蛇的长度为3,吃到食物蛇身+1,碰到墙游戏结束

1.2游戏区思路

1.2.1围墙

围墙很简单,我们只要确定长和宽即可

#define ROW 22
#define COL 42

1.2.2游戏区域

利用一个二维数组face来存放游戏区内各方块的内容

如果(x,y)处是空的,我们就把数组的face[x][y]=BLANK;

如果(x,y)处是墙,我们就把数组的face[x][y]=WALL;

如果(x,y)处是食物,我们就把数组的face[x][y]=FOOD;

为了代码的可读性,我们使用宏定义

#define BlANK 0
#define WALL 1
#define FOOD 2
#define HEAD 3
#define BODY 4

1.2.3蛇头与蛇身

我们利用结构体来构造蛇头与蛇身

(1)蛇头的结构体

需要存放蛇头的横纵坐标,以及蛇的总长度

struct snakehead
{int x;//蛇头横坐标int y;//蛇头纵坐标int len;//蛇的总长度
}snake;

(2)蛇身结构体

存放每个蛇身的横纵坐标,需要开辟多个

struct snakebody
{int x;//蛇身横坐标int y;//蛇身纵坐标
}body[ROW*COL];

1.3游戏逻辑思路

接收键盘字符来判断需要进行的操作

#define UP 72
#define DOWN 80
#define LEFT 75
#define RIGHT 77
#define SPACE 32
#define ESC 27

整体:初始化棋盘——初始化蛇头与蛇身——打印蛇——进行游戏

游戏:蛇移动(通过接收键盘)——打印蛇——判断触碰的内容(墙=游戏结束,食物=长度加                   一,空=继续游戏)

2.正式实现贪吃蛇

2.1在开始前我们先包头文件和宏定义

#pragma once#include <stdio.h>
#include <windows.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>#define ROW 22
#define COL 42#define BlANK 0
#define WALL 1
#define FOOD 2
#define HEAD 3
#define BODY 4#define UP 72
#define DOWN 80
#define LEFT 75
#define RIGHT 77
#define SPACE 32
#define ESC 27

接下来我们先实现这次的重点——实现光标跳转函数

光标跳转可以让我们实现在任意位置的打印,这个非常有用

void CursorJump(int x, int y)//传入需要跳转的位置
{COORD pos;//存放横纵坐标的一个结构体pos.X = x;//赋值pos.Y = y;//赋值HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);//接收屏幕句柄SetConsoleCursorPosition(handle, pos);//将光标放置到pos处
}

这里的COORD不需要你自己定义,直接使用就可以了。这个结构体内部包含一个横坐标,一个纵坐标

调用函数,光标跳转到指定地点,我们就可以实现任意位置的打印。

为了游戏的美观我们需要隐藏光标

void HideCursor()
{CONSOLE_CURSOR_INFO curInfo;curInfo.dwSize = 1;curInfo.bVisible = FALSE;HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);SetConsoleCursorInfo(handle, &curInfo);
}

2.2创建游戏区并且初始化

int face[ROW][COL];

先创建一个长*宽大小的二维数组,用来存放游戏区每个格子的情况

初始化游戏区

void InitInterface()
{for (int i = 0; i < ROW; i++)//需要打印ROW行{for (int j = 0; j < COL; j++){if (j == 0 || j == COL - 1)//第一列或者最后一列{face[i][j] = WALL; //标记该位置为墙CursorJump(2 * j, i);//光标跳转printf("■");}else if (i == 0 || i == ROW - 1)//第一行和最后一行{face[i][j] = WALL; //标记该位置为墙printf("■");}else{face[i][j] = BlANK; //标记该位置为空}}}
}

初始化后我们就得到了游戏区,并且将游戏区的内容存放到数组中

2.3初始化蛇头与蛇身

void Initsnake()
{snake.len = 2;//蛇的初始长度为2snake.x = COL / 2;//蛇头初始位置snake.y = ROW / 2;//蛇头初始位置//第一个蛇身body[0].x = COL / 2-1;body[0].y = ROW / 2;//第二个蛇身body[1].x = COL / 2-2;body[1].y = ROW / 2;face[snake.y][snake.x] = HEAD;//标记该位置为头face[body[0].y][body[0].x] = BODY;//标记该位置为身子face[body[1].y][body[1].x] = BODY;//标记该位置为身子
}

2.4打印与覆盖蛇

这里实现蛇移动的方法是利用空格覆盖来实现蛇的移动

void DrawSnake(int flag)//利用flag来决定是打印还是覆盖
{if (flag == 1)//打印蛇{CursorJump(2 * snake.x, snake.y);//光标跳转到蛇头位置printf("■");//打印蛇头for (int i = 0; i < snake.len; i++)//利用循环打印蛇身{CursorJump(2 * body[i].x, body[i].y);//光标跳转到蛇身的位置printf("□");//打印蛇身}}else//覆盖蛇{if (body[snake.len - 1].x != 0)//蛇身不为空{CursorJump(2 * body[snake.len-1 ].x, body[snake.len-1 ].y);printf("  ");//空格覆盖}}
}

2.5实现蛇的移动

思路:将原来的蛇覆盖后打印新蛇

void MoveSneke(int x, int y)
{DrawSnake(0);//先覆盖之前的蛇face[body[snake.len - 1].y][body[snake.len - 1].x] = BlANK;//将覆盖后的标记为空for (int i = snake.len - 1; i > 0; i--){body[i].x = body[i - 1].x;//将后一个身子的坐标放到前一个身子body[i].y = body[i - 1].y;}body[0].x = snake.x;body[0].y = snake.y;snake.x = snake.x + x;snake.y = snake.y + y;DrawSnake(1);//打印蛇
}

画图更容易理解

 

 

 

 

 2.6蛇移动

void run(int x, int y)
{int t = 0;while (1){if (t == 0){t = 6000;//蛇移动的速度}while (--t){if (kbhit() != 0)//检测是否有键盘输入,有就返回非0break;}if (t == 0){judgeFunc(x, y);//判断游戏是否结束MoveSneke(x, y);//移动蛇}else{break;}}
}

2.7食物的随机生成

void RandFood()
{int i, j;do{i = rand() % ROW;//随机生成坐标j = rand() % COL;} while (face[i][j] != BlANK);//判断此坐标是否为空,不为空就重新生成face[i][j] = FOOD;//在为空的地方标记食物CursorJump(2 * j, i);//跳转打印食物printf("●");
}

2.8判断游戏是否结束

void judgeFunc(int x, int y)
{if (face[snake.y + y][snake.x + x] == FOOD)//如果这个地方是食物{snake.len++;//蛇身长度+1RandFood();//重新随机生成食物}else if (face[snake.y + y][snake.x + x] == WALL)//如果位置是墙{Sleep(1000);//给玩家反应时间system("cls");//清屏CursorJump(2 * (COL / 3), ROW / 2 + 3);printf("game over,agin?  y/n");char n;scanf("%c", &n);if (n == 'y'){system("cls");main();}else{exit(0);}}
}

3.整体游戏逻辑

void game2()
{int n = RIGHT;//默认向右移动int tmp = 0;goto first;while (1){n = getch();//接收玩家键盘输入switch (n){case UP:case DOWN:if (tmp != LEFT && tmp != RIGHT)//玩家按上下,但是上一次不是左右{n = tmp;//方向改为上或下}break;case LEFT:case RIGHT:if (tmp != UP && tmp != DOWN){n = tmp;}case SPACE:case ESC:case 'r':case 'R':break;default:n = tmp;break;}first:switch (n){case UP:run(0, -1);tmp = UP;break;case DOWN:run(0, 1);tmp = DOWN;break;case LEFT:run(-1, 0);tmp = LEFT;break;case RIGHT:run(1, 0);tmp = RIGHT;break;case SPACE:system("pause>nul");break;case ESC:system("cls");CursorJump(COL - 8, ROW / 2);printf("game over");CursorJump(COL - 8, ROW / 2);exit(0);case 'r':case 'R':system("cls");main();}}
}

4.完整代码

#include <stdio.h>
#include <windows.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>#define ROW 22
#define COL 42#define BlANK 0
#define WALL 1
#define FOOD 2
#define HEAD 3
#define BODY 4#define UP 72
#define DOWN 80
#define LEFT 75
#define RIGHT 77
#define SPACE 32
#define ESC 27int max, grade;
struct snakehead
{int x;int y;int len;
}snake;struct snakebody
{int x;int y;
}body[ROW*COL];int face[ROW][COL];void HideCursor();//隐藏光标
void CursorJump(int x, int y);
void InitInterface();
void Initsnake();
void DrawSnake(int flag);
void MoveSneke(int x, int y);
void run(int x, int y);
void judgeFunc(int x, int y);
void RandFood();void HideCursor()
{CONSOLE_CURSOR_INFO curInfo;curInfo.dwSize = 1;curInfo.bVisible = FALSE;HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);SetConsoleCursorInfo(handle, &curInfo);
}
void CursorJump(int x, int y)
{COORD pos;pos.X = x;pos.Y = y;HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);SetConsoleCursorPosition(handle, pos);
}
void InitInterface()
{//color(6);for (int i = 0; i < ROW; i++){for (int j = 0; j < COL; j++){if (j == 0 || j == COL - 1){face[i][j] = WALL; //标记该位置为墙CursorJump(2 * j, i);printf("■");}else if (i == 0 || i == ROW - 1){face[i][j] = WALL; //标记该位置为墙printf("■");}else{face[i][j] = BlANK; //标记该位置为空}}}
}void Initsnake()
{snake.len = 2;snake.x = COL / 2;snake.y = ROW / 2;body[0].x = COL / 2-1;body[0].y = ROW / 2;body[1].x = COL / 2-2;body[1].y = ROW / 2;face[snake.y][snake.x] = HEAD;face[body[0].y][body[0].x] = BODY;face[body[1].y][body[1].x] = BODY;
}void DrawSnake(int flag)
{//system("cls");//InitInterface();if (flag == 1){CursorJump(2 * snake.x, snake.y);printf("■");for (int i = 0; i < snake.len; i++){CursorJump(2 * body[i].x, body[i].y);printf("□");}}else{if (body[snake.len - 1].x != 0){CursorJump(2 * body[snake.len-1 ].x, body[snake.len-1 ].y);printf("  ");}}
}void MoveSneke(int x, int y)
{DrawSnake(0);face[body[snake.len - 1].y][body[snake.len - 1].x] = BlANK;for (int i = snake.len - 1; i > 0; i--){body[i].x = body[i - 1].x;body[i].y = body[i - 1].y;}body[0].x = snake.x;body[0].y = snake.y;snake.x = snake.x + x;snake.y = snake.y + y;DrawSnake(1);
}void run(int x, int y)
{int t = 0;while (1){if (t == 0){t = 6000;}while (--t){if (kbhit() != 0)break;}if (t == 0){judgeFunc(x, y);MoveSneke(x, y);}else{break;}}
}
void judgeFunc(int x, int y)
{if (face[snake.y + y][snake.x + x] == FOOD){snake.len++;grade += 10;RandFood();}else if (face[snake.y + y][snake.x + x] == WALL){Sleep(1000);system("cls");CursorJump(2 * (COL / 3), ROW / 2 + 3);printf("game over,agin?  y/n");char n;scanf("%c", &n);if (n == 'y'){system("cls");main();}else{exit(0);}}
}
void RandFood()
{int i, j;do{i = rand() % ROW;j = rand() % COL;} while (face[i][j] != BlANK);face[i][j] = FOOD;CursorJump(2 * j, i);printf("●");
}void game()
{//printf("贪吃蛇\n");//创建游戏区域HideCursor();InitInterface();Initsnake();DrawSnake(1);RandFood();game2();}int main()
{game();return 0;
}
void game2()
{int n = RIGHT;int tmp = 0;goto first;while (1){n = getch();switch (n){case UP:case DOWN:if (tmp != LEFT && tmp != RIGHT){n = tmp;}break;case LEFT:case RIGHT:if (tmp != UP && tmp != DOWN){n = tmp;}case SPACE:case ESC:case 'r':case 'R':break;default:n = tmp;break;}first:switch (n){case UP:run(0, -1);tmp = UP;break;case DOWN:run(0, 1);tmp = DOWN;break;case LEFT:run(-1, 0);tmp = LEFT;break;case RIGHT:run(1, 0);tmp = RIGHT;break;case SPACE:system("pause>nul");break;case ESC:system("cls");CursorJump(COL - 8, ROW / 2);printf("game over");CursorJump(COL - 8, ROW / 2);exit(0);case 'r':case 'R':system("cls");main();}}
}


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

相关文章

C语言制作小游戏——贪吃蛇

直接上代码 ​ #include <stdio.h> #include <stdlib.h> #include <math.h> #include <conio.h> #include <time.h> #include <windows.h>//MAXWIDTH、MAXHEIGHT、INITLEN 以字符记 #define MAXWIDTH (30) #define MAXHEIGHT MAXWIDTH #d…

C语言之贪吃蛇游戏源码

贪吃蛇游戏是我编程以来做的第一个游戏&#xff0c;很兴奋&#xff0c;我记得当时我一直最求代码数量的最小化&#xff0c;即以最少的代码实现功能&#xff0c;有的时候&#xff0c;对换行、括号之类的都下手&#xff0c;呵呵&#xff0c;现在想想都想笑&#xff0c;那些年让我…

c语言贪吃蛇(简易版本含完整代码)

文章目录 前引头文件注释部分头文件部分主函数部分实现效果 前引 这个贪吃蛇是在我学完C语言的基本部分 在跟着哈工大的c语言程序设计Mooc课程完了之后做的 因为学完C语言很迷茫 不晓得应该学什么 学校里面的题库感觉刷起来又没有实际我能看到的东西 我认为在阶段性的学习过程中…

C语言实现简单贪吃蛇代码

基本构成 穿墙控制 死亡控制 初始化蛇&#xff08;init_snake函数&#xff09; 移动蛇&#xff08;move_snake函数&#xff09; 打印蛇&#xff08; print_snake函数&#xff09; 利用for循环检测坐标对应的蛇的位置 代码演示 #include <stdio.h> #include <window…

C语言实现贪吃蛇

C语言实现贪吃蛇 贪吃蛇项目是在b站的一位老师那里边学边敲的&#xff08;现在视频被老师删掉了&#xff09;&#xff0c;在这里记录一下代码和学习时的一些思考&#xff0c;希望自己以后能用链表将贪吃蛇实现。 思考过程&#xff1a; 贪吃蛇 C语言实现 1.打印首页 --FirstP…

C语言写个贪吃蛇游戏

贪吃蛇是个非常经典的游戏&#xff0c;用C语言来实现也是一个好玩的事情。这个游戏我写完后放在知乎&#xff0c;竟然点赞的人数超级多。我觉得大家喜欢&#xff0c;一个方面是因为写得简单&#xff0c;大家都能看得懂&#xff0c;一个可扩展性还是非常强的。 我试了说一下这个…

C语言实现贪吃蛇小游戏(详解)

目录 一、程序实现的原理&#xff1a; 二、预备知识 1、控制台窗口 2、通过代码将光标移动到控制台指定位置 三、 程序框架 四、具体操作 1、定义相关头文件 2、定义函数结构以及相关属性 五、完成各代码块 1、 实现将光标移到指定位置的操作 2、 打印游戏边框以及游戏初始…

小白入门——“贪吃蛇”的C语言实现(详细)

C语言实现&#xff0c;编译环境VS&#xff12;&#xff10;&#xff11;&#xff17; 附&#xff1a;easyx图形化(文章末尾&#xff09; 效果图如下 &#xff08;有一些函数kbhit&#xff0c;getch&#xff0c;在这表示为_kbhit与_getch&#xff09;//不同编译器原因 注意在Dev…

【C语言】贪吃蛇游戏的实现(一)

&#xff08;注意&#xff1a;本代码是在VC6.0环境下编译的&#xff0c;在其他环境如codeblocks下运行可能会产生意想不到的问题&#xff0c;请尽量使用VC。至于为什么要使用VC编译&#xff0c;哦&#xff0c;我亲爱的朋友&#xff0c;这只有上帝才知道&#xff09; 最近由于小…

C语言贪吃蛇 新手入门(超详细)

贪吃蛇小程序&#xff0c;主要采用C语言描述&#xff0c;采用数组进行数据存储的图形化操作界面&#xff0c;会涉及一点点C 知识&#xff08;特别少的一点点&#xff09;&#xff0c;但是有C语言基础就够用了&#xff0c;编译器&#xff1a;VS2015&#xff0c;会涉及部分库函数…

C语言实现的贪吃蛇(无EasyX,详解)

&#x1f4a6;前言 或许厌倦了枯燥的做题&#xff0c;那就学学贪吃蛇&#xff0c;激发你的学习乐趣吧~ 你将进一步加深对结构体&#xff0c;单链表&#xff0c;函数&#xff0c;循环等基础的理解。 希望对你有所帮助~ 纯C实现的贪吃蛇&#x1f40d; &#x1f4a6;前言&#x1f…

教你如何用C语言做一个简单的贪吃蛇

小时候大家可能都玩过贪吃蛇&#xff0c;但有没有想过自己做一个出来玩玩看。今天我们就教大家用C语言做一个简单的贪吃蛇游戏。这里没有采用图形界面去做&#xff0c;而是采用win32控制台。 首先&#xff0c;先把做好的游戏初始界面和游戏截图先展示一下。 游戏初始界面如图&a…

C语言实现贪吃蛇(简易)

文章目录 目录 文章目录 前言 一、游戏功能和效果 1.游戏功能 2.游戏效果 二. 游戏初步实现 1.确定地图大小 2.创建蛇对象&#xff0c;食物对象 3.初始化蛇 4.生成随机食物 5.画蛇 6.画食物 7. 游戏内移动控制 1.当按上下左右时移动方向改变 。 2.开始游戏时的默认方向 8.判…

C语言贪吃蛇小游戏,贪吃蛇C语言代码实现大全

一、C语言贪吃蛇代码实现前言 设计贪吃蛇游戏的主要目的是让大家夯实C语言基础&#xff0c;训练编程思维&#xff0c;培养解决问题的思路&#xff0c;领略多姿多彩的C语言。 贪吃蛇是非常经典的一款游戏&#xff0c;本次我们模拟在控制台实现贪吃蛇游戏&#xff0c;也就是实现…

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

C语言贪吃蛇项目 今天给分享一下使用C语言写个贪吃蛇小游戏&#xff0c;主要包含以下10部分内容&#xff1a; 1、windows光标定位与隐藏 2、欢迎界面 3、打印围墙 4、产生食物 5、初始化蛇身 6、响应按键 7、蛇身运动 8、碰撞检测 9、结束界面 10、程序运行 windows…

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语言实现)

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