• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

c++ - 在游戏中组织实体的最佳方式?

[复制链接]
菜鸟教程小白 发表于 2022-8-3 00:17:53 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题

假设我正在用 C++ 创建一个 OpenGL 游戏,它将创建许多对象(敌人、玩家角色、元素等)。我想知道组织这些的最佳方法,因为它们将根据时间、玩家位置/ Action 等实时创建和销毁。

这是我到目前为止想到的:
我可以有一个全局数组来存储指向这些对象的指针。这些对象的纹理/上下文加载在它们的构造函数中。这些对象将具有不同的类型,因此我可以转换指针以将它们放入数组中,但我希望稍后有一个 renderObjects() 函数,该函数将使用循环为每个现有对象调用 ObjectN.render() 函数。

我想我以前试过这个,但我不知道用什么类型来初始化数组,所以我选择了一个任意的对象类型,然后转换任何不是那种类型的东西。如果我记得,这不起作用,因为编译器不希望我取消引用指针,如果它不再知道它们的类型,即使给定的成员函数具有相同的名称: (*Object5).render() <-doesn不行吗?

有没有更好的办法?像HL2这样的商业游戏如何处理?我想一定有一些模块等可以跟踪所有对象。



Best Answer-推荐答案


对于我即将成为的个人游戏项目,我使用了基于组件的实体系统。

您可以通过搜索“基于组件的游戏开发”了解更多相关信息。一篇著名的文章是Evolve Your Hierarchy来自牛仔编程博客。

在我的系统中,实体只是 ids - unsigned long,有点像在关系数据库中。
与我的实体关联的所有数据和逻辑都写入到组件中。我有将实体 ID 与其各自组件链接的系统。类似的东西:

typedef unsigned long EntityId;

class Component {
    Component(EntityId id) : owner(id) {}
    EntityId owner;
};

template <typename C> class System {
    std::map<EntityId, C * > components;
};

然后对于每种功能,我编写了一个特殊的组件。所有实体都没有相同的组件。
例如,您可以拥有一个包含 WorldPositionComponent 和 ShapeComponent 的静态岩石对象,以及一个具有相同组件和 VelocityComponent 的移动敌人。
下面是一个例子:
class WorldPositionComponent : public Component {
    float x, y, z;
    WorldPositionComponent(EntityId id) : Component(id) {}
};

class RenderComponent : public Component {
    WorldPositionComponent * position;
    3DModel * model;
    RenderComponent(EntityId id, System<WorldPositionComponent> & wpSys)
        : Component(id), position(wpSys.components[owner]) {}
    void render() {
        model->draw(position);
    }
};

class Game {
    System<WorldPositionComponent> wpSys;
    System<RenderComponent> rSys;
    void init() {
        EntityId visibleObject = 1;
        // Watch out for memory leaks.
        wpSys.components[visibleObject] = new WorldPositionComponent(visibleObject);
        rSys.components[visibleObject] = new RenderComponent(visibleObject, wpSys);
        EntityId invisibleObject = 2;
        wpSys.components[invisibleObject] = new WorldPositionComponent(invisibleObject);
        // No RenderComponent for invisibleObject.
    }
    void gameLoop() {
        std::map<EntityId, RenderComponent *>::iterator it;
        for (it = rSys.components.iterator(); it != rSys.components.end(); ++it) {
            (*it).second->render();
        }
    }
};

这里有 2 个组件,WorldPosition 和 Render。 Game 类包含 2 个系统。 Render 组件可以访问对象的位置。如果实体没有 WorldPosition 组件,您可以选择默认值,或忽略该实体。
Game::gameLoop() 方法只会渲染可见对象。对于不可渲染的组件没有处理浪费。

您还可以将我的 Game 类拆分为两个或三个,以将显示和输入系统与逻辑分开。诸如模型、 View 和 Controller 之类的东西。

我发现根据组件定义我的游戏逻辑很巧妙,并且拥有只具有它们需要的功能的实体——不再有空的 render() 或无用的碰撞检测检查。

关于c++ - 在游戏中组织实体的最佳方式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/764824/

回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注0

粉丝2

帖子830918

发布主题
阅读排行 更多
广告位

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap