Обзор
В 2013 году я работал над мобильной игрой, жанр которой я хотел бы назвать соревновательное фермерство. Игра, в которой игрок может построить город, армию и атаковать друг друга.
Мы собираем игру в ObjC, используя Cocos2D, UIKit и Entitas. Entitas — это простая реализация паттерна Entity Component System, или сокращенно ECS.
В этой статье я расскажу об одном конкретном аспекте реализации игры, а именно о симуляции боя. Эта боевая симуляция легла в основу реального игрового процесса, повторов и проверок BackEnd. Без лишних слов привожу список систем:
В списке выше мы видим 27 систем, составляющих боевую симуляцию.
Синтаксис, который я буду использовать, представляет собой вымышленный язык, который включает в себя концепции ECS. В какой-то момент я мог бы построить из него настоящий язык программирования, но пока давайте рассмотрим его просто как псевдокод.
loop
— это список систем, которые выполняются повторно с определенной частотой.
В следующих статьях я рассмотрю реализацию каждой из этих 27 систем, чтобы показать, как можно реализовать такую сложную логику с помощью чистых концепций ECS. Но сначала позвольте мне объяснить детали, которые не видны непосредственно из определения цикла BattleSimulation
.
Данные
Данные в игре можно разделить на 3 категории:
- Конфигурация
- Состояние игрока
- Состояние выполнения
Если вы хотите узнать больше, вы можете воспользоваться моей старой статьей:
В игре, на которой я основываю эту статью, все не иначе.
Конфигурация
У нас есть конфиг, определяющий характеристики зданий и юнитов:
- размер здания
- очки здоровья
- задержка удара, урон, дальность и время
- скорость движения юнита
Состояние игрока
В случае битвы у нас есть два состояния игрока. Состояние атакующего игрока содержит информацию о юнитах, которые они привели в бой. Состояние игрока защитника содержит план города (какое здание на какой позиции) и сколько ресурсов можно разграбить.
Состояние выполнения
Во время игры взаимодействие с пользователем будет создавать новые данные, в нашем случае, в основном, какой юнит нужно развернуть на какой позиции. В случае воспроизведения или проверки BackEnd эти данные также сохраняются и добавляются к моделированию на основе дискретного шага выполнения. Скажем, мы хотим, чтобы наша битва/симуляция выполнялась в течение 2 минут с частотой 60. Тогда есть 60 * 60 * 2 = 7200
дискретных шага выполнения симуляции. Нам нужно сохранить событие взаимодействия с пользователем вместе с номером шага, а затем воспроизвести событие на данном шаге. Таким образом, у нас есть детерминированное воспроизведение.
Есть и другие вещи, о которых нам нужно позаботиться, если мы хотим иметь детерминированную и воспроизводимую симуляцию. Вот мои 5 центов об этом:
Я постараюсь сделать эту серию как можно короче. Так что пока это все. Оставайтесь с нами для следующей статьи, в которой мы погрузимся в первую систему в нашем цикле BattleSimulation
.
UpdateGroupObstaclesAndTargetOnDestructionSystem
. 😱