Alle Befehle von PixelRAM zum Nachschlagen: den Bildschirm öffnen, Pixel setzen und lesen, Paletten, Farben ohne Palette, der Speicher hinter dem Bild, Tastatur, Maus und Zeit. PixelRAM hat mit Absicht keine Befehle für Linien, Kreise oder Figuren: Alles, was du siehst, besteht aus einzelnen Pixeln, die dein Programm setzt.
In einem Ordner mit der PixelRAM-Vorlage übersetzt make die Datei main.c in die Webseite main.html, die du mit »Go Live« in der Vorschau öffnest. Beim ersten Mal lädt make die Bibliothek PixelRAM in den versteckten Ordner .pixelram.
make # main.c → main.html make PROGRAM=spiel # spiel.c → spiel.html make PROGRAM=beispiele/feuer
make einen Fehler, nennt es Datei und Zeile, und die alte Webseite bleibt, wie sie war. Lies die erste Fehlermeldung zuerst.printf ausgibt, steht in der Konsole der Seite: Fahre mit der Maus über das Bild und klicke unten rechts auf das Terminal-Symbol oder drücke `.#include "pixelram.h" int main(void) { if (!screen_open(320, 180, pixel_indexed8, "Mein Programm")) return 1; while (!should_close()) { clear(0); // … Pixel setzen … present(); // das fertige Bild zeigen } screen_close(); return 0; }
| Befehl | Bedeutung |
|---|---|
screen_open(breite, hoehe, modus, titel) |
Öffnet den Bildschirm mit so vielen Pixeln; false, wenn es nicht klappt |
screen_width(), screen_height()
|
Breite und Höhe in Pixeln |
should_close() |
Wahr, wenn das Programm enden soll |
present() |
Zeigt das fertige Bild und wartet auf das nächste; einmal pro Durchlauf der Schleife |
set_target_fps(n) |
Höchstens n Bilder pro Sekunde, ohne Angabe 60; 0 schaltet die Grenze ab |
set_title(titel) |
Ändert den Titel |
set_pixel_aspect(f) |
Pixel breiter (größer als 1) oder höher (kleiner als 1) als quadratisch |
set_fullscreen(true) |
Vollbild, im Browser nach dem nächsten Klick |
screen_close() |
Schließt den Bildschirm am Ende |
Ein Programm ohne Schleife, das nur ein Bild malt, braucht im Browser kein present(): Die Seite zeigt das Bild dann von selbst.
Der Pixel (0, 0) ist oben links, x wächst nach rechts, y nach unten. Im Modus pixel_indexed8 ist die Farbe eines Pixels eine Zahl von 0 bis 255, eine Nummer in der Palette.
| Befehl | Bedeutung |
|---|---|
set_pixel(x, y, farbe) |
Setzt einen Pixel; außerhalb des Bildes passiert nichts |
get_pixel(x, y) |
Die Farbe eines Pixels; außerhalb des Bildes 0 |
clear(farbe) |
Füllt das ganze Bild mit einer Farbe |
Weil man Pixel auch lesen kann, ist das Bild selbst ein Speicher: Ein Spiel kann nachsehen, ob an einer Stelle schon etwas steht, und ein Feuer kann seine Farbe aus den Pixeln darunter ausrechnen.
for (int y = 0; y < screen_height(); y++) for (int x = 0; x < screen_width(); x++) set_pixel(x, y, (x ^ y) % 16);
Die Palette sagt, welche Farbe zu jeder Nummer gehört. Ändert man eine Farbe der Palette, ändern sich sofort alle Pixel mit dieser Nummer, ohne dass ein einziger Pixel neu gesetzt wird.
| Befehl | Bedeutung |
|---|---|
use_palette("pico_8") |
Wählt eine fertige Palette; ohne Angabe gilt vga
|
set_palette(nummer, r, g, b) |
Gibt einer Nummer eine Farbe, Rot, Grün und Blau von 0 bis 255 |
get_palette(nummer, &r, &g, &b) |
Liest eine Farbe der Palette |
palette_count(), palette_name(i)
|
Wie viele fertige Paletten es gibt und wie sie heißen |
PixelRAM kennt dieselben 88 Paletten wie Pixelflow Canvas, zum Beispiel vga, pico_8, sweetie_16, endesga_32, zughy_32 und aap_64. Alle stehen in der Dokumentation von PixelRAM.
Ein Farbverlauf in der Palette macht aus Nummern Helligkeiten, etwa für Feuer: Nummer 0 ist Schwarz, 63 ist Weiß, dazwischen Rot und Gelb.
for (int i = 0; i < 16; i++) { set_palette(i, i * 8, 0, 0); set_palette(i + 16, i * 8 + 128, i * 8, 0); set_palette(i + 32, 255, i * 8 + 128, i * 8); set_palette(i + 48, 255, 255, i * 8 + 128); }
In den anderen Modi steht in jedem Pixel gleich die Farbe:
| Modus | Bytes pro Pixel | Bedeutung |
|---|---|---|
pixel_indexed8 |
1 | Nummer in der Palette |
pixel_rgb565 |
2 | Farbe mit 5 Bit Rot, 6 Bit Grün, 5 Bit Blau |
pixel_rgb24 |
3 | Rot, Grün und Blau mit je 8 Bit |
pixel_rgba32 |
4 | Dazu 8 Bit Deckkraft |
| Befehl | Bedeutung |
|---|---|
set_pixel_rgb(x, y, r, g, b) |
Setzt einen Pixel in einer Farbe |
get_pixel_rgb(x, y, &r, &g, &b) |
Liest die Farbe; geht in jedem Modus, auch mit Palette |
clear_rgb(r, g, b) |
Füllt das ganze Bild |
screen_set_mode(breite, hoehe, modus) |
Wechselt Größe und Modus, während das Programm läuft |
set_pixel schreibt in einen Speicher, den die Grafik am Ende zeigt. Mit framebuffer() kommt man direkt an ihn heran, so wie Spiele aus den Neunzigerjahren:
uint8_t *pixel = framebuffer(); pixel[y * screen_pitch() + x] = 12; // dasselbe wie set_pixel(x, y, 12)
screen_pitch() ist die Länge einer Zeile in Bytes, framebuffer_size() die Größe des ganzen Speichers. Im Modus pixel_indexed8 ist jedes Byte ein Pixel. Direkt in den Speicher zu schreiben ist schneller, aber nichts passt mehr auf: Wer über den Rand schreibt, zerstört andere Daten.
| Befehl | Wahr, … |
|---|---|
key_down(pixel_key_w) |
solange die Taste gedrückt ist; für Bewegung |
key_pressed(pixel_key_space) |
nur in dem Bild, in dem sie heruntergedrückt wurde |
key_released(pixel_key_e) |
nur in dem Bild, in dem sie losgelassen wurde |
poll_key_event(&ereignis) |
wenn noch ein Tastendruck in der Warteschlange steht; ereignis.key und ereignis.pressed sagen welcher |
Die Tasten heißen pixel_key_a bis pixel_key_z, pixel_key_0 bis pixel_key_9, pixel_key_up, pixel_key_down, pixel_key_left, pixel_key_right, pixel_key_space, pixel_key_enter, pixel_key_escape, pixel_key_shift, pixel_key_ctrl und pixel_key_f1 bis pixel_key_f12. Buchstaben und Ziffern haben die Nummer ihres Zeichens: pixel_key_a ist 'a'.
Im Browser bekommt das Programm die Tasten erst, wenn du einmal ins Bild geklickt hast.
| Befehl | Bedeutung |
|---|---|
mouse_position(&x, &y) |
Wo die Maus steht, in Pixeln des Bildes |
mouse_delta(&dx, &dy) |
Wie weit sie sich seit dem letzten Bild bewegt hat |
mouse_button_down(pixel_mouse_left) |
Wahr, solange die Taste gedrückt ist; auch pixel_mouse_right, pixel_mouse_middle
|
mouse_button_pressed(…), mouse_button_released(…)
|
Wahr im Bild des Klicks oder des Loslassens |
set_mouse_relative(true) |
Fängt die Maus: Der Zeiger verschwindet, mouse_delta zählt jede Bewegung; im Browser nach dem nächsten Klick |
| Befehl | Bedeutung |
|---|---|
seconds() |
Sekunden seit dem Start, mit Nachkommastellen |
ticks_ms() |
Millisekunden seit dem Start, als ganze Zahl |
sleep_ms(ms) |
Wartet so viele Millisekunden |
Damit eine Bewegung auf jedem Computer gleich schnell ist, rechnet man mit der Zeit seit dem letzten Bild:
double vorher = seconds(); while (!should_close()) { double jetzt = seconds(); double dt = jetzt - vorher; vorher = jetzt; x += 40 * dt; // 40 Pixel pro Sekunde // … present(); }