作为一个小练习,我正在尝试编写一个非常小的、简单的游戏引擎,它只处理实体(移动、基本 AI 等)
因此,我正在尝试考虑游戏如何处理所有实体的更新,并且我有点困惑(可能是因为我以错误的方式进行操作)
所以我决定在这里发布这个问题,向您展示我目前的思考方式,并看看是否有人可以向我建议更好的方法。
目前,我有一个 CEngine 类,它指向它需要的其他类(例如 CWindow 类、CEntityManager 类等)
我有一个游戏循环,在伪代码中会像这样(在 CEngine 类中)
while(isRunning) {
Window->clear_screen();
EntityManager->draw();
Window->flip_screen();
// Cap FPS
}
我的 CEntityManager 类看起来像这样:
enum {
PLAYER,
ENEMY,
ALLY
};
class CEntityManager {
public:
void create_entity(int entityType); // PLAYER, ENEMY, ALLY etc.
void delete_entity(int entityID);
private:
std::vector<CEntity*> entityVector;
std::vector<CEntity*> entityVectorIter;
};
我的 CEntity 类看起来像这样:
class CEntity() {
public:
virtual void draw() = 0;
void set_id(int nextEntityID);
int get_id();
int get_type();
private:
static nextEntityID;
int entityID;
int entityType;
};
之后,我会为敌人创建类,并给它一个精灵表,它自己的功能等。
例如:
class CEnemy : public CEntity {
public:
void draw(); // Implement draw();
void do_ai_stuff();
};
class CPlayer : public CEntity {
public:
void draw(); // Implement draw();
void handle_input();
};
所有这些都适用于将精灵绘制到屏幕上。
但后来我遇到了使用存在于一个实体中但不存在于另一个实体中的函数的问题。
在上面的伪代码示例中,do_ai_stuff(); 和句柄输入();
从我的游戏循环中可以看出,有一个对 EntityManager->draw(); 的调用。这只是遍历 entityVector 并调用 draw(); 每个实体的功能 - 看到所有实体都有一个draw(),效果很好;功能。
但后来我想,如果它是一个需要处理输入的玩家实体怎么办?这是如何运作的?
我没有尝试过,但我认为我不能像使用 draw() 函数那样循环遍历,因为像敌人这样的实体不会有 handle_input() 函数。
我可以使用 if 语句来检查 entityType,如下所示:
for(entityVectorIter = entityVector.begin(); entityVectorIter != entityVector.end(); entityVectorIter++) {
if((*entityVectorIter)->get_type() == PLAYER) {
(*entityVectorIter)->handle_input();
}
}
但我不知道人们通常如何写这些东西,所以我不确定最好的方法。
我在这里写了很多,我没有问任何具体的问题,所以我将澄清我在这里寻找什么:
- 我布置/设计代码的方式是否可行,是否实用?
- 有没有更好更有效的方法来更新我的实体并调用其他实体可能没有的函数?
- 使用枚举来跟踪实体类型是识别实体的好方法吗?