复合模式/实体系统和传统 OOP
我正在开发一个用Java编写的小游戏(但问题是与语言无关的)。由于我想探索各种设计模式,因此我一直关注复合模式/实体系统(我最初在这里和这里读到过),作为典型的深度分层继承的替代方案。
现在,在写了几千行代码之后,我有点困惑。我认为了解模式,我喜欢使用它。我认为它非常酷,像星巴克一样,但它感觉它提供的好处有些短暂,并且(最让我烦恼的)在很大程度上取决于你的粒度。
这是上面第二篇文章中的图片:
我喜欢对象(游戏实体,或任何你想称呼它们的东西)具有最少的组件集的方式,推断的想法是你可以编写看起来像这样的代码:
BaseEntity Alien = new BaseEntity();
BaseEntity Player = new BaseEntity();
Alien.addComponent(new Position(), new Movement(), new Render(), new Script(), new Target());
Player.addComponent(new Position(), new Movement(), new Render(), new Script(), new Physics());
..这将是真的很好...但实际上,代码最终看起来像这样。
BaseEntity Alien = new BaseEntity();
BaseEntity Player = new BaseEntity();
Alien.addComponent(new Position(), new AlienAIMovement(), new RenderAlien(), new ScriptAlien(), new Target());
Player.addComponent(new Position(), new KeyboardInputMovement(), new RenderPlayer(), new ScriptPlayer(), new PhysicsPlayer());
似乎我最终拥有一些由较小组件组成的非常专业的组件。通常,我必须制作一些具有其他组件依赖关系的组件。毕竟,如果你没有位置,你怎么能渲染呢?不仅如此,你最终渲染玩家、外星人和手榴弹的方式也可能有根本的不同。你不能有一个组件来决定所有三个,除非你做一个非常大的组件(在这种情况下......为什么你还要使用复合模式?
举另一个现实生活中的例子。我的游戏中有角色可以装备各种装备。装备一件装备后,一些统计数据会发生变化,以及视觉上显示的内容。以下是我现在的代码:
billy.addControllers(new Movement(), new Position(), new CharacterAnimationRender(), new KeyboardCharacterInput());
billy.get(CharacterAnimationRender.class).setBody(BODY.NORMAL_BODY);
billy.get(CharacterAnimationRender.class).setFace(FACE.BLUSH_FACE);
billy.get(CharacterAnimationRender.class).setHair(HAIR.RED_HAIR);
billy.get(CharacterAnimationRender.class).setDress(DRESS.DRAGON_PLATE_ARMOR);
上述内容仅影响视觉上显示的内容。因此,我显然需要制作另一个处理齿轮统计数据的组件。但是,我为什么要做这样的事情:CharacterAnimationRender.class
billy.addControllers(new CharacterStatistics());
billy.get(CharacterAnimationRender.class).setBody(BODY.NORMAL_BODY);
billy.get(CharacterStatistics.class).setBodyStats(BODY_STATS.NORMAL_BODY);
当我可以制作一个控制器/组件来处理统计数据的分布以及视觉变化时?CharacterGearStuff
底线,我不确定这应该如何帮助生产力,因为除非你想手动处理所有事情,否则你仍然必须创建依赖于2个以上组件的“元组件”(并修改/交叉修改它们的所有子组件 - 把我们带回OOP)。或者也许我完全搞错了。我是吗?