Как правильно организовать классы в игре на JavaScript с точки зрения архитектуры и применения ООП?

Как лучше организовать хранение экземпляров классов врагов в игре в стиле Tower Defence, если уже создан класс игры, башни и волн, и в игре используется метод repeatFunction для обработки игровых событий?
  • 9 июня 2024 г. 8:01
Ответы на вопрос 2
Для организации классов в игре на JavaScript с точки зрения архитектуры и применения ООП, рекомендуется следовать принципам SOLID: разделение ответственности, открытость/закрытость, наследование, полиморфизм и инкапсуляция.

Для начала, необходимо определить базовый класс Enemy, от которого будут наследоваться все классы врагов (например, классы Goblin, Orc, Skeleton и т.д.). В классе Enemy можно определить общие методы и свойства для всех врагов, такие как координаты, здоровье, скорость и методы для перемещения и атаки.

После этого можно создать класс Game, который будет отвечать за общую логику игры, включая создание волн врагов, управление башнями и игровым процессом. В этом классе можно хранить массив или структуру данных для хранения текущих врагов на поле (например, массив enemies), которые будут обновляться и рисоваться на каждом шаге игры.

Для создания и обновления волн врагов в стиле Tower Defence, можно использовать метод repeatFunction, который будет вызываться с определенной периодичностью и создавать новых врагов на поле. Кроме того, можно реализовать методы для обработки столкновений врагов с башнями, уменьшения здоровья врагов при атаке и удаления врагов при их уничтожении.

Таким образом, с использованием правильной архитектуры и принципов ООП, можно эффективно организовать классы в игре на JavaScript и управлять экземплярами врагов в игре в стиле Tower Defence.
<b>Статические методы класса как раз для оперирования с несколькими экземплярами класса?</b> <br/> <br/> Статические поля и методы служат для работы с классом в целом. Примеры: <br/> • Есть десять объектов и новых создавать нельзя. <br/> • Общий для всей проги объектный пул, а второго, скорее всего, не будет. <br/> • Псевдоконструктор — Rect.xyxy(x1,y1,x2,y2) и Rect.xywh(x,y,w,h). <br/> • Функциональность никак не зависит от экземпляра объекта: calculateDamageWithCrit при условии, что генератор случайных чисел тоже статический (принадлежит библиотеке языка в целом, а не игровому миру). <br/> <br/> <b>Где правильно хранить экземпляры классов врагов?</b> <br/> <br/> С Wave вы, вероятно, сами запутались: это то информация о волне, то часть текущего состояния мира. Я бы всех врагов закинул в Game (правда, назвал бы объект World). <br/> <br/> <b>Создать статическую переменную в классе башни, или все же создать экземпляр башни и хранить его в классе игры</b> <br/> <br/> Башня принадлежит игровому миру — тоже её в Game (или World). <br/> <br/> <b>У башни есть массив с пулями которые она выпускает.</b> <br/> <br/> Пули очень не стоит в башню — их лучше в тот же Game/World. Башню вы уничтожаете — пули тоже исчезают? <br/> <br/> <b>И эта вот функция просчёта у меня просто в файле. Нужно ли её загонять в класс как метод?</b> <br/> <br/> Только для красоты. Не важно, где лежит скрытая функция, если она не зависит от экземпляра (типа-статическая) и скрытая (не видна снаружи). <br/> <br/> <b>Важная штука</b> : часто в играх есть неизменная информация о врагах, башнях, пулях (TowerType, EnemyType, BulletType, WaveInfo…), и есть конкретный экземпляр (Tower, Enemy, Bullet). Иногда враги, башни и пули объединяют в один GameObj, но это уже зависит от архитектуры. Возможно и так, и этак.
Похожие вопросы