当前位置: 首页 > news >正文

C++写有一个2D 小游戏(贪吃蛇)

用 C++ 开发游戏需要结合图形库、输入处理、游戏逻辑等模块,以下以2D 小游戏(贪吃蛇)为例,展示 C++ 游戏开发的核心流程,使用跨平台图形库SFML(简单易用,适合入门)。

一、准备工作

1. 安装 SFML 库

  • 下载地址:SFML 官网
  • 配置环境:将 SFML 的 include 目录添加到编译器包含路径,lib 目录添加到库路径,链接对应库文件(如sfml-graphics.libsfml-window.libsfml-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 重启)。

四、进阶扩展方向

  1. 添加计分系统:记录吃到的食物数量,显示在窗口中。
  2. 难度递增:随着分数增加,提高游戏帧率(蛇移动速度加快)。
  3. 音效与音乐:使用 SFML 的sf::Soundsf::Music添加音效(如吃到食物、游戏结束)。
  4. 3D 游戏开发:若需开发 3D 游戏,可使用OpenGL或引擎(如 Unreal Engine、Unity,底层用 C++)。
  5. 物理引擎集成:引入 Box2D 等物理引擎,实现更复杂的碰撞和运动(如格斗游戏、赛车游戏)。

五、C++ 游戏开发的优势

  • 性能高效:C++ 是编译型语言,直接操作内存,适合对帧率和响应速度要求高的游戏。
  • 底层控制:可直接调用图形 API(如 DirectX、OpenGL),定制化程度高。
  • 生态丰富:有 SFML、SDL、Qt 等图形库,以及 Unreal Engine 等成熟游戏引擎支持。
通过这个贪吃蛇示例,可快速掌握 C++ 游戏开发的基础框架,后续可根据需求扩展更复杂的游戏逻辑!
http://www.gsyq.cn/news/63239.html

相关文章:

  • CF2157C Meximum Array 2
  • AT_fps_24_b 整数の組
  • 第五十篇
  • 我踩坑后总结:企业微信客服API接入客服系统,90%的人都搞错了!
  • 香橙派上进行MQTT数据存储客户端开发(一)基本环境配置
  • 编程中的枚举法与数学上的穷举法有何区别?
  • 《程序员修炼之道:从小工到专家》阅读笔记5
  • C# 图片加载引发的内存溢出异常
  • Mac 安装 4K Video Downloader v5.0.0.5303-1.dmg 方法(附安装包)
  • TPS的另外一层含义:绝对并发用户数 - BKY007
  • 笔记——OI中求逆元的几种方式(不含数学知识的讲解)
  • 2025国内公关公司排名推荐(整合权威数据源):十大机构深度对比,专业分析与选择指南
  • acme证书申请
  • [CEOI 2025] Equal Mex 题解
  • Open WebUI大模型输出完成后新对话响应延迟、输出变慢问题
  • 2025年11月液体容器磁致伸缩液位计,格雷母线,lvdt位移传感器厂家最新推荐,容器监测与位移适配指南
  • Python中isdigit、isdecimal、isnumeric区别详解
  • 3D 场景预加载应用实现 | 图扑软件
  • 2025年11月GEO公司推荐:全链路破局企业流量困境,AI驱动搜索优化实力全解析
  • 医疗器械渠道管理革新:数字化平台如何解决行业痛点
  • 如何在VSCode中Debug(带有参数,name、program、$file、args、pickArgs、指定虚拟环境)
  • 适合应届生:零经验专业简历模板TOP4
  • 2025年简约智能家居照明灯品牌推荐,让生活更智能
  • [论文阅读] AI | 大语言模型服务框架服务级目标和系统级指标优化研究
  • 2025年11月治鼻炎产品推荐:高性价比解决方案与市场热门排行榜
  • 蓝牙音频协议——安卓开发
  • 2025年11月治鼻炎产品推荐:一份详尽的清单与选择指南
  • 成为中国中小制造业企业数字营销领域的引领者 ——纪实西安动力无限的信息化赋能之路
  • SKI欧洲原装进口瓷砖:汇聚国际匠心,打造高端家居空间
  • Java NIO框架和传统的IO框架有什么区别?