C++ 游戏开发示例:简单的贪吃蛇游戏
下面是一个使用C++和SFML库实现的简单贪吃蛇游戏。这个示例展示了游戏开发的基本概念,包括游戏循环、图形渲染、用户输入处理和游戏逻辑。
cpp
#include <SFML/Graphics.hpp>
#include <vector>
#include <random>// 游戏常量
const int WINDOW_WIDTH = 800;
const int WINDOW_HEIGHT = 600;
const int GRID_SIZE = 20;
const int GRID_WIDTH = WINDOW_WIDTH / GRID_SIZE;
const int GRID_HEIGHT = WINDOW_HEIGHT / GRID_SIZE;// 方向枚举
enum class Direction { Up, Down, Left, Right };class Snake {
public:Snake() {// 初始化蛇身,从屏幕中央开始body.push_back(sf::Vector2i(GRID_WIDTH / 2, GRID_HEIGHT / 2));direction = Direction::Right;growPending = 3; // 初始长度为4}void changeDirection(Direction newDirection) {// 防止直接反向移动if ((direction == Direction::Up && newDirection != Direction::Down) ||(direction == Direction::Down && newDirection != Direction::Up) ||(direction == Direction::Left && newDirection != Direction::Right) ||(direction == Direction::Right && newDirection != Direction::Left)) {direction = newDirection;
rd.xjyl.gov.cn/upload/1982074940999303168.html
rd.xjyl.gov.cn/upload/1982074941032857600.html
rd.xjyl.gov.cn/upload/1982074941074800640.html
rd.xjyl.gov.cn/upload/1982074941158686720.html
rd.xjyl.gov.cn/upload/1982074941171269633.html
rd.xjyl.gov.cn/upload/1982074941171269632.html
rd.xjyl.gov.cn/upload/1982074941234184192.html
rd.xjyl.gov.cn/upload/1982074941485842432.html
rd.xjyl.gov.cn/upload/1982074941506813952.html
rd.xjyl.gov.cn/upload/1982074941515202560.html
rd.xjyl.gov.cn/upload/1982074941544562688.html
rd.xjyl.gov.cn/upload/1982074941607477248.html
rd.xjyl.gov.cn/upload/1982074941670391808.html
rd.xjyl.gov.cn/upload/1982074941792026624.html
rd.xjyl.gov.cn/upload/1982074941850746880.html
rd.xjyl.gov.cn/upload/1982074942056267776.html
rd.xjyl.gov.cn/upload/1982074942106599424.html
rd.xjyl.gov.cn/upload/1982074942135959552.html
rd.xjyl.gov.cn/upload/1982074942144348160.html
rd.xjyl.gov.cn/upload/1982074942190485504.html
rd.xjyl.gov.cn/upload/1982074942307926016.html
rd.xjyl.gov.cn/upload/1982074942505058304.html
rd.xjyl.gov.cn/upload/1982074942484086784.html}}void update() {// 移动蛇身sf::Vector2i newHead = body.front();switch (direction) {case Direction::Up:newHead.y--;break;case Direction::Down:newHead.y++;break;case Direction::Left:newHead.x--;break;case Direction::Right:newHead.x++;break;}// 检查边界碰撞if (newHead.x < 0 || newHead.x >= GRID_WIDTH || newHead.y < 0 || newHead.y >= GRID_HEIGHT) {reset();return;}// 检查自身碰撞for (auto segment : body) {if (segment == newHead) {reset();return;}}// 添加新头部body.insert(body.begin(), newHead);// 如果不需要增长,移除尾部if (growPending > 0) {growPending--;} else {body.pop_back();}}void grow() {growPending++;}void reset() {body.clear();body.push_back(sf::Vector2i(GRID_WIDTH / 2, GRID_HEIGHT / 2));direction = Direction::Right;growPending = 3;}const std::vector<sf::Vector2i>& getBody() const {return body;}sf::Vector2i getHead() const {return body.front();}private:std::vector<sf::Vector2i> body;Direction direction;int growPending;
};class Food {
public:Food() {respawn();}void respawn() {std::random_device rd;std::mt19937 gen(rd());std::uniform_int_distribution<> disX(0, GRID_WIDTH - 1);std::uniform_int_distribution<> disY(0, GRID_HEIGHT - 1);position.x = disX(gen);position.y = disY(gen);}sf::Vector2i getPosition() const {return position;}private:sf::Vector2i position;
};class Game {
public:Game() : window(sf::VideoMode(WINDOW_WIDTH, WINDOW_HEIGHT), "Snake Game"), snake(), food(), score(0) {// 设置帧率限制window.setFramerateLimit(10);// 加载字体if (!font.loadFromFile("arial.ttf")) {// 如果无法加载字体,使用默认字体font.loadFromFile("C:/Windows/Fonts/arial.ttf");}scoreText.setFont(font);scoreText.setCharacterSize(24);scoreText.setFillColor(sf::Color::White);scoreText.setPosition(10, 10);updateScoreText();}void run() {while (window.isOpen()) {handleEvents();update();render();}}private:void handleEvents() {sf::Event event;while (window.pollEvent(event)) {if (event.type == sf::Event::Closed) {window.close();} else if (event.type == sf::Event::KeyPressed) {switch (event.key.code) {case sf::Keyboard::Up:snake.changeDirection(Direction::Up);break;case sf::Keyboard::Down:snake.changeDirection(Direction::Down);break;case sf::Keyboard::Left:snake.changeDirection(Direction::Left);break;case sf::Keyboard::Right:snake.changeDirection(Direction::Right);break;case sf::Keyboard::Escape:window.close();break;default:break;}}}}void update() {snake.update();// 检查是否吃到食物if (snake.getHead() == food.getPosition()) {snake.grow();food.respawn();score += 10;updateScoreText();}}void render() {window.clear(sf::Color::Black);// 绘制蛇sf::RectangleShape segment(sf::Vector2f(GRID_SIZE - 1, GRID_SIZE - 1));segment.setFillColor(sf::Color::Green);for (auto pos : snake.getBody()) {segment.setPosition(pos.x * GRID_SIZE, pos.y * GRID_SIZE);window.draw(segment);}// 绘制食物sf::CircleShape foodShape(GRID_SIZE / 2 - 1);foodShape.setFillColor(sf::Color::Red);foodShape.setPosition(food.getPosition().x * GRID_SIZE, food.getPosition().y * GRID_SIZE);window.draw(foodShape);// 绘制分数window.draw(scoreText);window.display();
rd.xjyl.gov.cn/upload/1982074942513446912.html
rd.xjyl.gov.cn/upload/1982074942693801984.html
rd.xjyl.gov.cn/upload/1982074942681219072.html
rd.xjyl.gov.cn/upload/1982074942777688064.html
rd.xjyl.gov.cn/upload/1982074942765105152.html
rd.xjyl.gov.cn/upload/1982074942828019712.html
rd.xjyl.gov.cn/upload/1982074942953848832.html
rd.xjyl.gov.cn/upload/1982074942949654528.html
rd.xjyl.gov.cn/upload/1982074943130009601.html
rd.xjyl.gov.cn/upload/1982074943150981120.html
rd.xjyl.gov.cn/upload/1982074943130009600.html
rd.xjyl.gov.cn/upload/1982074943176146944.html
rd.xjyl.gov.cn/upload/1982074943272615936.html
rd.xjyl.gov.cn/upload/1982074943339724800.html
rd.xjyl.gov.cn/upload/1982074943490719744.html
rd.xjyl.gov.cn/upload/1982074943520079872.html
rd.xjyl.gov.cn/upload/1982074943608160256.html
rd.xjyl.gov.cn/upload/1982074943629131776.html
rd.xjyl.gov.cn/upload/1982074943801098240.html
rd.xjyl.gov.cn/upload/1982074943935315968.html
rd.xjyl.gov.cn/upload/1982074943981453312.html
rd.xjyl.gov.cn/upload/1982074944308609024.html
rd.xjyl.gov.cn/upload/1982074944455409664.html
rd.xjyl.gov.cn/upload/1982074944560267264.html
rd.xjyl.gov.cn/upload/1982074944606404608.html}void updateScoreText() {scoreText.setString("Score: " + std::to_string(score));}sf::RenderWindow window;Snake snake;Food food;int score;sf::Font font;sf::Text scoreText;
};int main() {Game game;game.run();return 0;
}
如何运行这个游戏
-
确保安装了SFML库。你可以从SFML官网下载并安装。
-
使用以下命令编译(假设使用g++):
text
g++ -c snake_game.cpp -I/path/to/SFML/include g++ snake_game.o -o snake_game -L/path/to/SFML/lib -lsfml-graphics -lsfml-window -lsfml-system
-
运行游戏:
text
./snake_game
游戏功能
-
使用方向键控制蛇的移动
-
吃到红色食物会增加蛇的长度和分数
-
撞到墙壁或自身会重置游戏
-
按ESC键退出游戏
扩展建议
-
添加游戏开始和结束界面
-
实现难度级别(通过改变蛇的移动速度)
-
添加音效和更多视觉效果
-
实现高分记录功能
-
添加不同类型的食物,具有不同的效果
这个示例展示了C++游戏开发的基本概念,你可以基于此代码进一步扩展和完善游戏功能。
