28/04/2020

Web (3): Daft Jong — простая игра на JS/WebGL

В этой заметке я представляю простейшую версию (обкаточную реализацию) игры типа «пасьянс», а именно — трёхмерную разновидность известного MahJong'а (его пасьянсной вариации). Хотя, скорее, у меня смесь головоломки и пасьянса.

Технологии надо описывать, а в игру — играть. Поиграть вы можете, пройдя по ссылке внизу. А здесь я вкратце опишу какие технологии я применял и какие решения принимал. Игра написана на WebGL, с использованием Three.js. Цель игры — разобрать куб, попарно убирая одинаковые фишки (кубики).

Правила
«Правилами» я здесь называю пары узоров, так как именно по ним пользователь играет. Поскольку выбирать фишки нужно попарно, перед созданием объектов на сцене, нужно составить какую-то структуру, содержащую (описывающую) эти правила и гарантирующую «сходимость» головоломки. Для этого реализован алгоритм, создающий такую структуру, учитывающий выбранный размер головоломки, и потом, уже по этой структуре генерируется сама головоломка, её представление — соответствие расположения «правил» в пространстве с узорами.

Отрисовка фишек
В этой игре 35, или уже более, разных «правил». Узоры на фишках я решил отрисовать алгоритмом. Во-первых, потому что рисование такого количества картинок руками у меня заняло бы больше времени (а это не входило в мои планы), а написав алгоритмы отрисовки нескольких примитивных элементов, основанных на линиях и кругах, я смог их комбинировать и получить большое количество «правил». И, на данный момент, ещё не все комбинации употреблены. Во-вторых, генерация узоров на стороне клиента даёт ещё три бонуса. Первый серьёзный — возможность изменения картинок на лету. Пока реализовано только изменение цветов. Но можно реализовать случайную генерацию узоров, что не позволит игрокам «привыкнуть» к «правилам». Второй бонус заключается в возможности контролировать качество графики на стороне клиента, играя размером текстуры и соотношением логического пикселя экрана к аппаратному — DPR. Эту возможность, я может быть использую в реализации алгоритма адаптивного подбора нагрузки на CPU/GPU. Третий бонус, по началу не столь важный — трафик. Но если «правил» — разных цветов и комбинаций, будет больше, то исключение ожидания загрузки картинок с сервера будет более желательно, а рисовать руками придётся ещё больше и скучнее.

Выбор объектов
Так как в игре нужно разбирать головоломку, выбирая попарно фишки, технически нам нужен механизм выбора объектов на экране. Два подхода к решению этой задачи я описывал в статье Web (1): RayCasting vs GPU Color Picking (на примере Three.js). Для этого приложения я выбрал метод трассировки лучом (RayCasting) потому что объектов на сцене немного, а прозрачность текстур не используется.

NB
У меня игра лучше всего работает на телефонах — хоть и греет устройство и батарею расходует, но играется идеально гладко. На всех моих компьютерах — Linux Netbook, MacBook и даже большой Linux на Core i7 c nVidia GPU, работает гораздо хуже — компьютеры шумят, греются, а игра сильно тормозит. А в Safari на MacOS вообще едва дышит, так как аппаратная OpenGL не используется, якобы для экономии батареи.

P.S.
В игре так же реализована несложная система авторизации, её я здесь не описываю. Про это будет отдельная статья.

Ссылка на игру: Daft Jong

Как играть: выбираете один элемент, он выделяется, ищете второй такой же, выбираете его, выбранные фишки удаляются с экрана. Таким образом надо разобрать весь куб. В конце выводится время, за которое вы разложили игру и количество ошибочных ходов (попыток выбрать неодинаковые кубики). На мобильных устройствах вращение куба осуществляется одним пальцем, приближение/отдаление — жестом двумя пальцами. На больших системах куб вращается движением мыши с зажатой правой кнопкой, а приближение/отдаление— колесом мыши.