HaDesWWW logo
Startseite

Downloads
Geschichte(n)
 
Hardware
FPGA-Board
Prozessor
  Instruktionssatz
Peripherie
  XBus-Referenz
PS/2-Board
Soundboard
USB-MMC-Board
 
PC-Software
HaCom
HoAsm, HLink
Emulator
Connectivity
 
Embedded Software
HAL
Dateimanager
Tetris
PacMan
3D-Engine
Pong
PacMan 3D
 
Kontakt

HaDes XP - Tetris

Überblick

Screenshot von Tetris

Wer kennt nicht Tetris? Neben Pong ist es sicher der Arcade-Klassiker überhaupt. Nachdem es den Gameboy zum Erfolg machte, haben seither auch unzählige Klone und Varianten auf dem PC Einzug gehalten. Also brauchten natürlich auch wir eine Version. 

Das Ziel von Tetris: Ordnen Sie die immer schneller herunterfallenden Steine geschickt an, so dass komplette Zeilen gefüllt und entfernt werden. Je mehr Zeilen Sie mit einem einzigen Stein entfernen können, desto mehr Punkte erhalten Sie. 

Tetris wurde als erstes HaDes-Spiel noch für den Textmodus entwickelt (damals gab es noch keine Grafikkarte), allerdings genügt dieser, natürlich mit modifiziertem Zeichensatz zur besseren Darstellung der Steine, auch völlig. Mit der Zeit wurde das Spiel aber um zahlreiche Funktionen wie Highscores, Soundausgabe und Multiplayer übers Netzwerk erweitert, so dass es heute das größte Anwendungsprogramm für die HaDes ist (33 KB HIX + 44 KB Sounds).

Bedienung

Folgen Sie den Anweisungen, um das Spiel zu starten. Zum Aufbau einer Multiplayer-Verbindung gehen Sie dabei wie folgt vor: 

  • Starten Sie zunächst alle benötigten HMC-Programme und verbinden Sie diese untereinander. 
  • Fügen Sie die HMC-Verbindungen zu den beteiligten JTAG-Ports hinzu bzw. verbinden Sie das JTAG-Fenster des Emulators mit dem HMC (Rechtsklick, "Connect to HMC..") 
    Aufbau eines Netzwerkspiels
  • Starten Sie nun auf einer der (evtl. emulierten) HaDesen den Tetris-Server (M, S) und legen Sie die Spieler an. 
  • Starten Sie nun auch den anderen HaDesen den Tetris-Client (M,C). Die Verbindung sollte automatisch hergestellt werden. Legen Sie die Spieler an. 
  • Starten Sie das Spiel auf dem Server. 

Zur Steuerung innerhalb des Spiels verwenden Sie folgende Tasten: 

Spieler 1 Spieler 2
linke Bildschirmhälfte rechte Bildschirmhälfte
Steuerung mit Tasten
W (Stein drehen),
A (Stein nach links), D (Stein nach rechts),
Linke Shift-Taste (Stein fallenlassen)
Steuerung mit Tasten auf dem Ziffernblock:
8 (Stein drehen),
4 (Stein nach links), 6 (Stein nach rechts),
0 (Stein fallenlassen)

Im Einzelspieler-Modus wird nur Spieler 1 verwendet. 

Platzieren Sie die herunterfallenden Steine so, dass möglichst wenig Lücken im Aufbau entstehen. Sobald eine Zeile vollständig gefüllt ist, wird sie entfernt und Ihnen werden Punkte gutgeschrieben. Wenn Sie durch den Einbau eines einzigen Steins mehrere Zeilen entfernen können, erhalten Sie viel mehr Punkte; bis zu vier gleichzeitig entfernte Zeilen sind möglich. Wenn sie k ≥ 2 Zeilen gleichzeitig entfernen, werden im Mehrspielermodus einem Ihrer Gegner k-1 graue Zeilen von unten her ins Spielfeld eingefügt, sobald er den aktuellen Stein platziert hat. Sie verlieren, wenn der nächste Stein nicht mehr ins Feld eingefügt werden kann.

Tip: Soundausgabe ist für den ultimativen Spielgenuß von Tetris unverzichtbar.

Implementierung

Alle Informationen über die teilnehmenden Spieler werden in einer NetPlayer-Datenstruktur (für Netzwerkspieler) bzw. einer erweiterten Player-Datenstruktur (für lokale Spieler, diese beinhaltet den kompletten Zustand des Felds) gespeichert. Diese sind in tdecl.hl deklariert. Da die Anzahl der Spieler variieren kann (bis zu 8 Spieler werden unterstützt), werden im globalen players-Array jeweils nur Zeiger auf das entsprechende, dynamisch alloziierte Objekt gespeichert.

In tdecl.hl werden auch alle verfügbaren Steine (const STONES[]) deklariert. Diese werden im nativen Textmodusformat (Vordergrund-, Hintergrundfarbe und Zeichen) gespeichert. Dabei werden Sonderzeichen für die abgerundeten Ecken verwendet (const SCHARS[]), die beim Start mittels gfx_loadchars() in die Hardware-Zeichentabelle der XGfx geladen werden. Zu beachten ist, dass pro Tetris-Feld jeweils 2x2 Textmodus-Zeichen verwendet werden. Hierdurch wird der Bildschirm besser ausgenutzt, außerdem können somit die Steine durch Abrundungen verschönert werden.

Die Verarbeitung lokaler Ereignisse findet in tevents.hl statt. Die beim System als Tastaturhandler registrierte Funktion on_key() behandelt die durch den Anwender gedrückten Tasten, der Timer on_game_timer() treibt das Spiel vorwärts, indem die Steine jeweils eine Zeile nach unten geschoben werden. Dies führt evtl. zum Aufsetzen des Steins, falls dieser auf der neuen Position im Inneren existierender Steine landen würde (hit_test() in tgame.hl). Der Timer on_anim_timer() wird nur zur Blinkanimation beim Entfernen von Zeilen verwendet. 

Wenn ein Stein aufsetzt (hitting_ground()), wird er in das Feld eingefügt und dann überprüft, ob Zeilen zu entfernen sind (check_lines()). Dabei muss der Punktestand aktualisiert werden und evtl. mit push_lines() Zeilen an den nächsten Spieler weitergegeben werden. Außerdem wird mit new_stone() ein neuer Stein zufällig gewählt und im "Next stone"-Fenster angezeigt; der aktuell nächste Stein wird nun im Feld platziert. Falls er dort keinen Platz mehr hat (hit_test()), wird das Spiel beendet.

In der Datei tnet.hl wird die Netzwerkfunktionalität implementiert. Hierbei wird zwischen Server und Client unterschieden. Im gesamten Netzwerk sollte es genau einen Server geben, bis zu drei Clients werden unterstützt (mit jeweils einem oder zwei lokalen Spielern). Der Server wartet zu Beginn auf Client-Anmeldungen, gleichzeitig können sich dort die lokalen Spieler bereits einloggen.
Beim Starten eines Client-Systems versendet dieses zunächst eine Anmeldenachricht, in der die Spiel-ID (1 für Tetris) und die Anzahl der lokalen Spieler übermittelt wird. Diese Message wird periodisch alle drei Sekunden an jedes angeschlossene System verschickt (Broadcast), und zwar so lange, bis der Client eine Anmeldebestätigung vom Server erhält. Durch diese Bestätigung bezieht der Client gleichzeitig die Netzwerkadresse des Servers.
Nun können sich auch die Spieler auf dem Client-System einloggen. Der Server kann das Spiel erst dann starten, wenn sich alle Spieler mit ihrem Namen angemeldet haben. Dazu wird für jeden lokalen Spieler eine Player-Anmeldung, die nur den Namen beinhaltet, an den Server geschickt. Der Name wird anschließend vom Server überprüft, kein Name darf zweimal vorkommen. Der Server sendet entweder eine Bestätigung oder eine Fehlermeldung. Bei Erhalt der Fehlermeldung hat der betroffene Spieler die Möglichkeit, einen anderen Namen zu wählen. Bei einer Bestätigung wird entweder mit dem nächsten Spieler fortgefahren oder auf das Startsignal gewartet. Die Bestätigungsnachricht enthält neben der Server-PlayerID (ID des Spielers auf dem Server, alle weiteren spielerbezogenen Nachrichten benutzen diese ID) auch die PlayerID und Netzwerkadresse des Nachfolgers. Der Nachfolger ist derjenige Spieler, der während des Spiels die von diesem Spieler abgebauten Zeilen erhält.
Insgesamt muss ein logischer Ring von Spielern aufgebaut werden. Damit auch die Vorgänger in dieser Liste bekannt sind, erhält jeder Spieler noch eine PREDEC_INFO Message, in der wiederum PlayerID und Netzwerkadresse des Vorgängers kodiert sind. Der Vorgänger wird nur für die Anzeige seines Namens benötigt. Schließlich möchte man als Netzwerkspieler schon wissen, von wem die grauen Zeilen immer kommen.
Die Spielernamen werden in separaten Nachrichten übermittelt. Bei einer erfolgreichen Spieleranmeldung wird sein Name sofort an alle Clients weitergegeben, damit diese ihre Playerliste aktualisieren können (siehe Setup-Screen oben).
Sobald nun jeder Spieler eingeloggt ist und die Spielerinformationen an alle Clients weitergereicht wurden, kann das Spiel beginnen. Der Server sendet dazu eine Start-Message mit einem Initialwert für den Zufallszahlengenerator an alle Clients (per Broadcast). Dieser Initialwert ist erforderlich, damit alle Spieler die gleichen Chancen haben; jeder Mitspieler erhält die gleichen Steine.
Während des Spiels werden lediglich PUSH_LINE Nachrichten mit der entsprechenden Zeilenanzahl an die Nachfolger verschickt.
Das Spiel endet, wenn ein Spieler den nächsten Stein nicht mehr unterbringen kann. Daraufhin wird eine GAMEOVER Message mit der PlayerID des Verlierers an alle Teilnehmer gesendet. Anschließend werden die Ergebnisse (Level, Lines, Score) ausgetauscht. Die Teilnehmer übermitteln diese sofort nach Erhalt der GAMEOVER Nachricht per Broadcast. Nachdem die Ergebnisse eingesehen wurden, werden die Spieler gefragt, ob sie das Spiel wiederholen möchten. Die Antwort (Ja/Nein) wird an den Server gesendet. Fall jeder mit Ja abgestimmt hat, wird das Spiel sofort wiederholt, ohne erneut die Spielerinformationen auszutauschen. Ansonsten wird die Netzwerkverbindung beendet.
 
rrobek.de Hauptseite
 
Valid HTML 4.01!