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 保存最高分
相关推荐
创界工坊工作室8 小时前
DPJ-120 基于STC89C52的多功能清扫消杀车控制系统设计(源代码+proteus仿真)
stm32·单片机·嵌入式硬件·51单片机·proteus
智者知已应修善业9 小时前
【输入两个数字,判断两数相乘是否等于各自逆序数相乘】2023-10-24
c语言·c++·经验分享·笔记·算法·1024程序员节
LaoZhangGong1239 小时前
深度学习uip中的“psock.c和psock.h”
c语言·开发语言
Darken039 小时前
引脚重映射是什么意思?如何使用?
stm32·单片机·引脚重映射
知南x9 小时前
【正点原子STM32MP157 可信任固件TF-A学习篇】(2) STM32MP1 中的 TF-A
stm32·嵌入式硬件·学习·stm32mp157
hefaxiang9 小时前
分支循环(下)(二)
c语言·开发语言·数据结构
小武~10 小时前
Leetcode 每日一题C 语言版 -- 45 jump game ii
c语言·算法·leetcode
LaoZhangGong12311 小时前
深度学习uip中“uip_arp.c“
c语言·stm32·以太网·arp·uip·enc28j60
laocooon52385788611 小时前
一个C项目实现框架
c语言·算法
Bona Sun12 小时前
单片机手搓掌上游戏机(二十三)—esp32运行简单街机模拟器软硬件准备
c语言·c++·单片机