Вы говорите об entity component system. В JS написано пару; самым популярным является Crafty, который большой, но стоит посмотреть. Недавно я написал один в CoffeeScript (только для funsies, вероятно, никогда не выпустит его).
Несколько замечаний по поводу столкновений:
Так первое, что проблема может быть хуже, чем вы думаете: столкновения произойдет, если два метода имеет одинаковое имя; JS не отличает сигнатуры функций. Это также может быть не так уж плохо: почему бы вам просто не создать соглашение об именах, где каждое поведение (значение метода) названо после того компонента, к которому он принадлежит, например burnable_burn
?
Чтобы сделать шаг назад, mixins - это не единственный способ построить это - поведение (т. Е. Вещи, которые может выполнять компонент) не обязательно должно быть методами. Мотивирующий вопрос, который я задаю, - как вы вызываете поведение? Например, вы можете:
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
в функциях компонента, так как иногда удобно просто вызвать поведение как метод. Но в основном компоненты объявляют слушатели, которые называют эти методы, которые помогли с развязкой и уменьшили неловкость использования имен с областью, поскольку я не называю их непосредственно в большинстве случаев.
Удивительно, спасибо за тщательный ответ! – preslavrachev
NP :) Не забудьте установить флажок, если он ответил на ваш вопрос. –
Да, я даю вам кредиты, потому что ваш ответ был действительно тщательным, и я ценю это. На данный момент я считаю, что я буду придерживаться модели GetComponent (""), подобной Crafty. Спасибо, что предложили эту приятную структуру для меня. – preslavrachev