Asteroid-Spieler in Java

Display example

Diese Seite gibt Zugriff auf eine erste Implementierung eines automatischen Spielprogramms für das Spiel Asteroid von 1979, die als Antwort auf den Wettbewerb creativ '08: Asteroids der Zeitschrift c't programmiert wurde.

Menü

  • Letzte Änderungen
  • Download
  • Erzeugen eines Projekts in Eclipse (für Anfänger)
  • Applet zum Betrachten von Dumpfiles
  • Wissenwertes
  • Zweck diese Projekts
  • Überblick über die Klassenstruktur
  • Threads
  • Programm starten
  • Programm-Dumps analysieren
  • Javadoc
  • Letzte Änderungen

    Download

    Bibliothek

    Wettbewerbsbeitrag

    Erklärungen zum Aufbau (bisher noch nicht viel)

    Wissenswertes

    Zweck dieses Projekts

    Diese Veröffentlichung dient dazu, Java-Anfängern schon mal eine Basis in die Hand zu geben, um sich nicht um die Details der UDP-Kommunikation und die Bitschiebereien beim Auslesen des Vektorspeichers kümmern zu müssen. Mittlerweile basiert auch das in der der Games-Seite verwendete Applet auf diesem Code (und ist natürlich in den Quellen enthalten).

    Bitte versucht, mit den hier angegebenen Dokumenten (für das eigentliche Programm) und frei verfügbaren Hilfen (für Java im Allgemeinen) klarzukommen, da ich nur begrenzt Zeit habe, Eure E-Mails zu beantworten. Ansonsten gibt es ja auch das Forum oder das Wiki.

    Überblick über die Klassenstruktur

    Es gibt eine javadoc-Dokumentation der jeweils aktuellsten Version.

    Basis ist hier bei mir zuhause bis inklusive Version 0.52 JDK 1.6, danach JDK 1.5 ohne irgendwelche Besonderheiten. Die Implementierung ist effektiv genug, dass sie inklusive Anzeige hier bei unter 5% Rechnerauslastung dümpelt (AMD Athlon(tm) 64 X2 Dual Core Processor 4200+ unter Linux), also bleibt noch genug Raum für Optimierungen.

    Die Klasse de.caff.asteroid.Communication dient der Kommunikation mit dem MAME-Prozess. Sie läuft in einem eigenen Thread. Bei eingehenden Datagrammen konvertiert sie diese in ein de.caff.asteroid.FrameInfo, das schon Objekte wie Asteroid und SpaceShip kennt.

    Als Beispielimplementierung dient SampleAsteroidPlayer, der im Großen und Ganzen dem Beispiel von Harald entspricht.

    Threads

    Im Gegensatz zu Haralds C++-Version verwendet diese Version Threads, in der vorliegenden Version allerdings nur für die Kommunikation, die in einem Extra-Thread läuft (und damit unabhängig vom Zeichnen ist). Sinnvollerweise sollte auch die KI in einem eigenen Thread laufen, aber im Moment klinkt sie sich in den Kommunikations-Thread ein, da sie über das FrameListener an die Kommunikationsklasse anhängt.

    Programm starten

    Generell muss das Programm immer nach MAME gestartet werden.

    java -jar asteroid.jar [hostname[:port]] [-d] [-b port] [-s file]
    java -jar asteroid.jar -P [hostname[:port]]

    hostname[:port] Angabe des Hosts, auf dem MAME läuft. Port von MAME ist natürlich immer 1979 und kann daher entfallen. Momentan gibt es die Angabe nur, damit ich den Bridge-Modus testen konnte. Ohne Angabe des Hostnamens wird 127.0.0.1 (Localhost) angenommen.
    -d Displaymode.
    Öffnet ein Fenster, das die eigene Idee des Vektorspeichers darstellt.
    -b port Bridgemode.
    Reicht die von MAME generierten Datagramme über den angegebenen lokalen Port weiter und vice versa. Im Moment kann dies höchstens dazu verwendet werden, dass auch andere Programme dort anmelden können, um zum Beispiel bei einem remote laufenden MAME trotzdem lokal was anzeigen zu können. Natürlich wird die Latenz dadurch ein wenig erhöht.
    Die Idee dahinter ist allerdings, später einmal auf diese Weise den von Harald vorgeschlagenen 3D-Modus zwischenschleifen zu können.
    Im Bridgemode versucht das Programm natürlich nicht selbst zu spielen.
    -s file Dump.
    Alle erhaltenen und gesendeten Daten werden in die Datei file geschrieben. Diese Datei kann später mit einem weiteren Tool (s. u.) ausgelesen und analysiert werden.
    -p player Player festlegen.
    Legt den Klassennamen eines PlayerStarters fest, der einen bestimmten Player installiert. Es kann entweder der komplette Klassennamen angegeben werden, oder ein Kürzel, dem wenn nötig noch der Präfix "de.caff.asteroid." und der Suffix "PlayerStarter angehängt wird. Momentan sind folgende Player vorhanden (Kurzform, Groß- und Kleinschreibung ist wichtig):
    1. rammi.Rammi: gibt's nur bei mir zuhause
    2. Sample: Haralds Beispielimplementierung
    3. Stupid: Die Arnold-Version: Gasgeben und schießen
    Wird kein Player angegeben, wird versucht, diese in der angegebenen Reihenfolge zu starten. Da meine Klassen nicht mitgeliefert werden, gibt es den ersten Player nicht und daher wird dann der Sample-Player von Harald gestartet.
    Im Bridge-Modus wird kein Player gestartet, daher ist dieser Schalter dort sinnlos.
    -P [hostname[:port]] Erlaubt das Spielen als Mensch.
    Defaultmäßig wird das Online-MAME unter asteroids.heise.de:1979 verwendet, die Tastenbelegung ist wie unter Wettbewerbsseite beschrieben:
    TasteFunktion
    Qlinks drehen
    Wrechts drehen
    ISchub
    OFeuer
    LeertasteHyperspace
    1neues Spiel (nicht beim Online-MAME, sondern nur bei einem modifizierten lokalen)
    ACHTUNG: Falls nicht gegen ein modifiziertes MAME gespielt wird, ist dies im am Anfang angezeigten Einstellungsdialog auch so anzugeben, sonst stürzt das MAME ab.
    Das mitgelieferte Skript runHumanPlayer.sh bzw. runHumanPlayer.bat startet ein Spiel mit dem Online-MAME, setzt aber noch einige sinnvolle Parameter für das verwendete Java.

    Ein paar Beispiele:

    Analysieren

    Was nützt einem eine Dumpdatei, die man nicht anschauen kann? Daher ist auch ein Analysetool enthalten, das man auf die folgende Weise starten kann:

    java -mx1800m -cp asteroid.jar de.caff.asteroid.analysis.AnalysisDisplay [-s] dump-datei
    

    Der Java-Schalter -mx1800m sorgt für genug Speicher (1800 MByte) und muss vielleicht bei Dir angepasst werden (viel mehr gibt 32-Bit-Java aber nicht her). Der Speicherbedarf hängt natürlich von der Größe der zu analysierenden Dump-Datei ab. Die können recht groß werden, pro Minute sind es etwa 3,7 MByte.

    Ab Version 0.61 werden auch Dumpfiles in dem von der c't verwendeten Format verstanden (ab 0.62 auch die 2. Version), und Dumpfiles dürfen auch gepackt sein mit ZIP oder GZIP, und als kleine Hilfe gegen die Firefox-Appletprobleme kann man auch eine URL angeben (falls Du über einen Proxy surfst, muss dieser allerdings noch in der Kommandozeile nach dem java in der Form -Dhttp.proxyHost=proxy -Dhttp.proxyPort=8080 angegeben werden. Ebenfalls ab dieser Version gibt es den Schalter -s, der ein reduziertes Interface ähnlich dem Applet startet.

    Das Ergebnis sieht dann etwa so aus (unreduziert):

    Screenshot vom Analysator-Fenster

    Wie man sieht, hat das Fenster verschiedene Bereiche. Ganz unten ist die Timeline, die den Inhalt der Datei in zeitlicher Reihenfolge darstellt, blau steht für Frames im Spiel (dunkelblau mit und hellblau ohne Schiff) und orange für welche dazwischen. An den Übergängen werden automatisch Marker gesetzt, die sich über die Knopfleiste oben mittig anspringen lassen. Die zwei schwarzen Dreiecke mit dem Strich dawischen markieren den aktuellen Frame. Wie zu erwarten kann man auch mit der Maus draufklicken oder draggen und die Markierung verschiebt sich entsprechend. Rollt man über der Timeline oder der grafischen Anzeige am Mausrad, bewegen sich die Frames mit jedem Klick vor oder zurück (mit SHIFT von Markierung zu Markierung). Den Index des aktuellen Frames sieht man übrigens im Titel.

    Ebenfalls hauptsächlich zur Navigation dient der Toolbar oben. Die Doppelpfeile machen keinen schnellen Rück- oder Vorlauf, sondern verschieben frame-weise (ich habe nur auf die Schnelle keine passenderen Icons gefunden). Die Pfeile mit dem Strich dran gehen zum vorigen bzw. nächsten Marker (also Übergang zwischen Spielphase und Zwischensequenz). Die Playtaste lässt das Spiel dann automatisch ablaufen, bei mir allerdings etwas langsamer als das Original, weil die ganze Informationsanzeige dann doch Zeit frisst. Schließlich kann man mit der Velocities-Checkbox anschalten, ob Geschwindigkeitspfeile berechnet und angezeigt werden (die werden dann im Hintergrund berechnet bzw. entfernt, daher ist die Reaktion nicht instantan, aber doch verblüffend schnell).

    Die Box Buttons direkt drunter enthält die zwischen dem letzten und diesem Frame gesendeten Buttons. Normalerweise ist das nur ein Paket, allerdings kann das im Bridge-Modus anders aussehen.

    Links in der Box Game Objects gibt es eine Übersicht über den Frame und die darin enthaltenen Objekte. Diese können selektiert werden, und die Daten des jeweils selektierten Objekts werden dann im Bereich Properties of Selected Object in der Mitte rechts angezeigt.

    Die Selektion wird auch durch einen magentafarbenen Rahmen im Frame-Display unten rechts markiert. Umgekehrt kann man dort auch auf ein Objekt klicken, um es zu selektieren und dadurch seine Eigenschaften angezeigt zu bekommen.