我正在开发一个游戏环境,它将包含许多不同的实体.每个都有一些常见的功能(绘制,更新等),但有时游戏必须根据敌人的类型区别对待它们.到目前为止,我已经在他们的实例课程中编码了敌人的“类型”.所以,我们有这样的情况:
class MotionObject { ... };
class Entity : public MotionObject { ... };
class Coin : public Entity { ... };
class TextSign : public Entity { ... };
class ShapeEnemy : public Entity { ... };
class Attractor : public ShapeEnemy { ... };
class Bumper : public ShapeEnemy { ... };
因此,类Coin,TextSign,Attractor和Bumper是游戏中实例化的实体类型.为不同类型的实体设置不同的类感觉是正确的,但是如果我只有一个实体类,其中包含一个基于其“实体类型”控制其行为的switch语句,我无法摆脱一些麻烦可能会被避免的感觉,存储在变量中的东西.玩家根据他们的类型以不同的方式与这些实体交互,每次我都使用dynamic_cast和null测试来确定应用了哪种行为.要清楚,这些是针对我无法在每个实体上调用简单Update()的行为;播放器将以特定方式响应,或者它们将是实体间交互,所有这些都基于实体类型.我的代码看起来像这样:
void Game::Update(float deltaT) {
for (int i =0; i < DrawChildren.size(); i++) {
//each entity has its Update called
DrawChildren[i].Update(deltaT);
//What follows is code that the Game class needs to run based on the entity type.
Coin * coin = dynamic_cast<Coin*>(DrawChildren[i]);
if (coin != nullptr) {
...
continue; //so no other type's code executes, in case I have inherited types.
}
TextSign * textSign = dynamic_cast<TextSign*>(DrawChildren[i]);
if (textSign != nullptr) {
...
continue; //so no other type's code executes, in case I have inherited types.
}
Attractor * attractor = dynamic_cast<Attractor*>(DrawChildren[i]);
if (attractor != nullptr) {
...
continue; //so no other type's code executes, in case I have inherited types.
}
Bumper * bumper = dynamic_cast<Bumper*>(DrawChildren[i]);
if (bumper != nullptr) {
...
continue; //so no other type's code executes, in case I have inherited types.
}
}
...
}
有一种不那么繁琐的方法吗?
最佳答案 另一种方法是使用“浅”类层次结构和独立的“行为”抽象类,您可以使用它们来装饰主层次结构.
所以你可以:
Entity
-> Character -> NPC ->….
-> Object -> Container -> ….
Renderable
活动
Killable
可装备…
您将使用多重继承来装饰类.
具有单一层次结构会强制您在不同“子树”之间共享时将功能向上移动到树中,这意味着您可以向可能不使用它们的类添加功能,从而使整个设计复杂化;否则,你最终不得不重复代码(DRY原则?).在这两种情况下,维护和扩展都变得更加困难.