Javascript 在CoffeeScript游戏引擎中使用mixin

Javascript 在CoffeeScript游戏引擎中使用mixin,javascript,coffeescript,mixins,Javascript,Coffeescript,Mixins,我正在为Html5画布开发一个CoffeeScript游戏引擎。在我检查了一份非常整洁的咖啡脚本后,我想出了一个“酷”的想法来利用混合饮料。我认为,通过开发一组基于mixin的组件,减少游戏对象通常提供的各种对象层次,这可能是一个非常酷的想法,每个组件都有非常特定的功能。然后,当开发一个实际的游戏时,可以通过基本上从一个组件开始并将其与一系列其他组件混合来动态构建独特的游戏对象。这减少了层次结构并允许频繁更改 然后我考虑了可能出现的冲突,例如让几个组件定义具有相同签名的方法。现在,我不像以前那么

我正在为Html5画布开发一个CoffeeScript游戏引擎。在我检查了一份非常整洁的咖啡脚本后,我想出了一个“酷”的想法来利用混合饮料。我认为,通过开发一组基于mixin的组件,减少游戏对象通常提供的各种对象层次,这可能是一个非常酷的想法,每个组件都有非常特定的功能。然后,当开发一个实际的游戏时,可以通过基本上从一个组件开始并将其与一系列其他组件混合来动态构建独特的游戏对象。这减少了层次结构并允许频繁更改

然后我考虑了可能出现的冲突,例如让几个组件定义具有相同签名的方法。现在,我不像以前那么兴奋了

我该怎么办?这是个好办法吗?我仍然喜欢它,特别是因为JS的底层原型机制,它允许如此简单的方式在运行中组合内容。

您所说的是一个。有几个是用JS写的;最受欢迎的是,它很大,但值得一看。我最近在CoffeeScript中写了一篇(只是为了好玩;可能永远不会发布)

关于碰撞的一些注意事项:

所以首先,问题可能比你想象的更糟:如果两个方法同名,就会发生冲突;JS不区分函数签名。它也可能没那么糟糕:为什么不创建一个名称空间约定,其中每个行为(意思是方法)都以它所属的组件命名,比如
burnable\u burn

但退一步说,mixin并不是构建这种行为的唯一方法——行为(即组件可以做的事情)根本不必是方法。我问的激励性问题是,你如何触发一种行为?例如,您可以执行以下操作:

if entity.hasComponent "burnable" #hasComponent provided by your framework
  entity.burn()
但这对我来说并不正确;它在游戏中发生的事情和您拥有的组件之间产生了一种奇怪的耦合,并且检查您的实体是否实现了相关组件很难。相反,我希望行为成为事件的倾听者:

然后让您的组件执行它需要执行的任何操作。因此,当您向实体添加组件时,它会向事件注册侦听器。也许它看起来像(只是草图):

为了让大家明白这一点,如果你这样做了,你就不在乎碰撞,因为你的行为没有名字。事实上,你想要“碰撞”;您希望能够让多个组件响应同一事件。也许它同时燃烧和融化


实际上,我同时使用了这两种设置。我在组件的函数中混合了
entity.addComponent
,因为偶尔将行为作为方法调用会很方便。但大多数情况下,组件声明调用这些方法的侦听器,这有助于解耦,减少了使用作用域名称的尴尬,因为在大多数情况下我不会直接调用它们。

NP:)记住,如果它回答了您的问题,请勾选该框。是的,我给您评分,因为您的答案非常全面,我很感激。不过,就目前而言,我认为我将坚持使用像getComponent(“”)这样的狡猾模型。感谢您向我推荐这个漂亮的框架。在Crafty上找到很酷的find,似乎是一个很好的快速引导工具集。在我寻找避免奇怪javascript对象编程语法的方法时,您让我发现了
实体组件范例。我不仅解决了简化语言的问题,还发现了编写游戏的另一个视角。谢谢你:)
entity.send("applySeriousHeat") #triggers whatever behaviors are there
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