На це складне питання відповісти, оскільки кожен має власне уявлення про те, як повинна бути структурована система компонентів сутності. Найкраще, що я можу зробити, - поділитися з вами деякими речами, які я вважаю найбільш корисними для мене.
Суб'єкт
Я сприймаю жировий клас до ECS, ймовірно, тому, що вважаю екстремальні методи програмування дуже неефективними (з точки зору продуктивності людини). З цією метою сутність для мене - це абстрактний клас, який успадковується більш спеціалізованими класами. Суб'єкт має ряд віртуальних властивостей та простий прапор, який підказує мені, чи має існувати ця сутність. Отже, стосовно вашого запитання щодо системи візуалізації, це Entity
виглядає так:
public abstract class Entity {
public bool IsAlive = true;
public virtual SpatialComponent Spatial { get; set; }
public virtual ImageComponent Image { get; set; }
public virtual AnimationComponent Animation { get; set; }
public virtual InputComponent Input { get; set; }
}
Компоненти
Компоненти "дурні" в тому, що нічого не роблять і не знають . Вони не мають посилань на інші компоненти, і вони, як правило, не мають функцій (я працюю в C #, тому я використовую властивості для обробки геттерів / сеттерів - якщо вони мають функції, вони базуються на пошуку даних, які вони містять).
Системи
Системи менш "дурні", але все ще тупі автомати. Вони не мають контексту загальної системи, не мають посилань на інші системи і не містять даних, крім кількох буферів, які можуть знадобитися для їх індивідуальної обробки. Залежно від системи, вона може мати спеціалізований Update
, або Draw
метод, або в деяких випадках і те, і інше.
Інтерфейси
Інтерфейси - це ключова структура в моїй системі. Вони використовуються для визначення того, що System
може обробляти, а на що Entity
здатний. Інтерфейсами, які мають значення для візуалізації, є: IRenderable
і IAnimatable
.
Інтерфейси просто повідомляють системі, які компоненти доступні. Наприклад, система візуалізації повинна знати поле обмеження сутності та зображення для малювання. У моєму випадку це було б SpatialComponent
і те ImageComponent
. Так це виглядає приблизно так:
public interface IRenderable {
SpatialComponent Component { get; }
ImageComponent Image { get; }
}
Система візуалізації
Тож як система візуалізації малює сутність? Насправді це дуже просто, тож я просто покажу тобі збитий клас, щоб дати тобі уявлення:
public class RenderSystem {
private SpriteBatch batch;
public RenderSystem(SpriteBatch batch) {
this.batch = batch;
}
public void Draw(List<IRenderable> list) {
foreach(IRenderable obj in list) {
this.batch.draw(
obj.Image.Texture,
obj.Spatial.Position,
obj.Image.Source,
Color.White);
}
}
}
Дивлячись на клас, система візуалізації навіть не знає, що Entity
таке. Все, про що вона знає, - IRenderable
це просто список їх, щоб скласти.
Як це все працює
Це може допомогти зрозуміти, як я створюю нові ігрові об’єкти та як я їх подаю до систем.
Створення утворень
Усі ігрові об’єкти успадковуються від Entity, а також будь-які застосовні інтерфейси, які описують, що може зробити цей ігровий об’єкт. Приблизно все, що анімоване на екрані, виглядає приблизно так:
public class MyAnimatedWidget : Entity, IRenderable, IAnimatable {}
Годування систем
Я зберігаю перелік усіх сутностей, що існують у ігровому світі, в єдиному списку під назвою List<Entity> gameObjects
. Кожен кадр я просіюю цей список і копіюю посилання на об'єкти до додаткових списків на основі типу інтерфейсу, наприклад List<IRenderable> renderableObjects
, та List<IAnimatable> animatableObjects
. Таким чином, якщо різним системам потрібно обробляти одну і ту ж сутність, вони можуть. Тоді я просто передаю ці списки кожній із систем Update
або Draw
методів і дозволю системам робити свою роботу.
Анімація
Вам може бути цікаво, як працює система анімації. У моєму випадку ви можете побачити інтерфейс IAnimatable:
public interface IAnimatable {
public AnimationComponent Animation { get; }
public ImageComponent Image { get; set; }
}
Головне, що тут слід помітити, - це ImageComponent
аспект IAnimatable
інтерфейсу не лише для читання; в ньому є сетер .
Як ви могли здогадатися, компонент анімації просто містить дані про анімацію; перелік кадрів (які є компонентами зображення), поточний кадр, кількість кадрів в секунду, яку потрібно намалювати, минулий час з моменту останнього збільшення кадру та інші параметри.
Анімаційна система використовує перевагу системи візуалізації та взаємозв'язку компонентів зображення. Він просто змінює компонент зображення об'єкта, збільшуючи рамки анімації. Таким чином, анімація виводиться опосередковано системою візуалізації.