讲师中心 微信公众号
AI工具推荐 视频效率加速

c++如何实现一个简单的ECS(实体组件系统)_c++游戏架构ECS设计与实现思路

梦宇君_9159

梦宇君_9159

发布时间:2025-11-15 15:29:02

|

534人浏览过

|

来源于php中文网

原创

答案:文章介绍了C++中一个轻量级ECS架构的实现,核心包括实体(Entity)作为唯一ID、组件(Component)存储数据、系统(System)处理逻辑。通过EntityManager管理组件的增删查,系统如MovementSystem遍历具备特定组件的实体执行行为。示例展示了位置与速度组件的更新过程,最后指出可优化方向如Archetype模式、更安全的实体ID管理及多线程支持,整体体现数据与逻辑分离、组合优于继承的设计思想。

c++如何实现一个简单的ecs(实体组件系统)_c++游戏架构ecs设计与实现思路

在C++中实现一个简单的ECS(Entity-Component-System)架构,核心目标是将数据(组件)与行为(系统)分离,通过实体作为标识符来组织它们。这种设计有利于性能优化(如内存连续访问)、代码解耦和扩展性。下面是一个轻量级、易于理解的ECS实现思路。

1. 核心概念拆解

ECS由三部分组成:

  • Entity(实体):只是一个唯一ID,代表游戏中的一个“东西”,不包含任何逻辑或数据。
  • Component(组件):纯数据结构,描述实体的某方面状态,比如位置、速度、血量等。
  • System(系统):处理具有特定组件组合的实体,执行逻辑,如移动、渲染、碰撞检测。

关键设计原则是:组件只存数据,系统负责操作,实体仅作索引。

2. 实现基础结构

从最简版本开始,定义基本类型:

立即学习“C++免费学习笔记(深入)”;

C++ Code Review Master
C++ Code Review Master

组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。

下载
#include <vector>
#include <unordered_map>
#include <typeindex>
#include <memory>

// 实体用无符号整数表示
using Entity = uint32_t;

// 组件存储池基类(用于多态)
struct ComponentPool {
    virtual ~ComponentPool() = default;
};

// 模板化组件池,按类型存储组件数据
template<typename T>
struct ComponentPoolImpl : ComponentPool {
    std::vector<T> data;           // 存储实际组件
    std::vector<bool> alive;       // 标记是否有效
    std::unordered_map<Entity, size_t> entityToIndex; // 映射实体到索引

    void grow(Entity entity) {
        if (entity >= data.size()) {
            size_t newSize = static_cast<size_t>(entity * 1.5) + 10;
            data.resize(newSize);
            alive.resize(newSize, false);
        }
    }

    T& add(Entity entity, const T& component) {
        grow(entity);
        data[entity] = component;
        alive[entity] = true;
        entityToIndex[entity] = entity; // 简化模型:直接使用entity为索引
        return data[entity];
    }

    T* get(Entity entity) {
        if (entity < alive.size() && alive[entity]) {
            return &data[entity];
        }
        return nullptr;
    }

    void remove(Entity entity) {
        if (entity < alive.size()) {
            alive[entity] = false;
            entityToIndex.erase(entity);
        }
    }
};

3. 实现EntityManager与Component管理

管理实体的创建、销毁以及组件的增删:

class EntityManager {
public:
    std::unordered_map<std::type_index, std::shared_ptr<ComponentPool>> pools;

    template<typename T>
    void registerComponent() {
        pools[typeid(T)] = std::make_shared<ComponentPoolImpl<T>>();
    }

    template<typename T>
    T& addComponent(Entity entity, const T& component) {
        auto pool = std::static_pointer_cast<ComponentPoolImpl<T>>(pools[typeid(T)]);
        return pool->add(entity, component);
    }

    template<typename T>
    T* getComponent(Entity entity) {
        auto it = pools.find(typeid(T));
        if (it != pools.end()) {
            auto pool = std::static_pointer_cast<ComponentPoolImpl<T>>(it->second);
            return pool->get(entity);
        }
        return nullptr;
    }

    template<typename T>
    void removeComponent(Entity entity) {
        auto pool = std::static_pointer_cast<ComponentPoolImpl<T>>(pools[typeid(T)]);
        pool->remove(entity);
    }
};

4. 定义并运行System

系统遍历具有指定组件的实体并执行逻辑。例如,一个移动系统:

struct Position {
    float x, y;
};

struct Velocity {
    float dx, dy;
};

class MovementSystem {
public:
    void update(EntityManager& em, float dt) {
        for (auto& [type, pool] : em.pools) {
            auto posPool = std::dynamic_pointer_cast<ComponentPoolImpl<Position>>(pool);
            if (!posPool) continue;

            for (size_t i = 0; i < posPool->alive.size(); ++i) {
                if (!posPool->alive[i]) continue;

                Entity entity = static_cast<Entity>(i);
                Position* pos = em.getComponent<Position>(entity);
                Velocity* vel = em.getComponent<Velocity>(entity);

                if (pos && vel) {
                    pos->x += vel->dx * dt;
                    pos->y += vel->dy * dt;
                }
            }
        }
    }
};

使用示例:

int main() {
    EntityManager em;
    MovementSystem moveSys;

    em.registerComponent<Position>();
    em.registerComponent<Velocity>();

    Entity e1 = 1;
    em.addComponent(e1, Position{0.f, 0.f});
    em.addComponent(e1, Velocity{1.f, 0.5f});

    for (int i = 0; i < 10; ++i) {
        moveSys.update(em, 0.1f);
        auto pos = em.getComponent<Position>(e1);
        printf("Pos: %.2f, %.2f\n", pos->x, pos->y);
    }

    return 0;
}

5. 可改进方向

当前实现较简单,可用于学习。生产环境中可考虑以下优化:

  • Archetype模式:按组件组合分组存储实体(类似Unity DOTS),提升缓存友好性。
  • Sparse Set或Generational Index:更安全高效的实体ID管理。
  • 事件机制:组件添加/移除时通知系统。
  • 多线程支持:系统间并行执行,注意数据竞争。
  • 反射或注册宏:简化组件声明与序列化。

基本上就这些。这个简易ECS展示了如何用最少代码体现ECS思想:数据与逻辑分离、基于组合而非继承、高效遍历。适合小型项目或学习架构设计。

相关文章

在线游戏
在线游戏

海量精品小游戏合集,无需安装即点即玩,休闲益智、动作闯关应有尽有,秒开即玩,轻松解压,快乐停不下来

下载

相关标签:

c++

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
超级简历WonderCV

一款AI办公效率工具,主要用于免费求职简历模版下载制作,应届生职场人必备简历制作神器,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

讯飞智作

讯飞智作是一款AI视频创作工具,AI文本配音工具,数字人课程、营销视频制作。

相关专题

更多
mysql标识符无效错误怎么解决
mysql标识符无效错误怎么解决

mysql标识符无效错误的解决办法:1、检查标识符是否被其他表或数据库使用;2、检查标识符是否包含特殊字符;3、使用引号包裹标识符;4、使用反引号包裹标识符;5、检查MySQL的配置文件等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

12900

2023.12.04

Python标识符有哪些
Python标识符有哪些

Python标识符有变量标识符、函数标识符、类标识符、模块标识符、下划线开头的标识符、双下划线开头、双下划线结尾的标识符、整型标识符、浮点型标识符等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

1023

2024.02.23

java标识符合集
java标识符合集

本专题整合了java标识符相关内容,想了解更多详细内容,请阅读下面的文章。

7490

2025.06.11

c++标识符介绍
c++标识符介绍

本专题整合了c++标识符相关内容,阅读专题下面的文章了解更多详细内容。

2962

2025.08.07

treenode的用法
treenode的用法

​在计算机编程领域,TreeNode是一种常见的数据结构,通常用于构建树形结构。在不同的编程语言中,TreeNode可能有不同的实现方式和用法,通常用于表示树的节点信息。更多关于treenode相关问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2361

2023.12.01

C++ 高效算法与数据结构
C++ 高效算法与数据结构

本专题讲解 C++ 中常用算法与数据结构的实现与优化,涵盖排序算法(快速排序、归并排序)、查找算法、图算法、动态规划、贪心算法等,并结合实际案例分析如何选择最优算法来提高程序效率。通过深入理解数据结构(链表、树、堆、哈希表等),帮助开发者提升 在复杂应用中的算法设计与性能优化能力。

336

2025.12.22

深入理解算法:高效算法与数据结构专题
深入理解算法:高效算法与数据结构专题

本专题专注于算法与数据结构的核心概念,适合想深入理解并提升编程能力的开发者。专题内容包括常见数据结构的实现与应用,如数组、链表、栈、队列、哈希表、树、图等;以及高效的排序算法、搜索算法、动态规划等经典算法。通过详细的讲解与复杂度分析,帮助开发者不仅能熟练运用这些基础知识,还能在实际编程中优化性能,提高代码的执行效率。本专题适合准备面试的开发者,也适合希望提高算法思维的编程爱好者。

377

2026.01.06

C++ 数据结构与算法实现教程合集
C++ 数据结构与算法实现教程合集

以 C++ 为实现语言,系统讲解核心数据结构与算法,涵盖链表(单链表/双链表/环检测)、栈与队列(单调栈/优先队列)、二叉树(遍历/BST/AVL/红黑树)、哈希表(开地址法/链地址法)、图(邻接表/BFS/DFS/Dijkstra/拓扑排序)、常见排序算法(快排/归并/堆排/计数排序)的实现与复杂度分析,同时分享 LeetCode 刷题技巧、竞赛编程常用模板(二分/前缀和/滑动窗口/动态规划),帮助开发者夯实算法基础。

432

2026.05.09

FrankenPHP集成Laravel详细教程
FrankenPHP集成Laravel详细教程

本专题提供FrankenPHP集成Laravel的详细配置指南,全面解析运行原理、开发环境搭建、Caddyfile配置、Octane工作模式、数据库连接、队列任务、定时任务和生产环境优化,解决部署过程中常见的报错与兼容性问题。

0

2026.10.08

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn