Маленькие радости большого мира

DOOM запустили на CSS

Содержание

    Неожиданный поворот в мире веб‑разработки

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

    Разработчик Нильс Ленхер реализовал амбициозный проект: он перенёс первый уровень DOOM в браузер, используя для визуализации исключительно CSS. Игровая логика написана на JavaScript, но вся графика построена на каскадных таблицах стилей — без применения Canvas и WebGL. Код проекта опубликован на GitHub под лицензией GPLv2, а поиграть можно на cssdoom.wtf. Для запуска подойдут последние версии Chrome или Safari — Firefox пока не поддерживает все необходимые функции.

    Этот эксперимент не про производительность: он демонстрирует, на что способен современный CSS.

    Как CSS стал 3D‑движком

    cssDOOMНа первый взгляд, каскадные таблицы стилей не предназначены для сложных графических задач. Однако Ленхер доказал обратное, создав полноценную 3D‑сцену из тысяч DIV‑элементов. Каждый объект — от стен до врагов — это стилизованный блок, размещённый в пространстве с помощью CSS‑свойств transform и transform-style: preserve-3d.

    Ключевой момент — использование оригинальных данных из WAD‑файла 1993 года. Координаты, высота пола и потолка, геометрия уровней передаются в виде CSS custom properties. Дальше в дело вступают математические функции: ширина стены вычисляется по теореме Пифагора через hypot(), а угол поворота — через atan2(). Эти инструменты, добавленные в CSS сравнительно недавно, позволяют проводить тригонометрические расчёты прямо в стилях.

    Разделение обязанностей между языками — основа архитектуры проекта. JavaScript отвечает за игровой цикл, коллизии и управление состоянием, а CSS берёт на себя все визуальные задачи: от позиционирования объектов до анимации и освещения.

    В CSS нет понятия виртуальной камеры, как в классических 3D‑движках. Вместо этого разработчик применил хитрый приём: при движении игрока перемещается весь окружающий мир в противоположном направлении.

    JavaScript передаёт всего четыре параметра: --player-x, --player-y, --player-z и --player-angle. На их основе CSS трансформирует сцену: поворачивает мир вокруг игрока и сдвигает его в пространстве. Если персонаж идёт вперёд, окружение смещается назад; если поднимается по лестнице, платформа опускается вниз. Такой подход требует инвертирования координат, но позволяет обойтись без сложной логики камеры.

    Одна из задач — создать иллюзию бесшовного пространства. Полы и стены должны стыковаться без видимых швов, даже если принадлежат разным секторам уровня. Решение нашлось в выравнивании текстур по мировым координатам: паттерн повторяется бесконечно, но его начало привязано к глобальной сетке. Это достигается через свойство background-position, которое учитывает положение каждого сектора.

    Сложные формы уровней — L‑образные комнаты, закруглённые коридоры, платформы с отверстиями — реализованы с помощью clip-path. Для простых многоугольников используется polygon(), для объектов с внутренними контурами — path() с правилом заливки evenodd. Новая функция shape() объединила преимущества обоих методов, позволив работать с процентами и сложными контурами одновременно.

    Освещение секторов управляется через filter: brightness(). Каждому участку сцены присваивается custom property --light, которое каскадно применяется ко всем элементам внутри: стенам, полам, спрайтам. Мерцающие лампы создаются анимацией этой переменной через @keyframes.

    cssDOOMВраги, двери, лифты и снаряды оживают благодаря возможностям CSS. Двери открываются через CSS transitions: при смене атрибута data-state на контейнере панели плавно сдвигаются вверх. Лифты требуют синхронизации с позицией игрока — здесь JavaScript рассчитывает траекторию с помощью функции cubic ease-in-out, чтобы движение оставалось плавным.

    Снаряды (ракеты и файерболы) анимируются через CSS animations. JavaScript задаёт конечную точку и длительность полёта, а стили перемещают объект от старта к финишу. Враги — это 2D‑спрайты с эффектом billboarding: они всегда повёрнуты к камере. Зеркальное отражение достигается через scaleX(-1), а анимация ходьбы — через сдвиг background-position-x в spritesheet.

    Чтобы избежать синхронного движения всех зомби, JavaScript добавляет случайную задержку (animation-delay). В будущем эту функцию можно будет перенести в CSS — как только появится встроенная поддержка случайных значений.

    Границы возможного

    Проект cssDoom — это демонстрация эволюции веб‑технологий за последние 30 лет. Функции вроде hypot(), atan2() и @property превратили CSS из инструмента для оформления страниц в среду для сложных вычислений и 3D‑визуализации. Нильс Ленхер подчёркивает: главная цель — найти границы возможностей браузера. Эксперимент показал, что разделение логики (JavaScript) и рендеринга (CSS) не только возможно, но и элегантно. Хотя производительность остаётся невысокой из‑за тысяч DIV‑элементов, проект доказал: современный CSS способен на гораздо большее, чем кажется на первый взгляд.

    Хотите проверить сами? Запускайте первый уровень DOOM в браузере, управляйте персонажем с помощью WASD и мыши — и убедитесь, что веб‑технологии умеют удивлять.


    Подготовлено по материалам с сайта: https://tproger.ru/news/razrabotchik-postroil-doom-na-chistom-css---rendering-bez-edinoj-s


    38 просмотров · 16.04.2026


    технологии, эксперимент, фронтенд, css, анимация в CSS, программирование, браузерные игры, github, javascript, doom, 3Dрендеринг, вебразработка


    Чтобы оставить комментарий, авторизируйтесь через соцсети: