C++ 从入门到精通C++ 从入门到精通
首页
基础教程
进阶教程
实战项目
编程指南
首页
基础教程
进阶教程
实战项目
编程指南
  • 🛠️ 实战项目

    • 🛠️ C++ 实战项目
    • 第23章 - 学生管理系统
    • 第24章 - 通讯录管理系统
    • 第25章 - 图书管理系统
    • 第26章 - 简易银行系统
    • 第27章 - 贪吃蛇游戏

第27章 - 贪吃蛇游戏

嗨,朋友!我是长安。

最后一个项目,我们来做一个经典的贪吃蛇游戏!这是一个综合性项目,用到了我们学过的几乎所有知识。

🎯 游戏功能

  • ✅ 蛇的移动控制
  • ✅ 吃食物长大
  • ✅ 碰墙/碰自己游戏结束
  • ✅ 分数统计
  • ✅ 速度递增
  • ✅ 实时刷新显示

💡 核心技术

  • deque容器 - 蛇身管理
  • 结构体 - 坐标点
  • 控制台操作 - Windows API
  • 游戏循环 - 实时刷新

📝 完整代码

#include <iostream>
#include <deque>
#include <conio.h>
#include <windows.h>
#include <ctime>
using namespace std;

// 坐标点
struct Point {
    int x, y;
    Point(int a = 0, int b = 0) : x(a), y(b) {}
    bool operator==(const Point& p) const {
        return x == p.x && y == p.y;
    }
};

// 贪吃蛇游戏类
class SnakeGame {
private:
    static const int WIDTH = 40;
    static const int HEIGHT = 20;
    
    deque<Point> snake;
    Point food;
    int direction; // 0上 1下 2左 3右
    int score;
    bool gameOver;
    int speed;
    
public:
    SnakeGame() {
        initGame();
    }
    
    void initGame() {
        snake.clear();
        snake.push_back(Point(WIDTH/2, HEIGHT/2));
        snake.push_back(Point(WIDTH/2-1, HEIGHT/2));
        snake.push_back(Point(WIDTH/2-2, HEIGHT/2));
        
        direction = 3; // 初始向右
        score = 0;
        gameOver = false;
        speed = 150;
        
        generateFood();
        hideCursor();
    }
    
    void run() {
        while (!gameOver) {
            if (_kbhit()) {
                handleInput();
            }
            
            update();
            draw();
            
            Sleep(speed);
        }
        
        showGameOver();
    }
    
private:
    void handleInput() {
        char key = _getch();
        
        switch (key) {
            case 'w': case 'W':
                if (direction != 1) direction = 0;
                break;
            case 's': case 'S':
                if (direction != 0) direction = 1;
                break;
            case 'a': case 'A':
                if (direction != 3) direction = 2;
                break;
            case 'd': case 'D':
                if (direction != 2) direction = 3;
                break;
            case 27: // ESC
                gameOver = true;
                break;
        }
    }
    
    void update() {
        // 计算新头部位置
        Point newHead = snake.front();
        
        switch (direction) {
            case 0: newHead.y--; break; // 上
            case 1: newHead.y++; break; // 下
            case 2: newHead.x--; break; // 左
            case 3: newHead.x++; break; // 右
        }
        
        // 检查碰墙
        if (newHead.x < 0 || newHead.x >= WIDTH ||
            newHead.y < 0 || newHead.y >= HEIGHT) {
            gameOver = true;
            return;
        }
        
        // 检查碰到自己
        for (auto& p : snake) {
            if (newHead == p) {
                gameOver = true;
                return;
            }
        }
        
        // 移动蛇
        snake.push_front(newHead);
        
        // 检查是否吃到食物
        if (newHead == food) {
            score += 10;
            
            // 提速
            if (speed > 50) {
                speed -= 5;
            }
            
            generateFood();
        } else {
            snake.pop_back();
        }
    }
    
    void draw() {
        setCursorPosition(0, 0);
        
        // 绘制顶部边框
        cout << "+";
        for (int i = 0; i < WIDTH; i++) cout << "-";
        cout << "+" << endl;
        
        // 绘制游戏区域
        for (int y = 0; y < HEIGHT; y++) {
            cout << "|";
            for (int x = 0; x < WIDTH; x++) {
                Point p(x, y);
                
                if (p == snake.front()) {
                    cout << "O"; // 蛇头
                } else if (isSnakeBody(p)) {
                    cout << "o"; // 蛇身
                } else if (p == food) {
                    cout << "*"; // 食物
                } else {
                    cout << " ";
                }
            }
            cout << "|" << endl;
        }
        
        // 绘制底部边框
        cout << "+";
        for (int i = 0; i < WIDTH; i++) cout << "-";
        cout << "+" << endl;
        
        // 显示信息
        cout << "分数:" << score << " | ";
        cout << "长度:" << snake.size() << " | ";
        cout << "速度:" << (200 - speed) << endl;
        cout << "控制:W(上) S(下) A(左) D(右) | ESC(退出)" << endl;
    }
    
    void generateFood() {
        srand(time(0));
        
        do {
            food.x = rand() % WIDTH;
            food.y = rand() % HEIGHT;
        } while (isSnakeBody(food));
    }
    
    bool isSnakeBody(const Point& p) {
        for (auto& s : snake) {
            if (s == p) return true;
        }
        return false;
    }
    
    void setCursorPosition(int x, int y) {
        COORD pos = {(SHORT)x, (SHORT)y};
        SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
    }
    
    void hideCursor() {
        CONSOLE_CURSOR_INFO cursorInfo;
        GetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursorInfo);
        cursorInfo.bVisible = false;
        SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursorInfo);
    }
    
    void showGameOver() {
        setCursorPosition(0, HEIGHT + 5);
        cout << "\n╔══════════════════════════╗" << endl;
        cout << "║      游戏结束!          ║" << endl;
        cout << "╠══════════════════════════╣" << endl;
        cout << "║  最终分数:" << score << "            ║" << endl;
        cout << "║  蛇的长度:" << snake.size() << "            ║" << endl;
        cout << "╚══════════════════════════╝" << endl;
    }
};

int main() {
    cout << "╔══════════════════════════╗" << endl;
    cout << "║      贪吃蛇游戏          ║" << endl;
    cout << "╚══════════════════════════╝" << endl;
    cout << "\n按任意键开始..." << endl;
    _getch();
    
    system("cls");
    
    SnakeGame game;
    game.run();
    
    cout << "\n感谢游戏!" << endl;
    
    return 0;
}

🎮 游戏说明

控制方式

  • W - 向上移动
  • S - 向下移动
  • A - 向左移动
  • D - 向右移动
  • ESC - 退出游戏

游戏规则

  1. 控制蛇吃食物(*)
  2. 每吃一个食物得10分
  3. 蛇会越来越长
  4. 速度会逐渐加快
  5. 碰到墙壁或自己身体游戏结束

🎯 知识点总结

  • deque容器 - 完美适合蛇身管理(双端操作)
  • Windows API - 控制台光标、输入处理
  • 游戏循环 - 输入-更新-绘制循环
  • 碰撞检测 - 边界检测、自身检测
  • 随机数 - 生成食物位置

🚀 扩展练习

  1. 添加障碍物
  2. 实现多关卡(不同地图)
  3. 添加特殊食物(加速、减速、双倍分数)
  4. 记录最高分
  5. 添加音效

🎉 恭喜你!

你已经完成了所有27章的学习!从零基础到完成5个实战项目,你已经掌握了C++的核心知识!

📚 你学到了什么

✅ 基础语法 - 变量、运算符、控制流、函数 ✅ 高级特性 - 指针、引用、动态内存 ✅ 面向对象 - 类、继承、多态、封装 ✅ STL容器 - vector、map、set、deque等 ✅ 算法应用 - 排序、查找、统计 ✅ 实战项目 - 5个完整的应用程序

🚀 下一步建议

  1. 深入学习:

    • 智能指针(shared_ptr、unique_ptr)
    • 多线程编程
    • 网络编程
    • 图形界面(Qt、wxWidgets)
  2. 实践项目:

    • Web服务器
    • 数据库应用
    • 游戏引擎
    • 自己的创意项目
  3. 持续提升:

    • 阅读优秀开源代码
    • 参与开源项目
    • 刷算法题(LeetCode)

编程是一个不断学习的过程,加油! 💪


🎓 C++ 从入门到精通 - 完结

最近更新: 2025/12/26 17:25
Contributors: 王长安
Prev
第26章 - 简易银行系统