基于组件的游戏实体和类型检查
Component-based game entities and type checking
我正在编写一个游戏,它将使用一个基于组件的实体系统。我正在实现的前两个组件是EntityRepresentation和EntityState。表示包含动画,状态决定实体对游戏事件的反应(EntityStates的示例:站立、跳跃、攻击、死亡、摔倒)。
EntityRepresnetation根据实体的EntityState决定在屏幕上绘制什么动画。如果实体处于"跳跃"状态,则会播放相应的动画。(请参见EntityRepresentation::changeAnimation()函数。)
以下是我写这堂课的大致方式。。。
class EntityRepresentation
{
public:
void draw(float x, float y, long currentTime, DrawingContext& dc) {
// ...
}
void changeAnimation(const EntityState::Id& stateId) {
currentAnimation = animationMap_[stateId];
}
private:
map<EntityState::Id, const Animation*> animationMap_;
const Animation* currentAnimation_;
};
我真的不喜欢我目前的做法…>:(EntityState::Id部分。当前,EntityRepresentation将其持有的每个动画映射到特定的EntityState::Id。Id对于从EntityState派生的每个类都是唯一的(对于类而不是实例是唯一的)。这些ID基本上是必须在类的构造函数中手工编写的字符串,这意味着它们很容易发生名称冲突—更重要的是,因为我计划让游戏脚本化(Python)。
有人能给我一些建议,告诉我如何缓解我的身份证问题吗。我在同样使用ID的游戏中看到了很多基于组件的系统的实现,但我仍然不喜欢它们。它只是把我揉错了方向。
也许您可以建议进行设计更改,这样EntityRepresentation就不必知道EntityState的类型,同时仍然保留封装。
使用typeid(),这就是它的用途。您可以使用const type_info*
作为密钥类型。
或者,你知道,你可以使用实际继承,比如调用一个虚拟函数来获取当前动画,这会更智能。
假设在编译时不需要与每个EntityState关联的ID,我使用的一个技巧是使用指针作为ID。如果EntityState是singleton,这一点尤其有效,在这种情况下,您可以简单地使用singleton实例的地址作为ID。否则,为每个ID静态分配一小块内存也可以。
class EntityState {
public:
EntityState(void *id) : mId(id) { }
private:
void *mId;
};
class EntityStateJump : public EntityState {
public:
EntityStateJump() : EntityState(getId()) { }
private:
void *getId() {
static void *id = new int;
return id;
}
};
编辑:为避免静态初始化顺序问题而进行的微小更改。
我建议使用状态模式来实现设计
class EntityState
{
public:
EntityState(const Animation* animation);
static const EntityState* getStandingState();
static const EntityState* getJumpingState();
static const EntityState* getAttackingState();
const Animation& getAnimation() const;
protected:
const Animation* pAnymation_;
};
class EntityRepresentation
{
public:
void draw(float x, float y, long currentTime, DrawingContext& dc) {
// ...
const Animation& animation(state_->getAnimation());
}
void changeState(const EntityState* newState) {
state_ = newState;
}
private:
const EntityState* state_;
};
void EventHandler(EntityRepresentation& entity)
{
entity.changeState(EntityState::getJumpingState());
}
- 使用指针重新分析实体
- 在C++游戏中与库存系统作斗争
- 如何使用tinyxml2从XML加载父实体和子实体
- 换位表导致测试失败(但在游戏中运行良好)
- 不能将 "void *" 类型的值分配给类型 "TCHAR" 的实体
- Craps游戏问题,忽略if语句
- 矢量下标超出SFML游戏中的范围
- 我是 c++ 的新手.学习基本知识后,我想做井字游戏.对于印刷板,我在下面写代码,但它显示错误
- 我在贪吃蛇游戏中收到了错误代码 -1073741571
- 需要帮助在 c++ 中将字符串转换为字符 ----错误 "const char *" 类型的值不能用于初始化 "char" 类型的实体
- 我应该在简单的策略游戏中为各个派系使用类吗 - C++
- 游戏体验和升级
- 我的代码运行良好,但在游戏循环中中断
- 如何使用 SFML 在贪吃蛇游戏中定义游戏结束?
- C++ - 创建游戏实体时,我应该使用"sub classes"还是结构?
- 游戏实体更新方法
- 基于实体多态性的事件游戏引擎
- 游戏实体类型分配
- C++,不同的游戏实体应该有不同的职业吗?或者它应该在一个包含所有行为的类中
- 基于组件的游戏实体和类型检查