夏曹俊:C++零基础到工程实战,视频+课件完结

夏曹俊:C++零基础到工程实战,视频+课件完结---youkeit.xyz/15939/

C++游戏开发核心技能实战:从引擎底层到游戏逻辑实现

项目概述

本文将带您深入C++游戏开发的核心领域,涵盖以下关键技术:

  1. 游戏引擎架构:自制微型游戏引擎框架
  2. 图形渲染:OpenGL现代渲染管线实现
  3. 物理系统:2D刚体物理引擎开发
  4. 资源管理:智能资源加载与缓存系统
  5. 游戏逻辑: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;
};

项目总结

通过本实战项目,我们实现了:

  1. 引擎架构:模块化的游戏引擎核心框架
  2. 图形渲染:基于OpenGL的现代渲染管线
  3. 物理系统:2D刚体物理与碰撞检测
  4. 资源管理:智能资源加载与缓存机制
  5. 游戏逻辑:基于ECS架构的游戏对象系统
graph TD A[游戏引擎核心] --> B[窗口管理] A --> C[输入系统] A --> D[资源管理] A --> E[渲染系统] A --> F[物理系统] A --> G[音频系统] E --> H[OpenGL/Vulkan] F --> I[Box2D/自定义] D --> J[纹理/着色器/模型]
相关推荐
databook3 小时前
manim边做边学--文字创建销毁的打字机效果
后端·python·动效
林太白3 小时前
八大数据结构
前端·后端·算法
林太白3 小时前
Rust14-字典数据
后端·rust
国思RDIF框架3 小时前
国思RDIF低代码快速开发框架 v6.2.2版本发布
前端·vue.js·后端
Java水解3 小时前
Java基础------真实大厂面试题汇总(含答案)
java·后端·面试
L.EscaRC3 小时前
面向 Spring Boot 的 JVM 深度解析
jvm·spring boot·后端
Undoom3 小时前
构建高可靠 OpenEuler 运维体系:从虚拟化部署到 Systemd 自动化核心实践
后端
澪贰3 小时前
云原生基石的试金石:基于 openEuler 部署 Docker 与 Nginx 的全景实录
后端
oak隔壁找我3 小时前
SpringBoot Starter 进阶教程
java·后端·架构