C语言控制台游戏教程:从零实现贪吃蛇(附源码+讲解)

🚀 一、项目简介

"没想到 C 语言也能写出这么流畅的游戏!"

本项目实现了一个支持键盘控制、自动移动、吃食物成长、死亡判定等功能的贪吃蛇游戏。

游戏在控制台运行,使用 printf 绘制界面,利用 _kbhit() 检测输入,实现了简易动画效果。


🧩 二、游戏功能概览

功能 说明
🐍 蛇自动移动 每隔固定时间刷新一帧
🎮 玩家控制 支持 W / A / S / D 控制方向
🍎 食物生成 随机出现在地图上
💀 碰撞检测 撞墙或撞自己即游戏结束
🏆 实时得分 每吃一颗食物 +10 分

💻 三、开发环境

项目 内容
编译器 GCC / MinGW / Dev-C++ / VS Code
C 标准 C99 及以上
系统环境 Windows 控制台(CMD)
外部依赖 无(纯标准库实现)

🧠 四、游戏设计思路

整个游戏的核心可以拆解为以下四部分:

  1. 地图系统:用二维坐标定义边界、蛇、食物位置

  2. 数据结构:用结构体数组保存蛇的每一节身体位置

  3. 控制输入 :使用 _kbhit() + _getch() 检测键盘方向

  4. 逻辑刷新:循环刷新 → 移动蛇 → 判断 → 绘制界面


🧩 五、项目结构设计

复制代码
snake_game/
├── snake.c             # 主程序
├── README.md           # 游戏说明

🧱 六、完整源码(可直接编译运行)

复制代码
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <windows.h>
#include <time.h>

// 游戏界面大小
#define WIDTH 40
#define HEIGHT 20

// 方向枚举
enum Direction { UP, DOWN, LEFT, RIGHT };

// 蛇的节点
typedef struct {
    int x;
    int y;
} Point;

// 全局变量
Point snake[100];
int snake_length = 3;
enum Direction dir = RIGHT;
Point food;
int game_over = 0;
int score = 0;

// 函数声明
void setup();
void draw();
void input();
void logic();
void generate_food();

int main() {
    setup();
    while (!game_over) {
        draw();
        input();
        logic();
        Sleep(100); // 控制帧率(延迟时间)
    }
    printf("\n\n🎮 Game Over! 你的得分是: %d\n", score);
    system("pause");
    return 0;
}

// 初始化
void setup() {
    srand(time(0));
    snake[0].x = WIDTH / 2;
    snake[0].y = HEIGHT / 2;

    for (int i = 1; i < snake_length; i++) {
        snake[i].x = snake[0].x - i;
        snake[i].y = snake[0].y;
    }
    generate_food();
}

// 绘制界面
void draw() {
    system("cls");

    for (int i = 0; i <= WIDTH + 1; i++) printf("#");
    printf("\n");

    for (int y = 0; y < HEIGHT; y++) {
        printf("#");
        for (int x = 0; x < WIDTH; x++) {
            int printed = 0;

            // 蛇
            for (int k = 0; k < snake_length; k++) {
                if (snake[k].x == x && snake[k].y == y) {
                    printf(k == 0 ? "O" : "o");
                    printed = 1;
                }
            }

            // 食物
            if (food.x == x && food.y == y) {
                printf("*");
                printed = 1;
            }

            if (!printed) printf(" ");
        }
        printf("#\n");
    }

    for (int i = 0; i <= WIDTH + 1; i++) printf("#");
    printf("\n得分: %d\n", score);
}

// 键盘输入
void input() {
    if (_kbhit()) {
        switch (_getch()) {
            case 'w':
            case 'W': if (dir != DOWN) dir = UP; break;
            case 's':
            case 'S': if (dir != UP) dir = DOWN; break;
            case 'a':
            case 'A': if (dir != RIGHT) dir = LEFT; break;
            case 'd':
            case 'D': if (dir != LEFT) dir = RIGHT; break;
            case 'x': game_over = 1; break;
        }
    }
}

// 逻辑控制
void logic() {
    Point prev = snake[0];
    Point temp;

    // 移动身体
    for (int i = 1; i < snake_length; i++) {
        temp = snake[i];
        snake[i] = prev;
        prev = temp;
    }

    // 移动头部
    switch (dir) {
        case UP: snake[0].y--; break;
        case DOWN: snake[0].y++; break;
        case LEFT: snake[0].x--; break;
        case RIGHT: snake[0].x++; break;
    }

    // 撞墙检测
    if (snake[0].x < 0 || snake[0].x >= WIDTH ||
        snake[0].y < 0 || snake[0].y >= HEIGHT)
        game_over = 1;

    // 撞到自己
    for (int i = 1; i < snake_length; i++) {
        if (snake[0].x == snake[i].x && snake[0].y == snake[i].y)
            game_over = 1;
    }

    // 吃食物
    if (snake[0].x == food.x && snake[0].y == food.y) {
        snake_length++;
        score += 10;
        generate_food();
    }
}

// 随机生成食物
void generate_food() {
    food.x = rand() % WIDTH;
    food.y = rand() % HEIGHT;
}

🕹 七、运行效果演示

复制代码
##########################################
#                                        #
#                                        #
#               Ooo                      #
#                                        #
#                   *                    #
#                                        #
##########################################
得分: 10

按键说明:

键位 功能
W / A / S / D 控制移动方向
X 退出游戏
每吃一个 * 蛇长度 +1,得分 +10

🔍 八、核心逻辑分析

模块 逻辑说明
🎯 移动机制 头向前移动,身体依次跟随
💀 碰撞检测 越界或与自身重叠即结束
🍎 食物机制 随机生成,吃掉后蛇变长
🌀 动画实现 利用 system("cls") 重绘整个画面
🎮 输入检测 _kbhit() 检测非阻塞键盘输入

⚡ 九、功能扩展建议(进阶玩法)

功能方向 实现思路
🔊 添加音效 使用 Beep() 播放吃食物提示音
🧱 边界穿越模式 超出边界从另一侧出现
🌈 彩色渲染 SetConsoleTextAttribute() 美化界面
🕹 难度递增 分数越高 → 蛇速越快
💾 存档系统 使用文件 I/O 保存最高分
相关推荐
xiezhr1 天前
米哈游36岁程序员被曝复工当晚猝死出租屋内
游戏·程序员·游戏开发
祈安_3 天前
C语言内存函数
c语言·后端
norlan_jame5 天前
C-PHY与D-PHY差异
c语言·开发语言
czy87874755 天前
除了结构体之外,C语言中还有哪些其他方式可以模拟C++的面向对象编程特性
c语言
m0_531237175 天前
C语言-数组练习进阶
c语言·开发语言·算法
爱搞虚幻的阿恺5 天前
Niagara粒子系统-超炫酷的闪电特效(加餐 纸牌螺旋上升效果)
游戏·游戏引擎
Lester_11015 天前
STM32霍尔传感器输入口设置为复用功能输入口时,还能用GPIO函数直接读取IO的状态吗
stm32·单片机·嵌入式硬件·电机控制
LCG元5 天前
低功耗显示方案:STM32L0驱动OLED,动态波形绘制与优化
stm32·嵌入式硬件·信息可视化
z20348315205 天前
STM32F103系列单片机定时器介绍(二)
stm32·单片机·嵌入式硬件
智算菩萨5 天前
儿童游乐空间的双维建构:室内淘气堡与室外亲子乐园的发展学理、功能分野与协同育人机制研究
游戏·游戏策划