3 Punkte von GN⁺ 2024-05-21 | 1 Kommentare | Auf WhatsApp teilen

City In A Bottle – Ein 256-Byte-Raycasting-System

  • Einführung

    • Heute stellen wir eine kleine Raycasting-Engine und einen Stadtgenerator vor, die in einer 256-Byte-HTML-Datei stecken.
    • Dieses Programm vereint mehrere Konzepte auf engstem Raum und lässt sich wie ein Rätsel Stück für Stück verstehen.
    • Die Hauptbestandteile sind der HTML-Code, die Frame-Update-Schleife, das Rendering-System, die Raycasting-Engine und die Stadt selbst.
  • Der gesamte Code

    • Dieser Code ist kein einfaches JavaScript-Snippet, sondern ein vollständiges HTML-Programm.
    • <canvas style=width:99% id=c onclick=setInterval('for(c.width=w=99,++t,i=6e3;i--;c.getContext`2d`.fillRect(i%w,i/w|0,1-d*Z/w+s,1))for(a=i%w/50-1,s=b=1-i/4e3,X=t,Y=Z=d=1;++Z<w&(Y<6-(32<Z&27<X%w&&X/9^Z/8)*8%46||d|(s=(X&Y&Z)%3/Z,a=b=1,d=Z/w));Y-=b)X+=a',t=9)>
      

HTML-Code

  • HTML-Code
    • Der HTML-Teil besteht aus einem einfachen Canvas-Element und einem onclick-Event.
    • <canvas style=width:99% id=c onclick=setInterval('',t=9)>
      
    • Die id des Canvas-Elements ist auf c gesetzt, sodass es in JavaScript angesprochen werden kann.
    • Das onclick-Event startet das Programm und erzeugt mit dem Aufruf von setInterval die Update-Schleife.

JavaScript-Code

  • JavaScript-Code

    • Der 199 Byte große JavaScript-Code, der beim Klicken auf das Canvas ausgeführt wird.
    • for(c.width=w=99,++t,i=6e3;i--;c.getContext`2d`.fillRect(i%w,i/w|0,1-d*Z/w+s,1))for(a=i%w/50-1,s=b=1-i/4e3,X=t,Y=Z=d=1;++Z<w&(Y<6-(32<Z&27<X%w&&X/9^Z/8)*8%46||d|(s=(X&Y&Z)%3/Z,a=b=1,d=Z/w));Y-=b)X+=a
      
  • Code-Analyse

    • Zur besseren Lesbarkeit wird der Code aufgeschlüsselt.
    • c.width = w = 99
      ++t
      for (i = 6e3; i--;){
        a = i%w/50 - 1
        s = b = 1 - i/4e3
        X = t
        Y = Z = d = 1
        for(; ++Z<w &  (Y < 6 - (32<Z & 27<X%w && X/9^Z/8)*8%46 ||  d | (s = (X&Y&Z)%3/Z, a = b = 1, d = Z/w));) {
          X += a
          Y -= b
        }
        c.getContext`2d`.fillRect(i%w, i/w|0, 1 - d*Z/w + s, 1)
      }
      
  • Schritt-für-Schritt-Erklärung des Codes

    • c.width = w = 99: Initialisiert das Canvas und setzt die Breite auf 99 Pixel.
    • ++t: Erhöht die Zeitvariable und erzeugt so die Animation.
    • for (i = 6e3; i--;){}: Die Schleife bestimmt die Helligkeit jedes Pixels.
    • a = i % w / 50 - 1: Berechnet die horizontale Komponente des Kameravektors.
    • b = s = 1 - i / 4e3: Berechnet die vertikale Komponente des Kameravektors.
    • X = t: Verwendet den Zeitwert als Startposition für X.
    • Y = Z = d = 1: Initialisiert die Werte Y, Z und d.
    • for(; ++Z<w & ...;): Das Raycasting-System läuft in einer Schleife, bis es eine Kollision erkennt.
    • c.getContext2d.fillRect(i%w, i/w|0, 1 - d*Z/w + s, 1): Zeichnet jedes Pixel und erzeugt das endgültige Bild.

Weiterführendes Lernen

  • Weiterführendes Lernen
    • Diese Demo wurde auf der Revision 2022 Demo-Party eingereicht und ist auf Pouet zu finden.
    • Auf Shadertoy gibt es eine erweiterte Version als 256-Byte-Shader.
    • Mit einem interaktiven Tool von Daniel Darabos lassen sich verschiedene Aspekte des Programms in Echtzeit manipulieren.

Meinung von GN⁺

  • Interessante Punkte

    • Dieses Programm zeigt, wie sich mit extrem wenig Code komplexe Grafiken erzeugen lassen.
    • Es verwendet nur grundlegende Mathematik, die auch für Einsteiger in die Softwareentwicklung verständlich ist.
    • Als gutes Beispiel für Code-Optimierung und Minimalismus kann es bei Wettbewerben wie Code Golf nützlich sein.
  • Kritische Perspektive

    • Der Code ist sehr stark komprimiert, was die Lesbarkeit beeinträchtigen kann.
    • Er eignet sich eher für künstlerische und experimentelle Zwecke als für praktische Anwendungen.
  • Verwandte Technologien

    • Für ähnliche Projekte finden sich auf Shadertoy viele verschiedene Shader-Beispiele.
    • Auf Plattformen wie Dwitter lassen sich weitere kleine Codebeispiele erkunden.
  • Überlegungen zur Einführung der Technik

    • Bei der Einführung dieser Technik sollten Lesbarkeit und Wartbarkeit des Codes berücksichtigt werden.
    • Man sollte sich der Herausforderungen bei Performance-Optimierung und Debugging bewusst sein, wenn komplexe Funktionen in sehr wenig Code umgesetzt werden.

1 Kommentare

 
GN⁺ 2024-05-21
Hacker-News-Kommentare

Zusammenfassung der Hacker-News-Kommentare

  • 1K-Pinball-Spiel in JavaScript:

    • „Es ist erstaunlich, wie viel Information sich in so wenig Code unterbringen lässt.“
    • „Das ist wirklich cool, aber während ich den Artikel gelesen habe, lief die Schleife weiter und mein Laptop wurde zu heiß.“
    • „Verwandte Themen: die World-Building-Methode von Pitfall auf dem [Atari 2600], prozedurale Generierung, Lazy Evaluation usw.“
  • Prozedurale Generierung und Lazy Evaluation:

    • „Es wurden verschiedene weiterführende Links zur prozeduralen Generierung geteilt.“
    • „Eine Beobachtung zur Ähnlichkeit zwischen Lazy Evaluation und Raytracing-Algorithmen.“
  • Weitere Meinungen:

    • „Wirklich cool! Gut gemacht.“
    • „Sowohl die Arbeit als auch der Artikel sind beeindruckend.“
    • „Ähnlich wie die 256-Byte-MS-DOS-Demo Remnants von Alcatraz – inklusive YouTube-Link.“
    • „Dass das in JavaScript geschrieben wurde, macht es noch beeindruckender.“
    • „Wirklich erstaunlich.“
    • „Macht Spaß zu lesen.“
    • „Wenn dir das gefällt, gefällt dir auf Twitter vielleicht auch #tweetcart: Programme in Tweet-Größe für die virtuelle Konsole Pico-8.“