UPDATE 2018: Moin Leute, hier gibts die EPISCHE Version dieses Artikels (in Englisch): https://happy-computing.weebly.com/tape.html..
Während Programmieren in vielen Ländern zu so einer Art Volkssport wird, tut man sich in Deutschland noch etwas schwer. Doch hier kommt ein Spitzengrund, um sich mit Coding zu beschäftigen. Ok, etwas exotisch ist das schon, aber ohne Frage faszinierend. Was man von den üblichen "Hallo Welt"-Übungen sicher nicht behaupten kann.
Letzten Monat beschäftigte mich ja die Frage, wie man 3D-Daten aus Spielen extrahiert. Und vor Jahren erwähnte ich die Möglichkeiten, Sprites aus 8-Bit-Spielen auszulesen.
Diese kultige Pseudo-3D-Grafik in echtes 3D zu verwandeln, lag nah. Und logisch, jemand hat auch schon Antesher in Minecraft gebaut. Aber seien wir ehrlich: Von Hand Klötzchen zu stapeln, ist etwas für Luschen. Der Katalane Carles Oriol schrieb hingegen ein Python-Script, um die Original-Daten aus einer Snapshot-Datei des Sinclair-Spectrum-Spiels (die wurden damals übrigens noch auf Audio-Kassetten gespeichert, liebe Kinder) auszulesen. Apropos Audio-Kassetten: Mit Taper kann man sich deren Inhalte genauer ansehen und der OtlaPlayer konvertiert die Daten-Sounds ins mp3-Format: So lässt sich ein Spiel dann in wenigen Sekunden auch in einen Original-Spectrum schaufeln :)
Zurück zum Thema. Die Schritte im Einzelnen:
- Emulator installieren,
- Python in der Version 2.x (nicht 3.x!) installieren,
- Spiele-ROM runterladen,
- starten und einen Snapshot (quasi ein Spielstand) unter dem Namen “ant.sna” abspeichern,
- in Python dieses Script erstellen und im gleichen Verzeichnis mit der .SNA-Datei abspeichern, und dann ausführen (F5):
file = open("ant.sna", "rb")
file.seek( 32795 );
buf=file.read()
print "map=["
for y in range(0,128):
print ("["),
for x in range(0,128):
print (ord(buf[x+y*128])),
print (","),
print "],"
print "];"
Etwas Hintergrund von Meister Carles: "About (ord(buf[x+y*128])): buf is an list for all the elements in the map (128 widht x 128 height), so to get the first one should be buf[0], next one to the right buf[1] until element buf[127]. Then buf[128] is the first next line... So to get the element at position (x, y) we multiply y128 and add x. buf[x+y128] ord function is to indicate python that the element is a byte if not it would get an ascii equivalent (A=65) easy."
Anders ausgedrückt: Nach dem Start bekommt man einen Haufen Zahlen um die Ohren gehauen. 16.384, um genau zu sein. Denn die Stadt Antesher hat eine Grundfläche von 128 x 128 Blöcken. Der erste Datensatz sieht so aus und repräsentiert, wenn ich die Beschreibungen auf dieser Seite richtig verstanden habe, die erste Reihe (von oben gesehen) der Stadtmauer:
[63, 15, 15, 7, 3, 3, 7, 3, 3, 3, 7, 3, 3, 7, 3, 3, 7, 3, 3, 3, 7, 3, 3, 3, 7, 3, 3, 7, 3, 3, 7, 3, 3, 7, 3, 3, 7, 3, 3, 7, 15, 15, 15, 15, 7, 3, 3, 7, 3, 3, 7, 3, 3, 7, 3, 3, 7, 3, 3, 7, 3, 3, 7, 3, 3, 3, 7, 3, 3, 7, 3, 3, 7, 3, 3, 7, 3, 3, 7, 27, 27, 7, 3, 3, 7, 3, 3, 7, 3, 3, 7, 3, 3, 7, 3, 3, 15, 27, 27, 15, 3, 3, 7, 3, 3, 7, 3, 3, 31, 27, 59, 27, 27, 31, 3, 3, 7, 3, 3, 7, 3, 3, 7, 3, 3, 7, 15, 63,]
Carles hat mir dazu geschrieben: "The numbers 63, 15, 7 are the binary representations about the blocks and holes so: a pilar of three elements it's (binary) 111 = 7 (decimal) with a hole 101 would be 5 (decimal). (lower digits are closer to ground)." Über einen Binär/Dezimal-Rechner lässt sich das prima nachvollziehen, die Dezimalzahl "63" steht also für sechs binäre Einsen (111111) und repräsentiert somit sechs Blöcke, siehe OpenSCAD-Screenshot oben. Man kann also mit einer einzigen Dezimal-Zahl eine vertikale Struktur beschreiben, ggf. inklusive Öffnungen!
Hier noch ein Bild, das illustriert, wie diese Zahlen sogar in einem Texteditor ein 2D-Bild ergeben. Man kann das "(c) SW" aus dem 30 Jahre alten Kassetten-Spiel zumindest erahnen, wie cool ist das denn!
So, nun zu OpenSCAD. Es ist die Hacker-Variante eines 3D-Programms. Hier entstehen 3D-Objekte ausschließlich aus Zahlenwerk bzw. Formeln. Dadurch werden Objekte möglich, die man von Hand nie erstellen könnte (zum Beispiel diese unfassbare digitale Sonnenuhr!!). Auch Antesher wird so in wenigen Sekunden aufgebaut:
/*
ZX Spectrum
Ant attack city map
Antescher
Carles Oriol 29/05/2015
(c) Sandy White
Thanks Sandy this was the first game I every had in my computer when I was 13 years old. I enjoyed playing it and hacking it.
*/
$fn=16;
mode=1;
color([1,1,1]) translate([130/2-2,-130/2+2,-2]) cube([140,140,2], center=true);
module block(x,y,z)
{
translate([x,y,z])
{
if( mode==0) // view borders
cube([.9,.9,.9]);
if( mode==1) // printable size
cube([1.05,1.05,1.05], center=true);
if( mode == 2) // boh...
difference()
{
cube([1,1,1]);
sphere(.85, $fn=9);
}
if( mode == 3) // perfect cube
cube([1,1,1]);
if( mode == 4) // lego style
{
cube([1,1,1]);
translate([.5,.5,1]) cylinder(r=.3, h=.2);
}
}
}
function bit(valor, nbit) = floor(valor/pow(2,nbit))%2 ;
module hblocks(x,y,n)
{
for( z= [0:n-1] )
{
block ( x,y,z );
}
}
module blocks(x,y,n)
{
for( z= [0:8] )
{
if( bit(n,z) == 1)
block ( x,y,z );
}
}
color([.7,.7,.7])
{
include <map.scad>
for( row = [0:127])
for( x = [0:127])
{
if( map[row][x] > 0 ) blocks(x,-row, map[row][x] );
}
}
Fett und in Rot: Die Zahlenkolonnen, die das Python-Script ausspuckte, werden nachgeladen. Und zack, hat man Sandys Original-Daten aus den 80er Jahren nicht nur in das Jahr 2015 gebeamt, sondern auch in echtes 3D verwandelt! Und das mit so wenigen Zeilen Code. Cool, oder? Für die ganz Faulen: Die Dateien bekommt ihr bei Thingiverse. Einen Spaziergang durch das original Antesher (mit isometrischer Grafik) ist dank des Pragers Pavel Šavara per Silverlight möglich. Und da die Unreal-Engine ja nun auch kostenlos heruntergeladen werden kann, ist es ein Kinderspiel, aus Ant Attack einen 3D-Shooter (oder was auch immer) zu basteln:
2 Kommentare:
Hi
Regards from the Catalan Carles Oriol
Yay! Welcome! And thanks again for your Efforts, what a great Idea of yours!
Kommentar veröffentlichen