夏曹俊: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[纹理/着色器/模型]
相关推荐
SomeB1oody24 分钟前
【RustyML入门】7.4. 按需裁剪与模块化集成
开发语言·后端·机器学习·rust·教程
罗超驿27 分钟前
SpringBoot 快速入门
java·spring boot·后端
卷无止境1 小时前
除了开发api,FastAPI其实也可以配合jinja2模板写页面
后端·python·fastapi
newerp1 小时前
Redis 操作与缓存策略
后端·程序员·go
newerp1 小时前
GORM ORM 基础
后端·程序员·go
小岛前端1 小时前
AI Skills 已经封神,但新的问题却越来越严重!
前端·后端·github
拖孩1 小时前
一个人 + AI 做的小程序,上线 15 天赚了 10 块 5
前端·后端·微信小程序
newerp1 小时前
CRUD 操作与预处理语句
后端·程序员·go
wei_shuo2 小时前
KES 数据同步与ETL实战:数据集成、转换与实时同步方案
后端
乒乓狂魔14786739970002 小时前
LangGraph:用一张图,编排一群 AI 助手
后端