我有点纠结:假设我正在制作一个简单的 2D 类塞尔达游戏。当两个对象发生碰撞时,每个对象都应该有一个结果动作。然而,当主角与某物发生碰撞时,他的反应完全取决于他所碰撞的物体的类型。如果是怪物,他应该反弹,如果是墙,什么都不应该发生,如果是一个带有缎带的神奇蓝色盒子,他应该治愈,等等(这些只是例子)。
我还应该注意,这两件事都是碰撞的一部分,也就是说,碰撞事件应该同时发生在角色和怪物身上,而不仅仅是其中之一。
你会怎么写这样的代码?我可以想到许多非常不优雅的方法,例如,在全局 WorldObject 类中使用虚函数来识别属性 - 例如,GetObjectType() 函数(返回整数、char*s、将对象标识为 Monster 的任何内容、Box 或 Wall),然后在具有更多属性的类中,比如 Monster,可能会有更多的虚函数,比如 GetSpecies()。
但是,这变得很烦人,并导致碰撞处理程序中的大型级联 switch(或 If)语句
MainCharacter::Handler(Object& obj)
{
switch(obj.GetType())
{
case MONSTER:
switch((*(Monster*)&obj)->GetSpecies())
{
case EVILSCARYDOG:
...
...
}
...
}
}
还有使用文件的选项,文件将包含以下内容:
Object=Monster
Species=EvilScaryDog
Subspecies=Boss
然后代码可以检索属性,而无需虚拟函数将所有内容弄得一团糟。但是,这并不能解决级联 If 问题。
然后可以选择为每种情况提供一个函数,比如 CollideWall()、CollideMonster()、CollideHealingThingy()。这是我个人最不喜欢的(尽管它们都远非讨人喜欢),因为它似乎维护起来最麻烦。
有人可以对这个问题的更优雅的解决方案提供一些见解吗?感谢您的任何帮助!