我正在开发一个用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个或更多组件(并修改/交叉修改它们的子组件-将我们带回到面向对象编程)的“元组件”。 或者也许我完全想错了。 我吗?
private double x;
和private double y;
)- 我在控制器内部完成所有这些链接。 - David Titarenco