以下是一个简单的C++跑酷游戏代码示例,使用SFML库实现。这个游戏包含一个玩家角色(方块)、障碍物(矩形)和基本的跳跃机制:
#include <SFML/Graphics.hpp>
#include <vector>
#include <cstdlib>
#include <ctime>
const int WINDOW_WIDTH = 800;
const int WINDOW_HEIGHT = 600;
const float GRAVITY = 0.6f;
const float JUMP_FORCE = -15.0f;
const float OBSTACLE_SPEED = 5.0f;
class Player {
public:
sf::RectangleShape shape;
float velocityY;
Player() {
shape.setSize(sf::Vector2f(50, 50));
shape.setFillColor(sf::Color::Green);
shape.setPosition(100, WINDOW_HEIGHT - 150);
velocityY = 0;
}
void update() {
// 应用重力
velocityY += GRAVITY;
shape.move(0, velocityY);
// 地面碰撞检测
if (shape.getPosition().y > WINDOW_HEIGHT - 150) {
shape.setPosition(100, WINDOW_HEIGHT - 150);
velocityY = 0;
}
}
void jump() {
if (shape.getPosition().y >= WINDOW_HEIGHT - 150) {
velocityY = JUMP_FORCE;
}
}
};
class Obstacle {
public:
sf::RectangleShape shape;
bool passed = false;
Obstacle(float x) {
shape.setSize(sf::Vector2f(30, 80 + rand() % 100));
shape.setFillColor(sf::Color::Red);
shape.setPosition(x, WINDOW_HEIGHT - shape.getSize().y);
}
void update() {
shape.move(-OBSTACLE_SPEED, 0);
}
};
int main() {
srand(time(0));
sf::RenderWindow window(sf::VideoMode(WINDOW_WIDTH, WINDOW_HEIGHT), "简易跑酷游戏");
window.setFramerateLimit(60);
Player player;
std::vector<Obstacle> obstacles;
sf::Clock obstacleClock;
int score = 0;
sf::Font font;
if (!font.loadFromFile("arial.ttf")) {
// 如果加载字体失败,使用默认字体
font.loadFromFile("C:/Windows/Fonts/Arial.ttf");
}
sf::Text scoreText;
scoreText.setFont(font);
scoreText.setCharacterSize(24);
scoreText.setFillColor(sf::Color::White);
while (window.isOpen()) {
// 事件处理
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::Space) {
player.jump();
}
}
}
// 生成新障碍物
if (obstacleClock.getElapsedTime().asSeconds() > 1.5f) {
obstacles.push_back(Obstacle(WINDOW_WIDTH));
obstacleClock.restart();
}
// 更新游戏状态
player.update();
for (auto& obs : obstacles) {
obs.update();
// 计分逻辑(当玩家越过障碍物时)
if (!obs.passed && obs.shape.getPosition().x < player.shape.getPosition().x) {
obs.passed = true;
score++;
}
}
// 移除屏幕外的障碍物
obstacles.erase(std::remove_if(obstacles.begin(), obstacles.end(),
[](const Obstacle& o) { return o.shape.getPosition().x < -50; }),
obstacles.end());
// 碰撞检测
for (auto& obs : obstacles) {
if (player.shape.getGlobalBounds().intersects(obs.shape.getGlobalBounds())) {
window.close();
}
}
// 渲染
window.clear(sf::Color::Black);
// 绘制地面
sf::RectangleShape ground(sf::Vector2f(WINDOW_WIDTH, 150));
ground.setPosition(0, WINDOW_HEIGHT - 150);
ground.setFillColor(sf::Color(100, 100, 100));
window.draw(ground);
// 绘制玩家和障碍物
window.draw(player.shape);
for (auto& obs : obstacles) {
window.draw(obs.shape);
}
// 绘制分数
scoreText.setString("分数: " + std::to_string(score));
window.draw(scoreText);
window.display();
}
return 0;
}
游戏说明:
- 控制方式:按空格键跳跃
- 游戏目标:尽可能避开红色障碍物并跑得更远
- 计分规则:每成功越过一个障碍物得1分
运行要求:
- 需要安装SFML库(Simple and Fast Multimedia Library)
- 编译时链接SFML模块(graphics, window, system)
安装SFML(以Ubuntu为例):
sudo apt-get install libsfml-dev
编译命令(Linux):
g++ -c game.cpp -o game.o
g++ game.o -o game -lsfml-graphics -lsfml-window -lsfml-system
./game
游戏特点:
- 随机高度的障碍物
- 物理重力系统
- 分数统计
- 逐渐增加的难度(通过障碍物速度控制)
- 碰撞检测
扩展建议:
- 添加游戏开始/结束界面
- 实现角色动画和更好的视觉效果
- 添加音效和背景音乐
- 增加不同类型的障碍物
- 实现双跳或滑行等特殊动作
- 添加游戏难度随时间增加的机制
这个基础版本可以根据需要进行扩展,添加更多游戏元素和功能来增强游戏体验。
C++跑酷游戏代码解析(基于SFML库)
以下是对上述跑酷游戏代码的详细解析,涵盖核心模块和实现原理:
1. 游戏架构
#include <SFML/Graphics.hpp> // 图形渲染核心库
#include <vector> // 动态数组容器(用于障碍物管理)
#include <cstdlib> // 随机数生成
#include <ctime> // 时间种子
- SFML:跨平台多媒体库,简化图形/窗口/事件处理
- 游戏元素:
- 玩家(绿色方块)
- 障碍物(红色矩形)
- 地面(灰色平台)
- 分数显示
2. 物理系统实现
const float GRAVITY = 0.6f; // 重力加速度
const float JUMP_FORCE = -15.0f; // 跳跃初速度
void Player::update() {
velocityY += GRAVITY; // 模拟重力加速度
shape.move(0, velocityY); // 垂直位移
// 地面碰撞检测
if (shape.getPosition().y > WINDOW_HEIGHT - 150) {
shape.setPosition(100, WINDOW_HEIGHT - 150);
velocityY = 0; // 落地后重置速度
}
}
void Player::jump() {
// 仅当接触地面时允许跳跃
if (shape.getPosition().y >= WINDOW_HEIGHT - 150) {
velocityY = JUMP_FORCE; // 施加反向速度
}
}
- 物理模型:牛顿运动定律(v = v0 + at)
- 碰撞检测:通过坐标比较实现简易地面碰撞
- 跳跃机制:瞬间赋予负Y轴速度模拟跳跃
3. 障碍物生成系统
class Obstacle {
public:
void update() {
shape.move(-OBSTACLE_SPEED, 0); // 向左移动
}
};
// 主循环中
if (obstacleClock.getElapsedTime().asSeconds() > 1.5f) {
obstacles.push_back(Obstacle(WINDOW_WIDTH)); // 从右侧生成
obstacleClock.restart(); // 重置计时器
}
// 障碍物构造函数
Obstacle(float x) : passed(false) {
shape.setSize(sf::Vector2f(30, 80 + rand() % 100)); // 随机高度
shape.setPosition(x, WINDOW_HEIGHT - shape.getSize().y); // 底部对齐
}
- 生成策略:每1.5秒在窗口右侧生成新障碍物
- 随机化设计:高度在80-179像素间随机变化
- 内存管理:移除屏幕外障碍物防止内存泄漏
obstacles.erase(std::remove_if(obstacles.begin(), obstacles.end(), [](const Obstacle& o){ return o.shape.getPosition().x < -50; }), obstacles.end());
4. 碰撞检测与计分
// 碰撞检测(玩家vs障碍物)
for (auto& obs : obstacles) {
if (player.shape.getGlobalBounds().intersects(obs.shape.getGlobalBounds())) {
window.close(); // 碰撞则结束游戏
}
}
// 计分系统
if (!obs.passed && obs.shape.getPosition().x < player.shape.getPosition().x) {
obs.passed = true; // 标记为已通过
score++; // 增加分数
}
- 碰撞检测:使用SFML内置的
intersects()
进行矩形碰撞检测 - 计分逻辑:当玩家X坐标超过障碍物时计分(每个障碍物仅计一次)
5. 渲染管线
window.clear(sf::Color::Black); // 清屏
// 绘制地面
sf::RectangleShape ground(sf::Vector2f(WINDOW_WIDTH, 150));
ground.setFillColor(sf::Color(100,100,100));
window.draw(ground);
// 绘制游戏对象
window.draw(player.shape);
for (auto& obs : obstacles) window.draw(obs.shape);
// 绘制UI
scoreText.setString("分数: " + std::to_string(score));
window.draw(scoreText);
window.display(); // 刷新显示
- 渲染顺序:
- 背景 → 2. 地面 → 3. 游戏对象 → 4. UI元素
- 帧率控制:
setFramerateLimit(60)
确保60FPS流畅运行
6. 游戏控制与事件处理
while (window.pollEvent(event)) {
if (event.type == sf::Event::Closed)
window.close(); // 关闭窗口
if (event.type == sf::Event::KeyPressed) {
if (event.key.code == sf::Keyboard::Space) {
player.jump(); // 空格键触发跳跃
}
}
}
- 事件循环:实时检测键盘/窗口事件
- 响应式控制:按下空格立即触发跳跃(无按键延迟)
扩展建议与优化方向
-
游戏状态管理
enum GameState { MENU, PLAYING, GAME_OVER }; // 添加开始界面和结束界面
-
动态难度系统
// 随时间增加速度 OBSTACLE_SPEED = 5.0f + (score * 0.1f);
-
动画效果
// 使用纹理动画 sf::Texture runTextures[6]; sf::Sprite animatedSprite;
-
音效系统
sf::SoundBuffer jumpSound; sf::Sound sound; sound.play(); // 跳跃时播放
-
数据持久化
// 保存最高分 std::ofstream hiScoreFile("score.dat"); hiScoreFile << highScore;
-
粒子特效
// 落地灰尘效果 class ParticleSystem { void createParticles(sf::Vector2f pos); };
编译运行指南
-
安装SFML
- Windows: 下载预编译包 → 配置VS包含路径
- Ubuntu:
sudo apt install libsfml-dev
- macOS:
brew install sfml
-
编译命令
# Linux/macOS g++ -std=c++11 game.cpp -o runner -lsfml-graphics -lsfml-window -lsfml-system # Windows (MinGW) g++ game.cpp -o runner.exe -I SFML/include -L SFML/lib -lsfml-graphics -lsfml-window -lsfml-system
-
资源管理
- 创建
assets
文件夹存放纹理/字体/音效 - 使用相对路径加载资源:
font.loadFromFile("assets/arial.ttf")
- 创建
此代码实现了一个完整的2D跑酷游戏核心框架,包含物理模拟、对象管理、碰撞检测等关键功能。通过SFML的轻量级封装,既保证了游戏性能,又提供了良好的扩展接口,适合作为游戏开发学习的基础项目。