Doom na czystym CSS: realizacja renderingu bez Canvas i WebGL
Rozwijający Nils Lenheer opublikował projekt cssDoom — pełną implementację klasycznej gry Doom, w której cała grafika jest renderowana wyłącznie za pomocą CSS. Logika gry jest zaimplementowana w JavaScript, bez użycia canvas ani WebGL. Jako baza posłużył kod źródłowy Doom od id Software, dostępny w plikach WAD. Projekt jest dostępny na GitHub pod licencją GPLv2.
Wszystkie elementy wizualne — sprite'y, teksturowane ściany, poziomy, efekty — są tworzone z elementów div. Są one pozycjonowane w przestrzeni 3D za pomocą właściwości CSS transform i transform-style: preserve-3d. JavaScript nie ingeruje bezpośrednio w style: zamiast tego ustawia niestandardowe właściwości CSS na podstawie geometrii wierzchołków z pliku WAD. CSS samodzielnie oblicza szerokość, wysokość i transformacje przy użyciu funkcji trygonometrycznych.
Adaptacja współrzędnych i pętla gry
System współrzędnych Doom różni się od CSS 3D: w Doom używany jest malejący układ 2D (oś Y rośnie na północ), w CSS oś Y skierowana jest w górę, a Z — w stronę widza. Transformacja jest realizowana za pomocą translate3d(x, -z, -y). Niestandardowe właściwości są definiowane w współrzędnych Doom, a CSS je interpretuje.
Pętla gry w JavaScript śledzi pozycję gracza, wejście, kolizje i AI przeciwników. Jest to bezpośredni port oryginalnego kodu. Podział jest ścisły: JS aktualizuje tylko kluczowe właściwości, takie jak --player-x, --player-y, --player-z, --player-angle. CSS przesuwa cały świat względem gracza, symulując kamerę (w CSS nie ma kamery). Ruch i widok to aktualizacja czterech właściwości.
Obsługiwany jest widok z pierwszej osoby, z możliwością przełączenia na widok mapy.
Szczegóły techniczne budowy sceny
Proces zaczyna się od parsowania pliku WAD: wyodrębniane są parametry liniowe, boczne i sektorowe. Na ich podstawie generowane są elementy div z początkową geometrią wierzchołków. CSS stosuje calc() do obliczeń:
- Szerokość i wysokość elementów są określane na podstawie kątów widzenia i odległości.
- Transformacje uwzględniają perspektywę.
Przykład uproszczonej struktury niestandardowych właściwości:
:root {
--player-x: 0;
--player-y: 0;
--player-angle: 0;
}
.scene-element {
width: calc(var(--doom-width) * var(--perspective-factor));
height: calc(var(--doom-height) * var(--perspective-factor));
transform: translate3d(
calc(var(--doom-x)),
calc(-var(--doom-z)),
calc(-var(--doom-y))
) rotateY(var(--player-angle));
}
Taki podejście zapewnia wydajność: silnik renderujący CSS przeglądarki optymalizuje transformacje 3D na GPU.
Porównanie z innymi eksperymentami
cssDoom kontynuuje linię nietypowych portów Doom. Wcześniej Adam Rice opracował Doom Over DNS: gra uruchamiana jest poprzez rekordy DNS TXT Cloudflare. Plik WAD jest kompresowany do ~1964 rekordów, dekompresowany skryptem PowerShell na bieżąco. Biblioteki DLL .NET są ładowane do pamięci bez zapisywania na dysk. Pokazuje to granice protokołów, ale ustępuje cssDoom pod względem złożoności wizualnej.
| Aspekt | cssDoom | Doom Over DNS |
|--------|---------|---------------|
| Rendering | CSS 3D div | Standardowy (przeglądarka) |
| Logika | JS (port Doom) | PowerShell + .NET |
| Zależności | Tylko CSS/JS | Zapytania DNS |
| Dostępność | GitHub | Publiczna strefa Cloudflare |
Co ważne
- Pełne renderowanie Doom w CSS: elementy div w przestrzeni 3D symulują raycasting.
- Niestandardowe właściwości + calc() do dynamicznych transformacji z danych WAD.
- Ścisły podział JS (logika) i CSS (wizualizacja) dla optymalizacji.
- Adaptacja współrzędnych Doom do CSS 3D poprzez inwersję osi.
- Otwarty kod na GitHub, licencja GPLv2.
Projekt jest przydatny do badanieenia granic CSS3 w gamedevie, zwłaszcza animacji transform i niestandardowych właściwości w scenariuszach czasu rzeczywistego.
— Editorial Team
Brak komentarzy.