贪吃蛇游戏在c++++中实现的核心在于构建游戏逻辑、图形界面绘制和键盘输入处理。1. 游戏基本结构包括蛇(由坐标点组成)、食物(随机生成)和游戏区域(控制台边界)。2. 数据结构使用std::vector<:p style="color:#f60; text-decoration:underline;" title="ai" href="https://www.php.cn/zt/17539.html" target="_blank">air
贪吃蛇游戏的核心在于构建游戏逻辑、绘制图形界面(即使是控制台的简单图形),以及处理键盘输入。C++是完全可以胜任这些任务的。
首先,我们需要明确游戏的基本组成部分:蛇、食物、游戏区域。蛇由一系列坐标点组成,食物是随机生成的坐标点,游戏区域则是控制台的边界。
解决方案
立即学习“C++免费学习笔记(深入)”;
数据结构设计:
游戏区域绘制:
蛇的移动逻辑:
键盘输入处理:
游戏循环:
#include <iostream> #include <vector> #include <cstdlib> #include <ctime> #include <conio.h> // Windows #include <thread> #include <chrono> using namespace std; enum Direction { UP, DOWN, LEFT, RIGHT }; int main() { // 游戏参数 int width = 20; int height = 10; vector<pair<int, int>> snake = {{width / 2, height / 2}}; // 初始蛇的位置 pair<int, int> food; Direction dir = RIGHT; bool gameOver = false; // 初始化随机数种子 srand(time(0)); // 生成食物 auto generateFood = [&]() { food.first = rand() % width; food.second = rand() % height; // 确保食物不在蛇的身体里 for (auto &segment : snake) { if (food == segment) { generateFood(); return; } } }; generateFood(); // 游戏循环 while (!gameOver) { // 绘制游戏区域 system("cls"); // 清空屏幕 (Windows) for (int i = 0; i < height; ++i) { for (int j = 0; j < width; ++j) { if (i == 0 || i == height - 1 || j == 0 || j == width - 1) { cout << "#"; } else if (i == food.second && j == food.first) { cout << "$"; } else { bool isSnakeBody = false; for (auto &segment : snake) { if (segment.first == j && segment.second == i) { cout << "@"; isSnakeBody = true; break; } } if (!isSnakeBody) { cout << " "; } } } cout << endl; } // 处理键盘输入 if (_kbhit()) { char key = _getch(); switch (key) { case 'w': if (dir != DOWN) dir = UP; break; case 's': if (dir != UP) dir = DOWN; break; case 'a': if (dir != RIGHT) dir = LEFT; break; case 'd': if (dir != LEFT) dir = RIGHT; break; case 'x': gameOver = true; break; // 退出游戏 } } // 更新蛇的位置 int headX = snake[0].first; int headY = snake[0].second; switch (dir) { case UP: headY--; break; case DOWN: headY++; break; case LEFT: headX--; break; case RIGHT: headX++; break; } // 检查是否撞墙 if (headX < 1 || headX >= width - 1 || headY < 1 || headY >= height - 1) { gameOver = true; break; } // 检查是否撞到自己 for (size_t i = 1; i < snake.size(); ++i) { if (headX == snake[i].first && headY == snake[i].second) { gameOver = true; break; } } if (gameOver) break; // 更新蛇的身体 snake.insert(snake.begin(), {headX, headY}); // 检查是否吃到食物 if (headX == food.first && headY == food.second) { generateFood(); // 生成新的食物 } else { snake.pop_back(); // 移除蛇尾 } // 控制游戏速度 this_thread::sleep_for(chrono::milliseconds(100)); } cout << "游戏结束!" << endl; return 0; }
这个代码展示了最基本的功能。请注意,这只是一个非常基础的实现,可能存在一些bug,例如蛇可以瞬间反向移动导致撞到自己。
防止蛇瞬间反向移动的关键在于,在更新蛇的移动方向时,要避免将方向设置为当前方向的完全相反方向。例如,如果蛇当前向右移动,则不允许立即将方向设置为向左移动。
修改键盘输入处理部分的代码:
// 处理键盘输入 if (_kbhit()) { char key = _getch(); switch (key) { case 'w': if (dir != DOWN) dir = UP; break; case 's': if (dir != UP) dir = DOWN; break; case 'a': if (dir != RIGHT) dir = LEFT; break; case 'd': if (dir != LEFT) dir = RIGHT; break; case 'x': gameOver = true; break; // 退出游戏 } }
要在控制台中显示更丰富的图形,例如使用不同的颜色或字符,你需要使用特定的API,这通常依赖于操作系统。
Windows:
在Windows下,你可以使用Windows.h头文件中的函数来控制控制台的颜色。
#include <iostream> #include <windows.h> using namespace std; int main() { HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); // 设置文本颜色为绿色 SetConsoleTextAttribute(hConsole, FOREGROUND_GREEN); cout << "This is green text." << endl; // 设置文本颜色为红色,背景色为蓝色 SetConsoleTextAttribute(hConsole, FOREGROUND_RED | BACKGROUND_BLUE); cout << "This is red text with blue background." << endl; // 恢复默认颜色 SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); cout << "This is default color." << endl; return 0; }
Linux/macOS:
在Linux和macOS下,你可以使用ANSI转义码来控制控制台的颜色和样式。ANSI转义码是一些特殊的字符序列,可以嵌入到文本中,用于控制终端的行为。
#include <iostream> using namespace std; int main() { // 设置文本颜色为绿色 cout << "\033[32mThis is green text.\033[0m" << endl; // 设置文本颜色为红色,背景色为蓝色 cout << "\033[31m\033[44mThis is red text with blue background.\033[0m" << endl; // 恢复默认颜色 cout << "This is default color." << endl; return 0; }
障碍物:
加速道具:
随机生成:
#include <iostream> #include <vector> #include <cstdlib> #include <ctime> #include <conio.h> // Windows #include <thread> #include <chrono> #include <random>
using namespace std;
enum Direction { UP, DOWN, LEFT, RIGHT };
int main() {
// 游戏参数
int width = 20;
int height = 10;
vector
// 随机数生成器 random_device rd; mt19937 gen(rd()); uniform_int_distribution<> distribW(1, width - 2); // 排除边界 uniform_int_distribution<> distribH(1, height - 2); // 排除边界 // 初始化随机数种子 srand(time(0)); // 生成食物 auto generateFood = [&]() { food.first = distribW(gen); food.second = distribH(gen); // 确保食物不在蛇的身体里 for (auto &segment : snake) { if (food == segment) { generateFood(); return; } } for (auto &obstacle : obstacles) { if (food == obstacle) { generateFood(); return; } } }; generateFood(); // 生成障碍物 auto generateObstacles = [&]() { obstacles.clear(); int numObstacles = 3; for (int i = 0; i < numObstacles; ++i) { pair<int, int> obstacle; obstacle.first = distribW(gen); obstacle.second = distribH(gen); // 确保障碍物不在蛇的身体里或食物的位置 bool valid = true; for (auto &segment : snake) { if (obstacle == segment) { valid = false; break; } } if (obstacle == food) valid = false; if (valid) { obstacles.push_back(obstacle); } else { i--; // 重新生成 } } }; generateObstacles(); // 游戏循环 while (!gameOver) { // 绘制游戏区域 system("cls"); // 清空屏幕 (Windows) for (int i = 0; i < height; ++i) { for (int j = 0; j < width; ++j) { if (i == 0 || i == height - 1 || j == 0 || j == width - 1) { cout << "#"; } else if (i == food.second && j == food.first) { cout << "$"; } else { bool isSnakeBody = false; for (auto &segment : snake) { if (segment.first == j && segment.second == i) { cout << "@"; isSnakeBody = true; break; } } if (isSnakeBody) continue; bool isObstacle = false; for (auto &obstacle : obstacles) { if (obstacle.first == j && obstacle.second == i) { cout << "X"; isObstacle = true; break; } } if (isObstacle) continue; cout << " "; } } cout << endl; } // 显示得分 cout << "得分: " << score << endl; // 处理键盘输入 if (_kbhit()) { char key = _getch(); switch (key) { case 'w': if (dir != DOWN) dir = UP; break; case 's': if (dir != UP) dir = DOWN; break; case 'a': if (dir != RIGHT) dir = LEFT; break; case 'd': if (dir != LEFT) dir = RIGHT; break; case 'x': gameOver = true; break; // 退出游戏 } } // 更新蛇的位置 int headX = snake[0].first; int headY = snake[0].second; switch (dir) { case UP: headY--; break; case DOWN: headY++; break; case LEFT: headX--; break; case RIGHT: headX++; break; } // 检查是否撞墙 if (headX < 1 || headX >= width - 1 || headY < 1 || headY >= height - 1) { gameOver = true; break; } // 检查是否撞到自己 for (size_t i = 1; i < snake.size(); ++i) { if (headX == snake[i].first && headY == snake[i].second) { gameOver = true; break; } } // 检查是否撞到障碍物 for (auto &obstacle : obstacles) { if (headX == obstacle.first && headY == obstacle.second) { gameOver = true; break; } } if (gameOver) break; // 更新蛇的身体 snake.insert(snake.begin(), {headX, headY}); // 检查是否吃到食物 if (headX == food.first && headY == food.second) { generateFood(); // 生成新的食物 generateObstacles(); // 生成新的障碍物 score += 10; } else { snake.pop_back(); // 移除蛇尾 } // 控制游戏速度 this_thread::sleep_for(chrono::milliseconds(speed)); } cout << "游戏结束! 得分: " << score << endl; return 0;
}
以上就是怎样用C++制作贪吃蛇游戏 控制台图形和键盘控制的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号