Как стать автором
Обновить

Рендеринг DOOM с помощью чекбоксов

Ненормальное программирование *Разработка веб-сайтов *Программирование *WebAssembly *
Перевод
Автор оригинала: Эндрю Хэли
Скриншот из DOOM, отрендеренного с помощью нативных чекбоксов
Скриншот из DOOM, отрендеренного с помощью нативных чекбоксов

Дисклеймер: перевод статьи публикуется с одобрения оригинального автора

Поиграть можно тут (Chrome/Edge), исходный код здесь, текст статьи ниже.

На этой неделе я прочитал статью Брайана Брауна — "Я всё ещё продолжаю экспериментировать с чекбоксами". Там он рассказывал про свою библиотеку Checkboxland.

JavaScript-библиотека для отображения текста и анимаций на сетке из чекбоксов

Это довольно приятная библиотека. Её API и документация лучше некоторых библиотек, с которыми мне приходится иметь дело на работе. С её помощью можно рендерить текст, фигуры, изображения и видео. Есть низкоуровневое API. В ней есть всё, что надо. Брайан использовал Checkboxland для создания шикарных интерактивных анимаций.

Кто-то на Hacker News прокомментировал статью:

Я не думаю, что вы исчерпаете все возможности библиотеки, до тех пор пока не отренедерите с её помощью DOOM

После проверки, что Брайан ещё не взялся за реализацию этой идеи, я начал скрещивать Checkboxland и WebAssembly-порт DOOM Корнелиуса Дайкменна.

Корнелиус во всех деталях описывает процесс портирования DOOM в README. Я взял его порт за основу и написал glue-код для интеграции с Checkboxland.

В моём проекте DOOM запускается с помощью WebAssembly и рендерится в невидимый <canvas>. Я использую HTMLCanvasElement.captureStream() для его преобразования в MediaStream. Элемент <video> отображает MediaStream и передаётся методу renderVideo из Checkboxland. Я экспериментировал с разными пороговыми значениями, чтобы картинка получилась настолько чёткой, насколько это возможно. Одно из возможных улучшений — использовать что-то похожее на дизеринг.

Элемент <video> тоже можно было спрятать, но по моим наблюдениям пользователи не могли выйти из главного меню без посторонней помощи, если они не видели оригинальную картинку.

Наш экран — это сетка 160 на 100, состоящая из нативных чекбоксов. С более высоким разрешением FPS падал совсем низко. Изображение в начале статьи из ранней версии с разрешением 320x200.

const cbl = new Checkboxland({
  dimensions: "160x100",
  selector: "#checkboxes",
});

Стигматизированное CSS-свойство zoom используется для уменьшения размера чекбоксов. Использование transform: scale(x) приводило к худшей производительности и качеству картинки. К сожалению, это означает, что пользователи Firefox должны вручную уменьшить масштаб страницы.

Эта нестандартное свойство, и оно не находится в процессе стандартизации. Не используйте его на публичных сайтах — оно не будет работать у всех пользователей.

События нажатия клавиш форвардятся в скрытый <canvas>, чтобы избежать проблем с фокусом.

const forwardKey = (e, type) => {
  const ev = new KeyboardEvent(type, {
    key: e.key,
    keyCode: e.keyCode,
  });
  canvas.dispatchEvent(ev);
};

document.body.addEventListener("keydown", function (e) {
  forwardKey(e, "keydown");
});

document.body.addEventListener("keyup", function (e) {
  forwardKey(e, "keyup");
});

На время загрузки и компиляции WebAssembly-модуля на сетке отображается сообщение с помощью метода print:

Сообщение о загрузке WebAssembly, отрендеренное с помощью чекбоксов
Сообщение о загрузке WebAssembly, отрендеренное с помощью чекбоксов

После загрузки выводится сообщение о том, что нужно где-нибудь кликнуть, чтобы инициализировать <video>. После клика запускается игра!

Пока вы всё ещё тут, вы знали, что Билл Гейтс однажды поместил себя в DOOM, чтобы прорекламировать Windows 95?

Кадр из рекламы Windows 95, на котором изображён Билл Гейтс c ружьём внутри коридора DOOM
Кадр из рекламы Windows 95, на котором изображён Билл Гейтс c ружьём внутри коридора DOOM

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

Теги:
Хабы:
Всего голосов 10: ↑10 и ↓0 +10
Просмотры 7.2K
Комментарии Комментарии 4