
夏曹俊:C++零基础到工程实战,视频+课件完结---youkeit.xyz/15939/
C++游戏开发核心技能实战:从引擎底层到游戏逻辑实现
项目概述
本文将带您深入C++游戏开发的核心领域,涵盖以下关键技术:
- 游戏引擎架构:自制微型游戏引擎框架
- 图形渲染:OpenGL现代渲染管线实现
- 物理系统:2D刚体物理引擎开发
- 资源管理:智能资源加载与缓存系统
- 游戏逻辑:ECS架构实现游戏对象系统
环境准备
bash
# 安装必要工具链(Ubuntu示例)
sudo apt install build-essential cmake libglfw3-dev libglew-dev libfreetype6-dev
# Windows推荐使用VS2019/2022并安装vcpkg管理依赖
vcpkg install glfw3 glew freetype
第一部分:游戏引擎架构设计
1. 核心引擎类设计
cpp
// Engine/Core/Engine.h
#pragma once
#include <memory>
#include <string>
class Window;
class Renderer;
class InputSystem;
class ResourceManager;
class Engine {
public:
Engine(const std::string& title, int width, int height);
~Engine();
void Initialize();
void Run();
void Shutdown();
bool IsRunning() const { return m_isRunning; }
// 子系统访问
Window& GetWindow() { return *m_window; }
Renderer& GetRenderer() { return *m_renderer; }
private:
void ProcessInput();
void Update(float deltaTime);
void Render();
bool m_isRunning = false;
std::unique_ptr<Window> m_window;
std::unique_ptr<Renderer> m_renderer;
std::unique_ptr<InputSystem> m_input;
std::unique_ptr<ResourceManager> m_resources;
};
2. 主循环实现
cpp
// Engine/Core/Engine.cpp
#include "Engine.h"
#include "Window.h"
#include "Renderer.h"
#include <chrono>
Engine::Engine(const std::string& title, int width, int height) {
m_window = std::make_unique<Window>(title, width, height);
m_renderer = std::make_unique<Renderer>();
// 其他子系统初始化...
}
void Engine::Run() {
Initialize();
auto lastTime = std::chrono::high_resolution_clock::now();
while (IsRunning()) {
auto currentTime = std::chrono::high_resolution_clock::now();
float deltaTime = std::chrono::duration<float>(currentTime - lastTime).count();
lastTime = currentTime;
ProcessInput();
Update(deltaTime);
Render();
}
Shutdown();
}
第二部分:图形渲染系统
1. OpenGL渲染器封装
cpp
// Engine/Graphics/Renderer.h
#pragma once
#include <GL/glew.h>
#include <glm/glm.hpp>
#include <vector>
#include <memory>
class Shader;
class Texture;
class VertexArray;
class Renderer {
public:
Renderer();
~Renderer();
void Initialize();
void BeginFrame();
void EndFrame();
void DrawSprite(const glm::mat4& transform,
const std::shared_ptr<Texture>& texture,
const glm::vec4& color = glm::vec4(1.0f));
private:
std::unique_ptr<Shader> m_spriteShader;
std::unique_ptr<VertexArray> m_spriteVAO;
struct SpriteBatch {
glm::mat4 transform;
std::shared_ptr<Texture> texture;
glm::vec4 color;
};
std::vector<SpriteBatch> m_spriteBatch;
};
2. 着色器实现
glsl
// Assets/Shaders/Sprite.vert
#version 330 core
layout(location = 0) in vec3 aPos;
layout(location = 1) in vec2 aTexCoord;
uniform mat4 uModel;
uniform mat4 uViewProj;
out vec2 vTexCoord;
void main() {
gl_Position = uViewProj * uModel * vec4(aPos, 1.0);
vTexCoord = aTexCoord;
}
glsl
// Assets/Shaders/Sprite.frag
#version 330 core
in vec2 vTexCoord;
out vec4 FragColor;
uniform sampler2D uTexture;
uniform vec4 uColor;
void main() {
FragColor = texture(uTexture, vTexCoord) * uColor;
}
第三部分:物理系统实现
1. 2D物理引擎核心
cpp
// Engine/Physics/Physics2D.h
#pragma once
#include <vector>
#include <glm/glm.hpp>
class Collider2D;
struct Rigidbody2D {
glm::vec2 position;
glm::vec2 velocity;
glm::vec2 force;
float mass;
float restitution;
bool isKinematic;
Collider2D* collider = nullptr;
};
class Physics2D {
public:
static Physics2D& Get();
void Update(float deltaTime);
Rigidbody2D* CreateRigidbody();
void DestroyRigidbody(Rigidbody2D* body);
private:
std::vector<Rigidbody2D*> m_bodies;
glm::vec2 m_gravity { 0.0f, -9.8f };
void Integrate(Rigidbody2D* body, float deltaTime);
void DetectCollisions();
void ResolveCollision(Rigidbody2D* a, Rigidbody2D* b);
};
2. 碰撞检测实现
cpp
// Engine/Physics/Collision2D.cpp
#include "Collision2D.h"
bool Collision2D::TestAABBAABB(const AABB& a, const AABB& b) {
return (a.min.x <= b.max.x && a.max.x >= b.min.x) &&
(a.min.y <= b.max.y && a.max.y >= b.min.y);
}
CollisionManifold Collision2D::FindAABBAABBManifold(const AABB& a, const AABB& b) {
CollisionManifold result;
result.isColliding = TestAABBAABB(a, b);
if (result.isColliding) {
// 计算穿透向量
glm::vec2 distances[4] = {
{ b.max.x - a.min.x, 0.0f }, // 右
{ b.min.x - a.max.x, 0.0f }, // 左
{ 0.0f, b.max.y - a.min.y }, // 上
{ 0.0f, b.min.y - a.max.y } // 下
};
float minPenetration = FLT_MAX;
for (const auto& dist : distances) {
float penetration = fabs(dist.x) > 0 ? fabs(dist.x) : fabs(dist.y);
if (penetration < minPenetration) {
minPenetration = penetration;
result.normal = glm::normalize(dist);
}
}
result.penetration = minPenetration;
}
return result;
}
第四部分:资源管理系统
1. 纹理资源管理
cpp
// Engine/Resources/TextureManager.h
#pragma once
#include <unordered_map>
#include <memory>
#include <string>
class Texture;
class TextureManager {
public:
static TextureManager& Get();
std::shared_ptr<Texture> LoadTexture(const std::string& filePath);
void UnloadTexture(const std::string& filePath);
void UnloadAll();
private:
std::unordered_map<std::string, std::weak_ptr<Texture>> m_textureCache;
// 防止外部构造
TextureManager() = default;
~TextureManager() = default;
};
2. 纹理类实现
cpp
// Engine/Graphics/Texture.cpp
#include "Texture.h"
#include <stb_image.h>
#include <iostream>
Texture::Texture(const std::string& filePath) : m_filePath(filePath) {
stbi_set_flip_vertically_on_load(true);
unsigned char* data = stbi_load(filePath.c_str(),
&m_width, &m_height,
&m_channels, 0);
if (!data) {
std::cerr << "Failed to load texture: " << filePath << std::endl;
return;
}
glGenTextures(1, &m_textureID);
glBindTexture(GL_TEXTURE_2D, m_textureID);
GLenum format = m_channels == 4 ? GL_RGBA : GL_RGB;
glTexImage2D(GL_TEXTURE_2D, 0, format,
m_width, m_height, 0,
format, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
stbi_image_free(data);
}
第五部分:游戏逻辑实现(ECS架构)
1. ECS核心结构
cpp
// Engine/ECS/World.h
#pragma once
#include <vector>
#include <memory>
#include <bitset>
#include <unordered_map>
class Entity;
class System;
class World {
public:
World();
~World();
Entity* CreateEntity();
void DestroyEntity(Entity* entity);
template<typename T, typename... Args>
T* AddSystem(Args&&... args) {
static_assert(std::is_base_of<System, T>::value,
"T must inherit from System");
auto system = std::make_unique<T>(std::forward<Args>(args)...);
T* ptr = system.get();
m_systems.push_back(std::move(system));
return ptr;
}
void Update(float deltaTime);
private:
std::vector<std::unique_ptr<Entity>> m_entities;
std::vector<std::unique_ptr<System>> m_systems;
};
2. 渲染系统示例
cpp
// Engine/Systems/RenderSystem.h
#pragma once
#include "System.h"
#include "../Components/SpriteComponent.h"
#include "../Components/TransformComponent.h"
class RenderSystem : public System {
public:
RenderSystem(Renderer& renderer) : m_renderer(renderer) {}
void Update(float deltaTime) override {
for (auto& entity : GetEntities()) {
auto transform = entity->GetComponent<TransformComponent>();
auto sprite = entity->GetComponent<SpriteComponent>();
if (transform && sprite) {
glm::mat4 model(1.0f);
model = glm::translate(model, glm::vec3(transform->position, 0.0f));
model = glm::rotate(model, transform->rotation, glm::vec3(0.0f, 0.0f, 1.0f));
model = glm::scale(model, glm::vec3(transform->scale, 1.0f));
m_renderer.DrawSprite(model, sprite->texture, sprite->color);
}
}
}
private:
Renderer& m_renderer;
};
第六部分:游戏示例 - 2D平台游戏
1. 玩家控制器实现
cpp
// Game/Components/PlayerController.h
#pragma once
#include "../Engine/ECS/Component.h"
#include "../Engine/Physics/Rigidbody2D.h"
class PlayerController : public Component {
public:
void Update(float deltaTime) override {
auto rigidbody = GetEntity()->GetComponent<Rigidbody2D>();
if (!rigidbody) return;
float moveSpeed = 5.0f;
float jumpForce = 7.0f;
if (Input::GetKey(GLFW_KEY_A)) {
rigidbody->velocity.x = -moveSpeed;
} else if (Input::GetKey(GLFW_KEY_D)) {
rigidbody->velocity.x = moveSpeed;
} else {
rigidbody->velocity.x = 0.0f;
}
if (Input::GetKeyDown(GLFW_KEY_SPACE) && m_isGrounded) {
rigidbody->velocity.y = jumpForce;
m_isGrounded = false;
}
}
void OnCollisionEnter(Collision2D& collision) override {
if (collision.normal.y > 0.5f) {
m_isGrounded = true;
}
}
private:
bool m_isGrounded = false;
};
2. 游戏初始化
cpp
// Game/Game.cpp
#include "Engine/Core/Engine.h"
#include "Engine/ECS/World.h"
#include "Engine/Systems/RenderSystem.h"
#include "Engine/Systems/PhysicsSystem.h"
#include "Components/PlayerController.h"
class Game {
public:
void Initialize() {
m_engine = std::make_unique<Engine>("2D Platformer", 1280, 720);
m_world = std::make_unique<World>();
// 添加系统
auto renderSystem = m_world->AddSystem<RenderSystem>(m_engine->GetRenderer());
auto physicsSystem = m_world->AddSystem<PhysicsSystem>();
// 创建玩家实体
Entity* player = m_world->CreateEntity();
player->AddComponent<TransformComponent>();
player->AddComponent<SpriteComponent>(
TextureManager::Get().LoadTexture("Assets/Textures/player.png")
);
player->AddComponent<Rigidbody2D>();
player->AddComponent<BoxCollider2D>(glm::vec2(0.8f, 1.5f));
player->AddComponent<PlayerController>();
// 创建平台
Entity* platform = m_world->CreateEntity();
platform->AddComponent<TransformComponent>(glm::vec2(0.0f, -2.0f));
platform->AddComponent<BoxCollider2D>(glm::vec2(10.0f, 0.5f));
}
void Run() {
m_engine->Run();
}
private:
std::unique_ptr<Engine> m_engine;
std::unique_ptr<World> m_world;
};
项目总结
通过本实战项目,我们实现了:
- 引擎架构:模块化的游戏引擎核心框架
- 图形渲染:基于OpenGL的现代渲染管线
- 物理系统:2D刚体物理与碰撞检测
- 资源管理:智能资源加载与缓存机制
- 游戏逻辑:基于ECS架构的游戏对象系统
graph TD
A[游戏引擎核心] --> B[窗口管理]
A --> C[输入系统]
A --> D[资源管理]
A --> E[渲染系统]
A --> F[物理系统]
A --> G[音频系统]
E --> H[OpenGL/Vulkan]
F --> I[Box2D/自定义]
D --> J[纹理/着色器/模型]