ПЛЯЖ

Некоторые знающие люди говорят, что самое крутое в моем портфолио — это 3D-шутер от первого лица со своим собственным веб-ориентированным 3D-движком на Three.js.

Отчасти они правы, наверное. Я принципиально не юзала готовые решения, никаких готовых физических библиотек — всё с чистого листа, на чистом коде. Но если честно, мне самой гораздо больше по душе другие мои проекты. А этот шутер так... чисто флекс и демонстрация возможностей для душных эйчаров. Хотя мои друзья из долины регулярно залетают в личку с комментариями в духе: «Стеф, ты хоть понимаешь, что в мире от силы пара тысяч человек способных поднять рабочий 3D-движок с нуля?». Приятно, конечно, но не то чтобы я этим дышу.

И вот сейчас, перебирая старые репозитории на Гитхабе, я вспомнила один поздний вечер на пляже. Да, ребятки, я туда не только фоткаться для соцсетей хожу, это место, можно сказать, мой персональный ночной офис, ха-ха.

Картина маслом: днем на пляже работать невозможно от слова совсем. Солнце фигачит так, что экран Макбука превращается в идеальное зеркало, в котором ты видишь только свое недовольное лицо. Плюс дикая жара, от которой кулеры ноута начинают реветь на максимальных оборотах. Короче, кринж и нулевая продуктивность.
Другое дело — ночь.

Представьте картину: вокруг глухая темень, ледяной ветер с океана, от которого спасает только огромный оверсайз-худи, и я. Сижу в раскладном кресле прямо на песке. Рядом остывает мой любимый безалкогольный коктейль — согревающий, слоистый, с густым зеленым мятным сиропом на дне и горячим красным ягодным чаем сверху. Перед глазами — тусклый матовый блеск экрана. Никаких тяжелых модных сред разработки, мне это не нужно. У меня открыт обычный nano — максимально простой консольный текстовый редактор прямо в терминале Мака. Только черное окно, строки кода и ядовито-зеленый курсор.

И в этом самом nano у меня открыта моя главная головная боль на тот момент — коллизии.

Для тех, кто не в теме: коллизии — это физика столкновения объектов. Сделать так, чтобы персонаж упирался в стену, а не летел сквозь нее. В готовых движках это делается в один клик. В моем кастомном коде это был персональный ад. Мой виртуальный персонаж упорно отказывался подчиняться законам физики. Стоило ему набрать скорость, как шаг просчета координат за один кадр увеличивался, и он буквально пролетал сквозь текстуру бетонной стены. Физически проскакивал ее и падал в бесконечную пустоту незарендеренного пространства. «Не туннелируй, пожалуйста, ну я же прописала проверку через векторы», — ворчала я под нос, стирая пальцы о холодную клавиатуру.

И вот в этот момент, когда я в сотый раз пересчитывала математику лучей, из темноты, прямо у кромки песка, раздался странный звук.

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

Я улыбнулась замерзшими губами и быстро набрала ответ в своем привычном ироничном стиле: «Если что, Спасатели Малибу рядом, я под прикрытием».

Чистая правда, кстати. Мое кресло стояло прямо в тени одной из этих культовых деревянных спасательных будок на сваях. Ночью они, разумеется, пустые — все спасатели давно спят дома. Но их массивные силуэты на фоне звездного неба создавали какое-то уютное, пусть и абсолютно ложное чувство безопасности. По крайней мере, от родительской паники защищало отлично.

Скрежет повторился, но уже гораздо ближе. Будто это «что-то» ползло прямо к моему шезлонгу. Я вздохнула, заблокировала Мак, включила фонарик на айфоне и направила луч вниз.

Из набежавшей пены на сухой песок неуклюже выползало нечто большое, усатое и покрытое шипами. Видимо, бедолагу случайно выбросило сильной ночной волной во время прилива, и теперь он сердито шуршал лапами по песку. Он потер усы о панцирь, издав тот самый сухой скрип.

Для любого нормального человека это был просто калифорнийский омар. Но для меня, выросшей на книгах Стивена Кинга, этот звук мгновенно отозвался в голове: Дид-а-чик? Дум-а-чум? Дад-а-чам? Я инстинктивно поджала ноги повыше на кресло и проверила, все ли пальцы на месте. Роланду Дискейну из «Темной Башни» на точно таком же ночном пляже повезло гораздо меньше. Мой реальный лобстер клешней не имел, но выглядел в темноте максимально стрёмно.

Оставлять его тут было нельзя — до утра высохнет. Надо было как-то закинуть его обратно в море, но трогать руками этого пришельца я не собиралась. Я перевернула пустую пластиковую бутылку и, используя её как импровизированный совок, начала аккуратно подталкивать бедолагу в сторону прибоя.

Омар отчаянно сопротивлялся. Он разворачивался ко мне, пятился, пытался обойти бутылку справа, слева, тыкался в ножку моего кресла под какими-то совершенно дикими углами. По песку он полз вообще не по прямой, а по дуге, постоянно меняя траекторию.

И тут, пока я пыталась направить этого упрямого Кинговского монстра в воду, меня жестко озарило. Я замерла с бутылкой в руке.

Блин, ну конечно! Почему мой персонаж пролетает сквозь стены в игре? Потому что я пыталась просчитать его движение по упрощенной координатной сетке. Будто он робот, который ходит строго вперед-назад и поворачивает только на 90 градусов. Если бы он ходил по такой сетке, проблем бы вообще не было. Но реальный игрок — как этот омар на песке. Он двигается под разными углами, стрейфит, подходит к стене под углом в 37 градусов, крутит камерой на ходу. Вектор его скорости постоянно расщепляется!
Мне не нужна была тяжелая физическая библиотека. Мне нужна была простая тригонометрическая функция.

Нужно просто написать функцию, которая в каждом кадре берет текущий угол взгляда персонажа, раскладывает вектор движения на синусы и косинусы, и вычисляет расстояние до стены по направлению этого луча. Если расстояние меньше радиуса хитбокса — движение блокируется. Всё! Магия синуса и косинуса, которую проходят в школе.

Омар тем временем поймал очередную набежавшую волну, его подхватило пеной, и он мгновенно скрылся в черной воде Тихого океана.

«Спасибо за код, друг», — шепнула я темноте.

Я запрыгнула обратно в кресло, сделала глоток своего красно-зеленого коктейля, который приятно обжег горло мятой, и рванула крышку Макбука. Пальцы сами полетели по клавишам, вбивая в nano тригонометрическую формулу. Через десять минут я запустила деплой. Персонаж на экране разогнался, прыгнул под углом прямо в стену... и намертво в неё уперся. Никаких пролетов сквозь текстуры. Никакого падения в пустоту. Движок работал идеально.

Я откинулась на спинку кресла и посмотрела на звезды. Движок готов. Пальцы на месте. Определенно, это была хорошая ночь.

https://game-3d-f1cc5.web.app/



Стефания

Моя нейросеть:
https://stephqnn-6f23f.web.app/

Мои официальные ресурсы:
https://t.me/stefanias_world
https://stephaniia-bubnova.web.app/
yandex.ru/rythm/profile/@019d3b535e807367b553f01d479beaef
https://t.me/+xGPeaaQyGIJjZGUy


Рецензии

С 3 по 5 июля состоится Литературный фестиваль в Этномире. В программе – семинары известных поэтов и писателей, поэтический конкурс, посвященный Году единства народов России, книжная выставкая-ярмарка. Приглашаем принять участие →