我有下面的代码,认为简单的射击游戏在C++:建模游戏对象层次结构的最优雅和最有效的方法是什么? (设计困扰)
// world.hpp
//----------
class Enemy;
class Bullet;
class Player;
struct World
{
// has-a collision map
// has-a list of Enemies
// has-a list of Bullets
// has-a pointer to a player
};
// object.hpp
//-----------
#include "world.hpp"
struct Object
{
virtual ~Object();
virtual void Update() =0;
virtual void Render() const =0;
Float xPos, yPos, xVel, yVel, radius; // etc.
};
struct Enemy: public Object
{
virtual ~Enemy();
virtual void Update();
virtual void Render() const;
};
// Bullet and Player are similar (they render and update differently per se,
/// but the behavior exposed to World is similar)
// world.cpp
//----------
#include "object.hpp"
// object.cpp
//-----------
#include "object.hpp"
两个问题:
1,游戏对象知道关于其他游戏对象。
必须有一个知道所有物体的设施。它可能或可能不需要公开所有对象,它必须公开一些,取决于参数(查询者的位置)。这个设施应该是世界。
对象必须知道他们所在的世界,以查询碰撞信息和其他对象。
这引入了一个依赖关系,其中Object和World的实现都必须访问对象的头部,因此World不会直接包含它自己的头部,而不是包含object.hpp(其中包含world.hpp)。这让我感觉不舒服 - 我不觉得world.cpp应该在对object.hpp进行更改后重新编译。世界并不觉得它应该与Object一起工作。这感觉像不好的设计 - 它如何被修复?
2,多态 - 能否也应该用于除代码重用和游戏实体逻辑分组以外的任何事情?
敌人,项目符号和玩家会更新和渲染不同,当然,因此虚拟Update()和Render()功能 - 相同的界面。它们仍然保存在单独的列表中,其原因是它们的交互取决于两个交互对象是哪个列表 - 两个敌人彼此反弹,子弹和敌人相互破坏等。
这是功能这超出了敌人和子弹的实施;这不是我关心的地方。我觉得除了它们相同的界面之外,还有一个因素可以区分敌人,子弹和玩家,这可以并且应该以其他方式表达,允许我为它们创建一个列表 - 因为它们的界面是相同的!
问题是如何判断包含在同一列表中的对象类别。 Typeid或其他形式的类型识别是不可能的 - 但接下来还有什么其他方式可以做到这一点?或者,这种方法没有错?
谢谢你前两段;这让我感觉很有意义,也有助于清除我的头脑。我已经重写了我的问题,以澄清我想用多态性做什么。 – zyndor 2009-09-23 09:37:30
访客模式很棒,谢谢指出。我猜OnHit()方法类似于模式的Visit()方法,而Objects就是他们自己的访问者,对吧? – zyndor 2009-09-24 15:59:18
选择一个答案接受为最好的答案是困难的,因为他们都有很好的积分,但没有一个是全能的。我觉得关于对象 - 世界交互的设计大纲是最有用的一点信息,并且与我的问题最相关。 - – zyndor 2009-10-14 08:00:38