【发布时间】:2017-07-27 01:18:45
【问题描述】:
我一直致力于用 C++ 创建游戏。 World 类包含所有游戏状态相关的对象和主游戏循环函数。
class World {
Clock clock;
Map map;
std::vector<Entity*> entities;
...
我游戏中的所有实体都继承自抽象类Entity。例如:
class Player: public Entity {...};
class Enemy: public Entity {...};
class Bullet: public Entity {...};
通过遍历所有实体的列表并对每个实体调用update() 方法,每帧都会更新实体。
为了考虑不同的帧速率,我将每个帧中的经过时间作为float delta 传递给更新方法(与大多数其他游戏引擎一样)。我遇到的问题是一个实体可能需要在update() 中引用的所有不同的东西。
Entity类定义虚拟更新方法如下:
virtual void update(float delta) = 0;
从游戏循环中调用此函数如下所示:
for(int i = 0; i < entities.size(); i++) {
entities[i]->update(clock.get_delta());
}
这很好用。但是现在,假设我们想要添加一个功能,Player 可以在不同的表面上更快地移动。要知道玩家在什么表面上,需要访问属于 World 类的 Map 对象。
我们可以将它添加到虚拟更新方法中:
virtual void update(float delta, Map *map) = 0;
但是现在Enemy 和Bullet 的更新函数必须采用新的地图参数,即使它们不使用它。
实体在其更新方法中需要的任何其他对象或变量也是如此。不久之后,方法定义中就会出现几十个参数(游戏地图、其他实体列表、游戏状态信息)。
我的问题是:如何防止这种情况发生?我尝试将World 的引用作为唯一参数传递,但它导致了循环依赖。
【问题讨论】:
-
这是一个有趣的问题,但它有点宽泛,并且有很多潜在的解决方案。在gamedev.stackexchange.com 上你可能会有更好的运气。那里有很多游戏引擎架构讨论,例如this question。
-
循环依赖可以用forward class declaration管理
标签: c++ inheritance design-patterns game-engine