В субботу у меня ближе к полуночи появилось свободное время и жгучее желание сделать игрушку под браузер, забавы ради и увеличения опыта для. С жанром определился довольно быстро: т.к. на MMORPG в этот раз у меня точно не хватило бы времени, я решил делать просто мясорубку. Минут 20 ушло на написание базового кода для управления игроком и его противниками. И тут встал вопрос — 2D или 3D (вернее так: Canvas/SVG или все же полноценный WebGL)?

Учитывая, что я сейчас участвую в разработке проекта, где WebGL является базовой технологией для 3D режима, выбор я сделал осознанно. Уже примерно полгода я работаю с замечательной библиотекой Three.js и в этот раз она снова стала моим лучшим помощником.

В следующий час была создана и настроена сцена, добавлена болванка игрока в виде пары примитивов и создана первая версия противников.

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

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

Собственно, в качестве результата в ночь на воскресенье я имел следующую картинку:



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

Первым делом, после того как я вошел в офис, я попросил нашего моделлера сделать мне для антуража модель сухого дерева, а сам подобрал на просторах сети модельку пушки. Модель противника я взял из примеров к библиотеке Three.js.
Народ в офисе периодически подходил посмотреть чем я занят. Все мило улыбались и ждали ссылку.

Буквально за несколько минут было придумано название (его смысл раскроется попозже), а затем я попросил нарисовать заставку, кнопки, иконки фрагов и здоровья, это с удовольствием сделал наш дизайнер.



Потом я подумал, что на дворе зима и без снега будет неуютно. Сказано – сделано, за 10 минут был прикручен снег на основе системы частиц.

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

Возвращаясь к описанию механики сцены я напомню, что нам всегда известны углы направления пушки и углы противников. Зная это, мы легко можем определить, попадает пуля в противника или нет, и в очередной раз замечу, что этот подход существенно упростил процесс расчета полета и попадания пули в противника. В итоге наша пушка научилась стрелять, а пуля – попадать в противника.
Осталось научить наших противников быть похожими на что-то живое. Я использовал уже анимированные модели, что само по себе позволило очень быстро наладить простейший механизм смены анимации и состояния противника: он бежит, падает, встает и идет нахмурившись, а под конец и вовсе умирает.
Кстати, достигнув определенного расстояния до игрока, противник переходит в режим атаки и, собственно, пытается забрать жизнь у игрока.



Чуть позже были добавлены обработчики клавиатуры для установки паузы и перехода в полноэкранный режим, а затем и собственно обертка для функционирования игрового процесса. Наверное, все это добавило немного каши в код, но время близилось к намеченному на 8 часов вечера корпоративу, и уже было несколько не до того :)

В конце концов все это дело перекочевало на сервер, и все, кто хотел – получили свою ссылку.

После анализа первых фидбеков были внесены небольшие правки, добавились боссы, противники стали умирать не сразу, а пули стали наносить плавающий урон.

Думаю, на выходных у меня еще появится свободное время, и я смогу прикрутить ИИ к противнику (чтобы он прятался за деревья и перемещался перебежками), сделаю деревья непробиваемыми и непроходимыми, ну и что-нибудь еще.

Все исходники проекта открыты для исследования. Я не добавлял комментарии, но старался писать код структурированным и понятным для изучения.

PS И да, я не претендую на образцовое решение и идеальные варианты реализации, это just for fun который работает в Google Chrome, Safari и Mozilla Firefox.