Все заметки

Игровой интерфейс

Большинство игр имеют различные внутриигровые интерфейсы вроде индикатора здоровья игрока, мини-карты, инвентаря, журналов заданий, меню с настройками и прочего.

К счастью веб что называется «из коробки» имеет широкий набор инструментов для создания подобных интерфейсов. Можно конечно использовать для этих целей уже существующую систему рендеринга на WebGl, но при таком подходе придется решать проблемы позиционирования, адаптивности, обработки событий на клик и многое другое. Веб же с подобными проблемами уже давным-давно справился. Поэтому я подавил безудержное желание изобретать велосипеды и перешел к поиску вариантов написания интерфейса с использованием стандартных для веба технологий: HTML и CSS.

Первой идеей было добавление нового компонента, содержащего HTML шаблон и стили. В таком случае, можно написать UI систему, которая будет собирать объекты с такими компонентами вместе и рендерить все это отдельным слоем в каком-нибудь div-е.

Обдумывая этот способ, через некоторое время я столкнулся с проблемой: пока ты верстаешь в рамках одного элемента, все ок. У тебя перед глазами есть его HTML, можно развешивать классы, писать по ним селекторы, позиционировать внутри всякие штуки. Все как обычно. Но затем, тебе нужно собрать все это вместе на экране. И тут начинаются проблемы. Из-за того, что весь UI раскидан по игровым объектам, ты не можешь увидеть итоговую структуру интерфейса во время разработки. UI система построит ее автоматически на этапе загрузки сцены. Отсюда возникает вопрос: как позиционировать компоненты интерфейса относительно страницы?

Первое что пришло в голову – это указывать в UI компоненте координаты x и y относительно экрана монитора, а затем переводить это в top-ы и left-ы абсолютного позиционирования через CSS. Или можно для каждой сцены собирать какой-нибудь main.css, который будет расставлять все объекты по местам.

Звучит, конечно, интересно, но как-то совсем не похоже на то как пишутся веб интерфейсы в реальном мире. Нужно что-то попроще.

Через некоторое время меня посетила другая мысль: что если не пихать рендеринг интерфейса в игровой движок, а вместо этого собирать весь UI в отдельном приложении? Тогда система не будет заниматься его отрисовкой, а будет служить чем-то вроде моста между игровым движком и интерфейсом. Будет принимать UI события, передавать информацию об объектах сцены и тд. В таком случае писать интерфейс станет намного приятнее: компоненты не будут раскиданы по куче игровых объектов, которые хз как собирать вместе, не нужно будет придумывать своих штук с позиционированием UI. Все как в обычном вебе.

При этом, появится возможность полностью абстрагироваться от деталей реализации интерфейса. Совершенно неважно на чем он будет написан. React, Angular, да хоть JQuery. Нужно только предоставить набор инструментов для взаимодействия ui и движка.