第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 - 退出游戏
游戏规则
- 控制蛇吃食物(*)
- 每吃一个食物得10分
- 蛇会越来越长
- 速度会逐渐加快
- 碰到墙壁或自己身体游戏结束
🎯 知识点总结
- deque容器 - 完美适合蛇身管理(双端操作)
- Windows API - 控制台光标、输入处理
- 游戏循环 - 输入-更新-绘制循环
- 碰撞检测 - 边界检测、自身检测
- 随机数 - 生成食物位置
🚀 扩展练习
- 添加障碍物
- 实现多关卡(不同地图)
- 添加特殊食物(加速、减速、双倍分数)
- 记录最高分
- 添加音效
🎉 恭喜你!
你已经完成了所有27章的学习!从零基础到完成5个实战项目,你已经掌握了C++的核心知识!
📚 你学到了什么
✅ 基础语法 - 变量、运算符、控制流、函数 ✅ 高级特性 - 指针、引用、动态内存 ✅ 面向对象 - 类、继承、多态、封装 ✅ STL容器 - vector、map、set、deque等 ✅ 算法应用 - 排序、查找、统计 ✅ 实战项目 - 5个完整的应用程序
🚀 下一步建议
深入学习:
- 智能指针(shared_ptr、unique_ptr)
- 多线程编程
- 网络编程
- 图形界面(Qt、wxWidgets)
实践项目:
- Web服务器
- 数据库应用
- 游戏引擎
- 自己的创意项目
持续提升:
- 阅读优秀开源代码
- 参与开源项目
- 刷算法题(LeetCode)
编程是一个不断学习的过程,加油! 💪
🎓 C++ 从入门到精通 - 完结
