传统的继承如果在初期设计不好,后期要修改添加功能会带来很多不便,而基于组件式的开发可以解决这些问题
基本上就是比如:我们有一个组件的接口
class IComponent
{
public:
virtual const CObjectId& GetComponentId() const = 0; //自身的ID
virtual const CObjectId& GetFamilyId() const = 0; //父组件的ID
}
然后我们定义了很多实现IComponent的组件(对!就是我们要用到的组件),比如:
class IRenderable :public IComponent
{
public:
virtual void Render() const = 0;
}
class IMoveable : public IComponent
{
public:
virtual void Move() = 0;
}
然后有一个由多个组件集成的类
class GameObject
{
public:
const IComponent* GetComponent(const CObjectId& id) const;
void AddComponent(IComponent* component);
private:
map<const CObjectId&, IComponent*> components;
}
然后我们就可以通过组件的方式来定义一个既可以Render又可以Move的精灵
class Sprite : public GameObject
{
GameObject()
{
AddComponent(IRenderable);
AddComponent(IMoveable);
}
}
void main()
{
Sprite sprite;
IMoveable* moveable = static_cast<IMoveable*>(sprite.GetComponent("moveable"));
if(moveable != NULL)
moveable->Move();
IRenderable* renderable = static_cast<IRenderable*>(sprite.GetComponent("renderable"));
if(renderable != NULL)
renderable->Render();
}
更加强大的是我们还可以通过XML来配置类,然后通过一个管理器来管理,
那以后我们就可以不用再写类了,直接通过XML就可以动态配置了
class GameObjectManager
{
public:
GameObject* CreateObject(const CObjectId& id);
}
<Objects>
<Object id="sprite">
<Component id="renderable"/>
<Component id="moveable" x="10" y="100"/>
</Object>
</Objects>
void main()
{
Sprite* sprite = static_cast<Sprite*>(GameObjectManager::GetSingleton().CreateObject("sprite"));
if(sprite == null)
return;
IMoveable* moveable = static_cast<IMoveable*>(sprite->GetComponent("moveable"));
if(moveable != NULL)
moveable->Move();
IRenderable* renderable = static_cast<IRenderable*>(sprite->GetComponent("renderable"));
if(renderable != NULL)
renderable->Render();
}
组件之间通信呢, 只要在组件间保存一个GameObject的指针就可以了。
不过我觉得有点不好的就是:访问所有的组件都要查表来完成,会影响一点速度。这些都只是理论,不知道那个
项目已经有比较好的实践,忘大家通知一下,谢谢!