Der Rasterbar-Effekt (auch Copperbar genannt) ist ein in Demos und älteren Videospielen verwendeter Effekt, der animierte, meist horizontale Farbbalken anzeigt. Solche Effekte waren auf dem Atari 2600 und der Atari 8-Bit-Familie weit verbreitet und später in Demos für den Commodore 64, Amiga, Atari ST, Amstrad CPC und IBM PC. Dieses Tutorial zeigt, wie man das im GameMaker Studio realisiert.
Übrigens: Der Begriff Copperbar stammt von einem Grafik-Coprozessor auf dem Amiga-Heimcomputer, der als Copper (eine Kurzform von Coprozessor) bezeichnet wird. Er kann so programmiert werden, dass er die Anzeigefarben pro Abtastzeile ändert, ohne die CPU zu beanspruchen, außer dass er die Position der Balken einmal pro Bild aktualisiert.
Heute kann man den Effekt im Menü als Hintergrund nutzen, für Credits oder als Fake-Cracktro.
Was wir brauchen
Wir werden diesen Effekt mit zwei Objekten und einem Sprite realisieren. In meinem Beispiel hat das Sprite eine Auflösung von 320×32 Pixel und sieht so aus:
Das wirkt recht unspektakulär. Später färben wir es per Code ein.
Nun brauchen wir noch die zwei Objekte o_bars_h und o_raster_bars_h.
Theorie
Das Sprite setzen wir im Objekt o_bars_h ein. Im Beispiel werden wir mit 16 Bars arbeiten, wobei jeder seine eigene Farbe enthält. Falls euch das bekannt vorkommt: Ja, etwas Vergleichbares haben wir bereits hier getan.
o_raster_bars_h ist das Objekt, welches wir im Raum platzieren. Dieses erstellt die 16 Instanzen der Bar und weist die Farben sowie Ausgangspositionen zu.
o_bars_h
Wie bereits erwähnt, setzen wir hier das Sprite ein. Origin beim Sprite sollte übrigens auf 0x0 stehen.
Create-Event
1 2 3 4 5 6 7 8 9 10 11 12 | image_alpha = 0; y_offset = 45; distance = 10; angle = 0; y_speed = 0.04; y_range = 60; interpolation_speed = 0.1; alarm[0] = 1*room_speed; |
Die Variablen erklären sich im Draw-Event quasi von selbst. Wichtig ist noch der Alarm. Hier regeln wir den Alpha-Wert. Den brauchen wir nur am Anfang, damit die Balken eingeblendet werden und nicht sofort auf dem Bildschirm erscheinen.
Alarm 0
1 2 3 4 5 | if (image_alpha < 1) { image_alpha += 0.01; alarm[0] = 0.05 * room_speed; } |
Draw-Event
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | draw_self(); // Berechne die gewünschte y-Position des Objekts mithilfe von cosinus y_target = y_offset + y_range * cos(angle); // Berechne die Differenz zwischen der aktuellen und der gewünschten y-Position var y_diff = y_target - y; // Addiere einen Bruchteil der Differenz zur aktuellen y-Position hinzu y += y_diff * interpolation_speed; // Verkleinere das Sprite, je weiter es von der Kamera entfernt ist image_yscale = 1 - (distance / 100); // Erhöhe den Winkel für die Kreisbewegungsfunktion angle += y_speed; // Prüfe, ob der Winkel den Bereich von 0 bis 360 Grad überschritten hat if (angle > 360) { angle = 0; } |
Hier findet die eigentliche Bewegung der Instanz statt, wobei wir die Höhe entsprechend der Distanz skalieren.
o_raster_bars_h
Hier brauchen wir nur ein Create-Event. Sobald die Instanzen erstellt wurden, übergeben wir ihnen noch ein paar Parameter und beste Wünsche mit auf den Weg. Die Farbe wird über image_blend definiert.
Create-Event
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | var bar_colors = [ [0, 255, 0], // Grün [0, 255, 127], // Gelbgrün [127, 255, 0], // Gelb [255, 255, 0], // Gelbgelb [255, 127, 0], // Orange [255, 0, 0], // Rot [255, 0, 127], // Pink [255, 0, 255], // Magenta [127, 0, 255], // Lila [0, 0, 255], // Blau [0, 127, 255], // Himmelblau [0, 255, 255], // Türkis [0, 255, 127], // Grüngrün [127, 255, 0], // Grüngelb [255, 255, 0], // Gelbgelb [255, 127, 0] // Orange ]; // Erstelle 16 Instanzen des Objekts „o_bars" for (var i = 0; i < 16; i++) { // Erstelle eine Instanz des Objekts var instance = instance_create_layer(0, 32 * i, „Instances", o_bars_h); // Setze die Farbe der Instanz instance.image_blend = make_colour_rgb(bar_colors[i][0], bar_colors[i][1], bar_colors[i][2]); // Setze den Abstand der Instanz zur Kamera instance.distance = (7 - i) * 10; instance.angle = 0.1 * i; } |
Um den Code besser zu verstehen, ist es ratsam, ein wenig mit den Zahlen zu spielen. Das hilft mehr als endlose Texterklärungen.