Итак, наконец, первая версия игры была выпущена. И она выглядит вполне себе достойна. Посмотреть можно тут.
Что же, пришло время разобрать, что было хорошо, что не очень, а что вообще пошло не так.
Rust
Удивил и заставил поднапрячься. Парадигма сильно отличается от всех языков программирования, с которыми я сталкивался, так что это было немного непросто взять и начать писать код. Отдельной головной болью был разбор сообщений компилятора (вроде вполне себе разумные сообщения, а как ими воспользоваться - непонятно). Впрочем, несколько дней погружения - и всё становится ясней.
Движок игры я написал на Rust, но переписывал его раза 3. Главной проблемой стало отсутствие прозрачности. Если JS позволяет "срезать углы", то Rust требует последовательности, без которой код превращается в нечитаемую кашу без понимания, как оно работает.
Если бы переписывал код ещё раз, то пошёл бы на следующие хитрости:
- Добавлял бы объекты на экране последовательности, равно как и их возможности (сперва пришельцы, потом они двигаются, потом начали стрелять и так далее);
- Вместо отрисовки по матрице - использовал бы отрисовку по координатам, т.к. у каждого объекта есть скорость и, в зависимости от неё, объект двигается;
- Не использовать тактирование по времени: количество кадров должно стать отправной точкой для движения изображений по экрану, а не принудительное разбиение.
Webassembly
Тут сложностей почти не возникло (лишь поначалу, пока непонятно, за что хвататься). wasm-pack всё делает сам, остаётся только удостовериться, что код работает верно. Углубляться в вопрос не стал.
WebGL
С графикой пришлось повозиться, хотя проблемных места было всего два:
- Наложение текстур - тут я сам виноват, просто недосмотрел, из-за чего не сразу получилось увидеть отображение. В принципе, сделал для одного объекта - сделал для всех фигур.
- Производительность: из-за того, что каждый раз пересоздавал буферы с вершинами объектов и координатами текстур - производительность сильно проседала и терялись кадры, что, порой, приводило к длительным зависаниям картинки (до 1 секунды).
Web Audio API
Тут всё прошло очень гладко (особенно если учесть, что я не сильно вообще заморачивался на тему озвучки: есть и хорошо).
Синтез звуков оказался очень простой задачей, API очень хорошо документировано и примеров очень много. Однако, для более серьёзной игры я бы не отдал озвучку на откуп второпях сгенерированным звукам.
JavaScript
Он, по-прежнему, безупречен. Первую версию Space Invaders я написал исключительно на нём. Примерно за вечер. Такую же версию, но на Rust я писал несколько дней... или недель - уже сбился со счёту.
Из проблем, опять же, всё та же трудность с тактированием игры. Не нужно делить секунду на 8 частей, запуская перерисовку каждые 125 милисекунд. Неэффективно. Отзывчивость игры получилась ниже среднего: играть можно, но всё время в голове вопрос, мол, а управление точно работает?
Вместе с Webassembly и Rust работает немного непредсказуемо. Структуры, передаваемые в wasm сразу же обнуляются и не могут быть использованы повторно (что непривычно), обратно тоже приходит не всегда такая информация, как хотелось бы. Это не проблема, но, иногда, немного сбивает с толку.
Заключение
По мере планирования игры я делал многочисленные заметки и записи. Что надо сделать, что исправить. Забавно, что сейчас, перечитывая свои записи, понял, что всё пошло прямо по ним: то есть как запланировал, так и вышло.
Когда буду делать следующую игру, пожалуй, проведу более внимательную подготовительную работу; это не будет лишним. Да и записи, наверное, лучше держать в более опрятном виде, а не прыгать среди многочисленных файлов в поисках нужного.