用 C++ 开发游戏需要结合图形库、输入处理、游戏逻辑等模块,以下以2D 小游戏(贪吃蛇)为例,展示 C++ 游戏开发的核心流程,使用跨平台图形库SFML(简单易用,适合入门)。
一、准备工作
1. 安装 SFML 库
- 下载地址:SFML 官网
- 配置环境:将 SFML 的 include 目录添加到编译器包含路径,lib 目录添加到库路径,链接对应库文件(如
sfml-graphics.lib、sfml-window.lib、sfml-system.lib)。
二、贪吃蛇游戏实现代码
cpp
运行
#include <SFML/Graphics.hpp>
#include <vector>
#include <random>
#include <iostream>// 方向枚举
enum Direction { UP, DOWN, LEFT, RIGHT };// 蛇节点结构体
struct SnakeSegment {sf::Vector2i position;SnakeSegment(int x, int y) : position(x, y) {}
};class SnakeGame {
private:sf::RenderWindow window; // 游戏窗口std::vector<SnakeSegment> snake; // 蛇的身体Direction dir; // 当前方向sf::Vector2i food; // 食物位置int gridSize; // 网格大小int windowSize; // 窗口大小bool gameOver; // 游戏结束标志std::random_device rd; // 随机数生成器std::mt19937 rng; // 随机数引擎public:SnakeGame(int gridSize = 20, int windowSize = 600) : gridSize(gridSize), windowSize(windowSize), dir(RIGHT), gameOver(false), rng(rd()) {// 初始化窗口window.create(sf::VideoMode(windowSize, windowSize), "Snake Game | C++ SFML");window.setFramerateLimit(10); // 控制游戏帧率// 初始化蛇(3个节点)snake.emplace_back(windowSize/2, windowSize/2);snake.emplace_back(windowSize/2 - gridSize, windowSize/2);snake.emplace_back(windowSize/2 - 2*gridSize, windowSize/2);// 生成初始食物spawnFood();}// 生成食物(随机位置,不与蛇身重叠)void spawnFood() {std::uniform_int_distribution<int> dist(0, (windowSize / gridSize) - 1);int x = dist(rng) * gridSize;int y = dist(rng) * gridSize;// 检查是否与蛇身重叠for (const auto& segment : snake) {if (segment.position.x == x && segment.position.y == y) {spawnFood(); // 重叠则重新生成return;}}food = sf::Vector2i(x, y);}// 处理输入void handleInput() {sf::Event event;while (window.pollEvent(event)) {if (event.type == sf::Event::Closed)window.close();// 键盘方向控制(防止反向移动)if (event.type == sf::Event::KeyPressed) {if (event.key.code == sf::Keyboard::Up && dir != DOWN)dir = UP;else if (event.key.code == sf::Keyboard::Down && dir != UP)dir = DOWN;else if (event.key.code == sf::Keyboard::Left && dir != RIGHT)dir = LEFT;else if (event.key.code == sf::Keyboard::Right && dir != LEFT)dir = RIGHT;else if (event.key.code == sf::Keyboard::R && gameOver)restart(); // 重新开始游戏}}}// 更新游戏逻辑void update() {if (gameOver) return;// 移动蛇头sf::Vector2i newHead = snake.front().position;switch (dir) {case UP: newHead.y -= gridSize; break;case DOWN: newHead.y += gridSize; break;case LEFT: newHead.x -= gridSize; break;case RIGHT: newHead.x += gridSize; break;}snake.insert(snake.begin(), SnakeSegment(newHead.x, newHead.y));// 检查是否吃到食物if (snake.front().position == food) {spawnFood(); // 生成新食物(蛇身不缩短)} else {snake.pop_back(); // 没吃到则缩短尾部}// 检查碰撞(边界或自身)checkCollision();}// 碰撞检测void checkCollision() {// 边界碰撞if (snake.front().position.x < 0 || snake.front().position.x >= windowSize ||snake.front().position.y < 0 || snake.front().position.y >= windowSize) {gameOver = true;}// 自身碰撞for (size_t i = 1; i < snake.size(); ++i) {if (snake.front().position == snake[i].position) {gameOver = true;break;}}}// 重新开始游戏void restart() {snake.clear();dir = RIGHT;gameOver = false;// 重新初始化蛇snake.emplace_back(windowSize/2, windowSize/2);snake.emplace_back(windowSize/2 - gridSize, windowSize/2);snake.emplace_back(windowSize/2 - 2*gridSize, windowSize/2);spawnFood();}// 渲染画面void render() {window.clear(sf::Color::Black); // 清空窗口(黑色背景)// 绘制蛇for (const auto& segment : snake) {sf::RectangleShape rect(sf::Vector2f(gridSize - 1, gridSize - 1)); // -1留间隙rect.setPosition(segment.position.x, segment.position.y);rect.setFillColor(sf::Color::Green);window.draw(rect);}// 绘制食物sf::RectangleShape foodRect(sf::Vector2f(gridSize - 1, gridSize - 1));foodRect.setPosition(food.x, food.y);foodRect.setFillColor(sf::Color::Red);window.draw(foodRect);// 游戏结束提示if (gameOver) {sf::Font font;if (font.loadFromFile("arial.ttf")) { // 需确保字体文件存在sf::Text text("Game Over! Press R to Restart", font, 24);text.setPosition(windowSize/2 - text.getLocalBounds().width/2, windowSize/2);text.setFillColor(sf::Color::White);window.draw(text);}}window.display(); // 显示画面}// 游戏主循环void run() {while (window.isOpen()) {handleInput();update();render();}}
};int main() {SnakeGame game;game.run();return 0;
}
三、代码解析
1. 核心模块
- 窗口管理:使用
sf::RenderWindow创建游戏窗口,设置帧率限制(10FPS,控制蛇的移动速度)。 - 蛇的逻辑:用
std::vector存储蛇的身体节点,通过插入头部、删除尾部实现移动;吃到食物时不删除尾部,实现蛇身增长。 - 食物生成:利用随机数生成食物位置,确保不与蛇身重叠。
- 碰撞检测:检测蛇头是否撞边界或自身,触发游戏结束。
- 渲染系统:通过
sf::RectangleShape绘制蛇和食物,游戏结束时显示提示文字。
2. 运行说明
- 确保 SFML 库配置正确,且项目目录下有
arial.ttf字体文件(或修改字体路径)。 - 编译运行后,用方向键控制蛇的移动,吃到红色食物得分,撞边界 / 自身则游戏结束(按 R 重启)。
四、进阶扩展方向
- 添加计分系统:记录吃到的食物数量,显示在窗口中。
- 难度递增:随着分数增加,提高游戏帧率(蛇移动速度加快)。
- 音效与音乐:使用 SFML 的
sf::Sound和sf::Music添加音效(如吃到食物、游戏结束)。 - 3D 游戏开发:若需开发 3D 游戏,可使用OpenGL或引擎(如 Unreal Engine、Unity,底层用 C++)。
- 物理引擎集成:引入 Box2D 等物理引擎,实现更复杂的碰撞和运动(如格斗游戏、赛车游戏)。
五、C++ 游戏开发的优势
- 性能高效:C++ 是编译型语言,直接操作内存,适合对帧率和响应速度要求高的游戏。
- 底层控制:可直接调用图形 API(如 DirectX、OpenGL),定制化程度高。
- 生态丰富:有 SFML、SDL、Qt 等图形库,以及 Unreal Engine 等成熟游戏引擎支持。
通过这个贪吃蛇示例,可快速掌握 C++ 游戏开发的基础框架,后续可根据需求扩展更复杂的游戏逻辑!