Вы говорите о компонентной системе .Есть пара написана на JS;самый популярный - Crafty , который большой, но стоит посмотреть.Недавно я написал один на CoffeeScript (просто для забавы; вероятно, никогда не выпустит его).
Несколько замечаний о столкновениях:
Итак, во-первых, проблема может быть хуже, чем вы думаете: столкновения будутпроизойдет, если два метода имеют одинаковое имя ;JS не различает сигнатуры функций.Это также может быть не так уж плохо: почему бы вам просто не создать соглашение о пространстве имен, где каждое поведение (смысловой метод) названо в честь компонента, к которому он принадлежит, например, burnable_burn
?
Чтобы сделать шагХотя миксины - не единственный способ построить это - поведение (то есть то, что может сделать компонент) вовсе не обязательно должно быть методом.Мотивирующий вопрос, который я задаю: как вы запускаете поведение?Например, вы могли бы сделать:
if entity.hasComponent "burnable" #hasComponent provided by your framework
entity.burn()
Но мне это не кажется правильным;он создает странную связь между тем, что происходит в вашей игре, и тем, какие компоненты у вас есть, и неудобно проверять, реализуют ли ваши сущности соответствующий компонент.Вместо этого я хотел бы, чтобы поведение было слушателями на событиях :
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
Чтобы довести эту мысль до дома, если вы делаете это, вас не волнуют коллизии, потому что у вашего поведения нет имен.На самом деле, вы хотите "столкновения";вы хотите иметь возможность иметь более одного компонента, отвечающего на одно и то же событие.Может быть, он горит и тает одновременно?
На практике я использовал обе установки вместе.Я сделал entity.addComponent
микс в функциях компонента, так как иногда удобно просто вызывать поведение как метод.Но в основном компоненты объявляют прослушиватели, которые вызывают эти методы, что помогло отделить и уменьшило неловкость использования имен с областями, поскольку в большинстве случаев я не вызываю их напрямую.