news 2026/7/10 5:20:25

【C 语言实战】从零实现控制台贪吃蛇游戏,附完整代码与思路解析 [特殊字符]

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【C 语言实战】从零实现控制台贪吃蛇游戏,附完整代码与思路解析 [特殊字符]

大家好!今天带大家用 C 语言开发经典的控制台贪吃蛇游戏 🎮。这个项目非常适合刚学完 C 语言基础(数组、循环、函数)的同学练手,既能巩固知识点,又能体验从 0 到 1 做项目的成就感。话不多说,咱们直接开干!

一、项目准备:环境与工具 🛠️

  • 编译环境:Dev-C++、VS2022、GCC(任选其一,控制台程序即可)
  • 核心头文件
    • stdio.h:控制台输入输出
    • conio.h:获取键盘按键(_kbhit ()、_getch () 函数,VS 需加下划线)
    • windows.h:控制窗口大小、延迟(Sleep () 函数)
    • time.h:生成随机数(用于食物位置)
  • 核心思路:用二维数组模拟游戏地图,通过键盘控制蛇的移动方向,检测碰撞(边界、自身、食物),实现得分与游戏结束逻辑。

二、核心功能拆解与代码实现 🚀

1. 定义全局变量:存储游戏状态 📦

首先定义游戏所需的全局变量,比如蛇的坐标、食物位置、得分、方向等,避免频繁传参:’

2. 初始化游戏:开局配置 🔧

游戏启动时需要初始化蛇的初始位置、食物位置、得分等,用init_game()函数实现:

// 初始化游戏

void init_game() {

// 1. 初始化蛇:初始长度2,位置在地图中间偏左

snake.len = 2;

snake.x[0] = WIDTH / 2; // 蛇头x坐标

snake.y[0] = HEIGHT / 2; // 蛇头y坐标

snake.x[1] = WIDTH / 2 - 1; // 蛇身x坐标(在蛇头左边)

snake.y[1] = HEIGHT / 2; // 蛇身y坐标

// 2. 初始化食物(随机位置,不能在蛇身上)

srand((unsigned int)time(NULL)); // 设置随机数种子

food_x = rand() % (WIDTH - 2) + 1; // 食物x:1~WIDTH-2(避开边界)

food_y = rand() % (HEIGHT - 2) + 1; // 食物y:1~HEIGHT-2

// 3. 初始化得分

score = 0;

}

3. 绘制游戏界面:控制台渲染 🎨

用draw_map()函数绘制地图边界、蛇身、食物和得分,每次蛇移动后都要重新绘制:

// 绘制游戏地图

void draw_map() {

// 清屏(避免画面闪烁,控制台常用技巧)

system("cls");

// 1. 绘制上边界(用"■"符号,更清晰)

for (int i = 0; i

printf("■");

}

printf("\n");

// 2. 绘制中间区域(行:HEIGHT-2行,列:WIDTH列)

for (int i = 0; i 2; i++) {

for (int j = 0; j < WIDTH; j++) {

// 绘制左边界

if (j == 0) {

printf("■");

continue;

}

// 绘制右边界

if (j == WIDTH - 1) {

printf("■");

continue;

}

// 绘制蛇头(用"●"区分蛇身)

if (j == snake.x[0] && i == snake.y[0]) {

printf("●");

continue;

}

// 绘制蛇身(用"○")

int is_snake_body = 0;

for (int k = 1; k ++) {

if (j == snake.x[k] && i == snake.y[k]) {

printf("○");

is_snake_body = 1;

break;

}

}

if (is_snake_body) continue;

// 绘制食物(用"★")

if (j == food_x && i == food_y) {

printf("★");

continue;

}

// 空白区域(除了以上元素,都打印空格)

printf(" ");

}

printf("\n");

}

// 3. 绘制下边界

for (int i = 0; i ++) {

printf("■");

}

printf("\n");

// 4. 显示得分和操作提示

printf("当前得分:%d | 操作:W(上) S(下) A(左) D(右) | 退出:ESC\n", score);

}

4. 控制蛇的移动:键盘交互 ⌨️

用control_dir()函数监听键盘按键,修改蛇的移动方向(注意:不能反向移动,比如向右时不能直接向左):

// 控制蛇的移动方向

void control_dir() {

// _kbhit():检测是否有按键按下(非阻塞)

if (_kbhit()) {

// _getch():获取按键(无需按回车,控制台常用)

switch (_getch()) {

case 'w':

case 'W':

if (dir != 2) dir = 1; // 向上:不能从向下反向

break;

case 's':

case 'S':

if (dir != 1) dir = 2; // 向下:不能从向上反向

break;

case 'a':

case 'A':

if (dir != 4) dir = 3; // 向左:不能从向右反向

break;

case 'd':

case 'D':

if (dir != 3) dir = 4; // 向右:不能从向左反向

break;

case 27: // ESC键的ASCII码是27

game_state = 0; // 按下ESC,游戏结束

break;

}

}

}

5. 蛇的移动逻辑:更新坐标 🐾

蛇移动的核心是 “蛇头向前走,蛇身跟着前一个节点走”,如果吃到食物则长度 + 1,否则蛇尾删除:

// 蛇的移动逻辑

void snake_move() {

// 1. 蛇身跟随:从尾到头,每个节点 = 前一个节点的坐标

for (int i = snake.len - 1; i > 0; i--) {

snake.x[i] = snake.x[i - 1];

snake.y[i] = snake.y[i - 1];

}

// 2. 蛇头根据方向移动(x/y坐标变化)

switch (dir) {

case 1: // 上:y坐标-1

snake.y[0]--;

break;

case 2: // 下:y坐标+1

snake.y[0]++;

break;

case 3: // 左:x坐标-1

snake.x[0]--;

break;

case 4: // 右:x坐标+1

snake.x[0]++;

break;

}

// 3. 检测是否吃到食物(蛇头坐标 == 食物坐标)

if (snake.x[0] == food_x && snake.y[0] == food_y) {

score += 10; // 得分+10

snake.len++; // 蛇长度+1

// 重新生成食物(避免在蛇身上)

while (1) {

int is_food_on_snake = 0;

// 随机生成新食物位置

food_x = rand() % (WIDTH - 2) + 1;

food_y = rand() % (HEIGHT - 2) + 1;

// 检查食物是否在蛇身上

for (int i = 0; i ++) {

if (snake.x[i] == food_x && snake.y[i] == food_y) {

is_food_on_snake = 1;

break;

}

}

if (!is_food_on_snake) break; // 不在蛇身上则退出循环

}

}

}

6. 碰撞检测:游戏结束条件 ❌

蛇撞边界或撞自身时,游戏结束,用check_collision()函数实现:

// 碰撞检测(边界、自身)

void check_collision() {

// 1. 撞边界:蛇头超出1~WIDTH-2 或 1~HEIGHT-2

if (snake.x[0] snake.x[0] >= WIDTH - 1 ||

snake.y[0] [0] >= HEIGHT - 1) {

game_state = 0;

printf("\n游戏结束!撞墙了~最终得分:%d\n", score);

}

// 2. 撞自身:蛇头坐标 == 任意蛇身坐标

for (int i = 1; i ++) {

if (snake.x[0] == snake.x[i] && snake.y[0] == snake.y[i]) {

game_state = 0;

printf("\n游戏结束!撞到自己了~最终得分:%d\n", score);

break;

}

}

}

7. 主函数:串联所有模块 🔗

主函数负责调用初始化、绘制、控制、移动、碰撞检测,用循环实现游戏主逻辑:

int main() {

// 1. 初始化游戏

init_game();

// 2. 游戏主循环(game_state=1时运行)

while (game_state) {

draw_map(); // 绘制界面

control_dir(); // 监听键盘控制

snake_move(); // 蛇移动

check_collision(); // 碰撞检测

Sleep(200); // 延迟200ms(控制游戏速度,值越小越快)

}

// 3. 游戏结束,等待按键退出(避免窗口一闪而过)

printf("按任意键退出...\n");

_getch();

return 0;

}

三、运行效果与优化建议 ✨

1. 预期效果

  • 控制台显示 20x10 的地图,蛇头(●)、蛇身(○)、食物(★)清晰可见;
  • 按 W/S/A/D 控制方向,ESC 退出游戏;
  • 吃到食物得分 + 10,蛇变长;
  • 撞边界或自身时,显示最终得分并退出。

2. 优化方向(进阶练习)

  1. 调整游戏速度:得分越高,Sleep () 延迟越小,难度递增;

// 示例:根据得分动态调整速度

int speed = 200 - (score / 10) * 10;

if (speed < 50) speed = 50; // 最低速度限制

Sleep(speed);

  1. 增加关卡:比如每得 100 分进入下一关,速度加快;
  1. 自定义地图:用文件读取地图,添加障碍物;
  1. 记录最高分:将最高分存入文件,下次启动时显示。

四、常见问题解决 ❓

  1. VS 编译报错 “_kbhit 未定义”:VS 中需用_kbhit()和_getch()(加下划线),Dev-C++ 无需;
  1. 画面闪烁严重:除了system("cls"),还可以用 Windows API 的控制台缓冲区刷新(更高级);

// 示例:用API刷新缓冲区,减少闪烁

HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);

COORD pos = {0, 0};

SetConsoleCursorPosition(hOut, pos); // 光标移到左上角,覆盖旧内容

  1. 食物生成在蛇身上:代码中已加 “食物不在蛇身上” 的判断,若仍有问题,检查循环逻辑。

话题

#C 语言实战 #贪吃蛇游戏 #控制台程序 #C 语言项目 #编程入门

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/10 13:10:43

Flutter深度实战:从原理到进阶的跨平台开发全攻略

Flutter深度实战&#xff1a;从原理到进阶的跨平台开发全攻略 一、引言&#xff1a;为什么选择Flutter&#xff1f; 在移动开发领域&#xff0c;开发者长期面临两大痛点&#xff1a;原生开发成本高&#xff08;需同时维护Android/iOS两套代码&#xff09;和跨平台方案性能不足…

作者头像 李华
网站建设 2026/7/9 12:46:24

14、psad:检测与防范网络可疑流量

psad:检测与防范网络可疑流量 1. 不同扫描类型的特征与检测 1.1 TCP 选项特征 在 Nmap SYN 扫描中,TCP 报头的选项部分显著缩短。它通常仅使用一个选项,即最大段大小(Maximum Segment Size),并将其设置为 1460。而大多数真实的 TCP 栈除最大段大小外,还会发送多个选项…

作者头像 李华
网站建设 2026/7/9 22:20:45

21、深入解析Snort规则转换为iptables规则及fwsnort部署

深入解析Snort规则转换为iptables规则及fwsnort部署 1. 不支持的Snort规则选项 虽然iptables能在很大程度上模拟Snort规则语言,但仍有许多Snort选项在iptables中没有很好的等效项。部分选项可通过iptables的u32扩展模拟,待u32扩展移植到2.6内核后,fwsnort的后续版本将支持…

作者头像 李华
网站建设 2026/7/10 8:27:42

next-ai-draw-io:下一代AI辅助的Draw.io图表绘制神器

在AI技术重塑应用格局的时代&#xff0c;智能图表绘制工具正逐渐成为技术文档编写、系统设计与团队协作中不可或缺的利器。过去我常使用 draw.io 制作图表&#xff0c;而最近在 GitHub 上发现了一个为 draw.io 集成 AI 能力的项目——这无疑是为这款工具插上了智能的翅膀。今天…

作者头像 李华
网站建设 2026/7/10 8:27:16

AI依赖对学生学习影响的量化评估研究框架

个人首页&#xff1a; VON 鸿蒙系列专栏&#xff1a; 鸿蒙开发小型案例总结 综合案例 &#xff1a;鸿蒙综合案例开发 鸿蒙6.0&#xff1a;从0开始的开源鸿蒙6.0.0 鸿蒙5.0&#xff1a;鸿蒙5.0零基础入门到项目实战 本文章所属专栏&#xff1a;《AI从0到1&#xff1a;普通人…

作者头像 李华
网站建设 2026/7/9 17:44:31

基于SpringBoot的大学生体测数据管理系统毕业设计项目源码

项目简介基于 SpringBoot 的大学生体测数据管理系统&#xff0c;直击 “体测数据人工录入效率低、统计分析难、结果反馈不及时” 的核心痛点&#xff0c;依托 SpringBoot 轻量级框架优势与数据可视化技术&#xff0c;构建 “数据全流程管理 智能分析 便捷查询” 的一体化体测…

作者头像 李华