Pre*_*hev 3 javascript mixins coffeescript
我正在为Html5画布开发CoffeeScript游戏引擎.在我检查了一个非常简洁的CoffeeScript 实现后,我提出了使用mixins的"酷"想法.我想,通过开发一组基于mixin的组件来减少游戏对象通常提供的各种对象层次结构可能是一个非常酷的想法,每个组件都具有非常特定的功能.然后,在开发实际游戏时,可以通过基本上从一个组件开始并将其与一堆其他组件混合来动态构建独特的游戏对象.这减少了层次结构并允许频繁更改.
然后我想到了可能出现的可能冲突,例如,有一些组件定义了具有相同签名的方法.现在,我没有像以前那样兴奋.
我该怎么办?这是一个好方法吗?我仍然喜欢它,特别是因为JS的基础原型机制,它允许这种简单的方法来动态组合东西.
小智 10
你在谈论一个实体组件系统.有一对用JS编写; 最受欢迎的是Crafty,它很大但值得一看.我最近在CoffeeScript中写了一个(仅用于测试;可能永远不会释放它).
关于碰撞的一些注意事项:
首先,问题可能比你想象的还要糟糕:如果两个方法具有相同的名称,就会发生冲突; JS没有区分功能签名.它也可能不是那么糟糕:你为什么不创建一个命名空间约定,其中每个行为(含义方法)都以它所属的组件命名,比如burnable_burn?
为了退一步,mixins不是构建它的唯一方法 - 行为(即组件可以做的事情)根本不必是方法.我问的激励性问题是,你如何触发行为?例如,您可能会这样做:
if entity.hasComponent "burnable" #hasComponent provided by your framework
entity.burn()
Run Code Online (Sandbox Code Playgroud)
但这对我来说听起来不对; 它会在您的游戏中发生的事情与您拥有的组件之间产生奇怪的联系,并且检查您的实体是否实现相关组件是很尴尬的.相反,我想行为是听众对事件:
entity.send("applySeriousHeat") #triggers whatever behaviors are there
Run Code Online (Sandbox Code Playgroud)
然后让你的组件做它需要做的任何事情.因此,当您向实体添加组件时,它会将侦听器注册到事件.也许它看起来像(只是草绘):
register: (entity) -> #called when you add a component to an entity
entity.listen "applySeriousHeat", -> #thing I do when this event is sent to me
#do burnination here
Run Code Online (Sandbox Code Playgroud)
要把这一点带回家,如果你这样做,你就不关心碰撞,因为你的行为没有名字.事实上,你想要"碰撞"; 您希望能够让多个组件响应同一事件.也许它同时燃烧和融化?
在实践中,我一起使用了两种设置.我entity.addComponent在组件的函数中进行了混合,因为将行为作为方法调用偶尔会很方便.但大多数情况下,组件声明调用这些方法的侦听器,这有助于解耦并减少必须使用范围名称的尴尬,因为在大多数情况下我不直接调用它们.