Freitag, 18. November 2005

SDLDuel

Splash

Seit einigen Tagen arbeite ich an einem Remake meines ersten selbst geproggten Computerspiels namens "SDLDuel". Obwohl im Original die objektorientierte Programmiersprache C++ verwendet wurde, habe ich versucht mich bei der neuen Version auf die Programmierung im prozeduralen Vorgänger C zu beschränken. Dies hatte den Grund darin, dass viele aus meiner Sicht interessante Quelltexte in C geschrieben sind, und es für jemanden, der bisher nur in C++ programmiert hat, schwieriger ist sich in reine C-Codes hinein zu denken, als wenn man schon ein bisschen Erfahrung im Umgang der Funktionsbibliotheken von C und Techniken der prozeduralen Programmierung hat.

InGame2

Jedenfalls bin ich mit dem momentanen Ergebnis relativ zufrieden. So besitzt das Spiel eine in-game Konsole, mit welcher man diverse Befehle in der Laufzeit aufrufen kann und beliebig an Variablen rumstellen kann, um so für mehr Kurzweil in den Spielrunden zu sorgen. Auch gibt es nun Powerups und Hindernisse, welche das ganze dann doch nicht mehr so langweilig wie im Original machen.

Was Eingabegeräte betrifft, so kann man das Spiel entweder über Tastatur, Maus oder Joystick (bzw. Gamepad) steuern. Theoretisch ist es sogar möglich, dass sich beide Spieler per Gamepad bekämpfen. Weiss aber nicht, ob das wohl wirklich mehr Spaß macht...

Source under code blocks

Hat man nicht sofort einen menschlichen Gegenspieler zur Hand, so kann man auch gegen einen Bot antreten, welcher derzeit aber leider noch nicht so perfekt ist, da gibt es noch Bedarf für Verbesserungen.

Hier kann man sich eine aktuelle Version des Spiels downloaden.

Montag, 7. November 2005

Quake 4 - Wirklich so schlecht?

Nun ist es schon ein paar Wochen her, dass der neue Teil der Quake-Serie in den Vereinigten Staaten von Amerika veröffentlicht wurde. Daher kann man mittlerweile die anfängliche vorhandene Euphorie vergessen und etwas objektiver über diesen Shooter schreiben.

Im Vergleich zum Vorgänger Quake 3 Arena ist in diesem Spiel so einiges anders. Denn dieser Teil stammt nun nicht mehr von Id Software sondern von Raven Software. Da letzteres Unternehmen aber schon mehrere erfolgreiche Spiele (Star Trek - Elite Force, Return to Castle Wolfenstein) auf der Basis einer Engine aus dem Hause Id Software geschaffen hat, dürfte das wohl niemanden stark negativ auffallen.

Weiterhin verfügt dieser Quake-Teil wieder über einen Einzelspieler-Modus, welcher ja bekanntlich im dritten Teil der Serie nicht wirklich vorhanden war. Der Einzelspieler-Modus hängt sich hierbei von der Story direkt an das Ende von Quake 2 an, sodass einem auch die Gegner, also diese Alien-Rasse "Strogg", recht bekannt vorkommen, so man den zweiten Teil schon gespielt hat.

Was neben den abwechslungsreicheren Leveln im Singleplayer im Vergleich zu Doom 3 auch noch auffällt, sind die steuerbaren Gefährte. So kann der Spieler in Quake 4 nämlich in einen Cyborg, Panzer und Schussturm rein schlüpfen und von dort leicht einige Gegner platt machen. Auch heitern Waffenupdates und Interaktion mit Kameraden den Spielverlauf im Einzelspieler sehr auf.

Was den Multiplayer-Modus betrifft lehnt sich der Shooter sehr an Quake 3 Arena an. Jedoch ist die Auswahl an Leveln und Spieler-Models sehr gering im Vergleich zum Vorgänger, doch das dürfte nicht großartig verwundern, bedenkt man, dass es sich nicht um einen reinen Mehrspieler-FPS bei Q4 handelt. Interessant sind einige Remakes unter den Multiplayer-Leveln, darunter mit q3dm17 und q2dm1 sehr beliebte Karten aus den Vorgängern.

Auch gibt es neben dem normalen CTF-Modus (Capture the Flag) auch noch einen CTF-Arena-Modus, welcher große Ähnlichkeiten zum Q3A-Addon Team Arena besitzt. In diesem Modus kann man nämlich nach dem Spawnen einmal ein Powerup aufsammeln, welches einen dann in eine bestimmte "Klasse" bis zum nächsten Death einordnet. Wenn man beispielsweise "Scout" aufsammelt, so wird man zu einer Art Pionier und kann schneller laufen, ist jedoch sonst nicht stärker. Mit "Guard" ist man mehr auf das beschützen der eigenen Base spezialisiert und die eigene Lebensenergie lädt sich automatisch wieder auf. Durch diese und weitere Powerups kann man in verschiedene Rollen mit den jeweiligen Stärken schlüpfen und so gewinnen bestimmte Taktiken und richtiges Teamplay mehr Bedeutung.

Insgesamt ist Quake 4 aus meiner Sicht sehr gelungen. Der Einzelspieler-Modus ist abwechslungsreicher als in Doom 3 und auch nicht mehr so dunkel, da man glücklicherweise die Taschenlampe auch in Kombination mit manchen Waffen verwenden kann. Der Multiplayer ist natürlich kein Quake 3 Arena und die geringe Anzahl an Leveln und Player-Models sorgen schon schnell für langeweile, doch wird dieses Problem in nicht all zu ferner Zukunft sicherlich durch Custom-Maps und Models aus dem Netz gelöst werden. Sieht man nämlich einmal von dem Mangel an Auswahl ab, ist das Gameplay aus meiner Sicht sehr gelungen. Bei weitem nicht so schlimm, wie bei Doom 3.

Morgen leider Musik-Klausur

Derzeitiges Thema in Musik: Liedanalyse. Ist ähnlich wie eine Textanalyse, aber nicht so schön. So soll die Liedanalyse nämlich aufgebaut sein:
  1. Einleitung: Nennung von Liedname, Autor und wenn die Möglichkeit besteht das betrachtete Lied in das übergeordnete Werk einordnen oder auch das Alter des Autors bei der Schaffung des Liedes wiedergeben, das kommt ganz auf das Vorwissen zum Lied an. Dann knappe Inhaltsangabe zum Liedtext und die Tonart nennen. Falls es sich um die Vertonung eines Gedichts handelt, dann dieses samt Autor nennen.
  2. Zum Text: Zuerst grundlegende Informationen über die Struktur des Textes: Versmaß, Reimform, männlicher oder weiblicher Schluss? Darauf vermittelte Stimmung (fröhlich, traurig...) und detaillierte Wiedergabe des Inhalts.
  3. Zur Musik: Übergeordnetes und musikalische Form kennzeichnen. Auf Unterschiede zum ursprünglichen Gedicht hinweisen. Achja, dabei Sequenz, Phrase, Gegenphrase, Motiv, Thema, Periode und weitere Fachbegriffe jeweils mindestens 1x oder besser gar 2x hinschreiben.
Also eine ganz schöne Arbeit. Bin gespannt wie das innerhalb der zwei Schulstunden (45min*2+5min=95min), in welchen man diese Klausur schreibt, klappt.

Donnerstag, 27. Oktober 2005

Java

Ich kenne nicht viele Leute, welche ein anderes Betriebssystem als Microsoft Windows auf ihrem Computer installiert haben. Dennoch habe ich mich früher sehr viel mit Linux beschäftigt und es auch eine Zeit lang als einziges OS auf meiner Platte gehabt. Jedoch arbeite ich nun seit längerer Zeit so ziemlich ausschließlich mit Windows, da es einfach keine gleichwertige Alternative zu Microsoft's Visual C++ gibt und auch nur die wenigsten Spiele ohne Geschwindigkeitseinbußen auf anderen Betriebssystemen als Windows zum Laufen gebracht werden können.

Von daher besteht für mich nicht wirklich der Anspruch portable Spiele zu entwickeln, schon allein weil der Großteil der Zocker, also die Zielgruppe, mit Microsoft Windows PCs arbeitet. Dennoch habe ich die meisten meiner Spiele unter Verwendung einer portablen Bibliothek für C, nämlich dem Simple DirectMedia Layer, programmiert. Zwar hatte ich gerade aus der Überlegung meine Spiele möglichst leicht auf andere Systeme zu portieren damals mit der Einarbeitung in diese Funktionsbibliothek begonnen, jedoch war mir später primär die Einfachheit in der Benutzung dieser wichtig geworden. Natürlich bietet DirectX in einigen Bereichen mehr und da ich es wie gesagt nicht unbedingt portabel haben muss, wäre es eigentlich die bessere Alternative. Wäre es nicht so kompliziert in Relation zur SDL, denn wenn man sich einmal in DirectX einarbeiten will, muss man eine ganze Menge dazu lernen. Schon allein weil DirectX im besten Fall auf der WinAPI aufgelegt wird. Das heißt wer bis dato immer Konsolenanwendungen geschrieben hatte, muss noch einiges dazu lernen, was die Programmierung mit der WinAPI betrifft. Die stdlib aus C ist dagegen schon ein Winzling.

Warum wird es jetzt aber um Java gehen, obwohl ich eine portable Library nur aufgrund der Einfachheit der unportablen Alternative vorziehe? Naja erstmal ist die Portablität von Java zwar eines der bezeichnendsten Eigenschaften, doch ist die Sprachstruktur an sich für einen Programmierer viel interessanter. Was ich damit ausdrücken will, ist dass Java mich naturgemäß auch wegen der Portablität (z.B. auf Mobiltelefone) reizt, jedoch eben nicht hauptsächlich.

Wenn man von einer anderen objektorientierten Programmiersprache wie C++ kommt, so fallen einem einige Dinge stark auf:

Java unterstützt keine Mehrfachvererbung und bietet stattdessen sogenannte Interfaces. Interfaces selbst sind eine Art Klassen, von welchen jedoch kein Objekt instantiiert werden kann und welche auch keine eigentlichen Methodendefinitionen enthalten. Vielmehr befinden sich in Interfaces nur die Köpfe von Methoden, sodass eine Klasse, welches dieses Interface implementiert, sich nur an den Aufbau der im Interface definierten Methodenköpfe zu halten hat.

Der nächste bedeutende Unterschied ist die Speicherverwaltung. In C/C++ konnte dies nämlich vom Programmierer selbst unter Verwendung sogenannte Pointer (Zeiger) getan werden, d.h. er konnte selbstständig Speicher für sein Programm in Anspruch nehmen (allokieren) und ihn auch allein wieder freigeben (deallokieren). In Java ist dies nicht möglich. Hier läuft im Hintergrund ein sogenannter Garbage-Collector (Müllsammler). Dieser schaut im Programm nach nicht mehr referenzierten Variablen und löscht sie dann. So kann der Programmierer zwar weiterhin Speicher anfordern, freigegeben wird dieser aber nur vom Garbage-Collector. Auf diese Weise werden mögliche Memory-Leaks (Speicherlücken) vermieden, welche entstehen, wenn man angeforderten Speicher nachher nicht wieder freigibt. Auch gibt der Garbage-Collector den Speicher nicht frei, wenn im Programm noch später auf ihn zugegriffen wird, sondern erst wenn alle Zugriffe abgeschlossen sind. Bei einem unachtsamen Programmierer kann es vor allem bei größeren Projekten passieren, dass er eben zu früh noch benötigten Speicher freigibt und dadurch auch allerhand von schwerwiegenden Fehlern bei der Ausführung verursachen kann.

Wo wir gerade bei Fehlern sind, so ist Java auch was die Behandlung von Ausnahmesituationen (ziemliches Synonym für Fehlerbehandlung, außer dass in Java richtige Fehler meist zum Absturz einer Anwendung führen, während Ausnahmen noch abgefangen werden können) betrifft viel strenger als C++. Befindet sich beispielsweise in einer Funktion problematischer Code, welcher zu solchen Ausnahmesituation führen kann, ist diese Funktion so gekennzeichnet, dass man den Aufruf immer in ein "try-catch"-Konstrukt packen muss, wenn man die Exceptions der eigenen Funktion nicht noch an eine Aufrufende weiterleitet. Dadurch wird sichergestellt, dass auf Ausnahmesituationen immer vom Programmierer reagiert werden muss. Eine Anwendung die auf alle möglichen Ausnahmesituationen passend reagiert ist natürlich auch dem Benutzer am liebsten.

Vorerst am schmerzhaftesten fällt einem dann noch das Fehlen von Präprozessor-Anweisungen auf. In Java gibt es weder ein #include noch die geliebten Macros, welche vor allem bei C-Programmieren massiv verwendet wurden, in C++ aber stark den inline Funktionen wichen. Betrachtet man das Fehlen der include-Anweisung, so liegt das am Aufbau von Java. In Java gibt es zwar keine Namespaces (Namensräume) wie in C++, jedoch liegen die Klassen alle in einem verschachtelten System von Packages (Paketen), welche den Namensräumen sehr ähneln. Da man prinzipiell Global auf alle öffentlichen Klassen in deren Packages zugreifen kann, brauch man sie also nicht erst durch eine include-Anweisung aus einer Headerdatei in den Quelltext kopieren. Vielmehr wird hier eine import-Anweisung verwendet. Diese macht nichts anderes, als den Zugriff auf Klassen zu vereinfachen. Normalerweise muss nämlich die gesamte übergeordnete Struktur von Packages, welche die gewünschte Klasse beinhalten, beim Zugriff angegeben werden. Importiert man aber z.B. das java.awt.-Package, so kann man auf jede ihrer öffentlichen Klassen einfach durch Nennung des Namens zugreifen, ohne ein langes Prefix, welches in diesem Beispiel java.awt. wäre.

Das waren erstmal die größten Unterschiede zu C++. Weitere Ausführungen über Java werden sicher folgen, spätestens wenn ich mein erstes Game als Java-Applet fertiggestellt habe.

Raycasting

Da ich mich in diesen Herbstferien mal etwas mit 3D-Programmierung beschäftigen wollte, suchte ich nach einer Möglichkeit nicht nur mit Objekten im 3D-Raum zu rechnen, wie es z.B. bei der Verwendung von OpenGL der Fall ist, sondern diese selbst in ein 2D-Bild mit bestimmter Perspektive umzuwandeln, sie quasi eigens zu zeichnen. Gefunden habe ich das Raycasting, die wohl einfachste Technik dies zu bewerkstelligen.

Beim Raycasting ist die eigentliche Welt auf einer 2D-Karte gespeichert, d.h. ein Gegenstand in dieser Welt besitzt nur 2-Koordinaten und nicht 3, wie es bei einer normalen 3D-Welt der Fall wäre. Üblicherweise stellt man diese 2D-Karte beim Programmieren in C als ein 2D-Array dar, in welchem Nullen für leeren Raum und höhere Ganzzahlen für solide Blöcke mit bestimmter Farbe bzw. Textur stehen. Die Perspektive selbst in dieser 2D-Karte wird durch die Position (mittels der zwei Koordinaten) und einen Sichtwinkel definiert.

Will man nun ein 2D-Abbild aus einer festgelegten Perspektive in dieser Welt zeichnen, so werden durch das gesamte Sichtfeld (FOV) für jede Bildschirmspalte Strahlen geschickt, deren Länge bis zum Aufprall auf eine Wand eines Blockes in der Welt bestimmt wird. Anhand dieser Distanz vom Lage der Perspektive zur Wand wird dann in der jeweiligen Bildschirmspalte ein vertikaler Strich von passender Farbe und Höhe gezeichnet.

Wenn man vor diesem Prozess noch den oberen und unteren Bildschirmteil mit einer bestimmten Farbe füllt, um so eine einfarbige Decke bzw. einen einfarbigen Untergrund darzustellen, erhält man ein Bild, welches in etwa so aussehen könnte:
untexturierter raycaster
Hinweis: Beim Raycaster auf dem Screenshot werden die auf der 2D-Karte vertikal liegenden Wände von Blöcken dunkler gezeichnet.

Bei der Texturierung ist der einzige Unterschied, dass nicht eine Farbe pro vertikalen Strich gezeichnet wird, sondern vertikal herunter die Farben für die Pixel aus einer Textur genommen werden. Die x-Koordinate dieser Farben wird dabei aus dem Abstand (Offset) des Ortes, wo der Strahl auftrifft, zum Anfangspunkt der jeweiligen Wand bestimmt. Bei den y-Koordinaten bleibt noch zu beachten, dass bei sehr nahen Wänden einige Pixel der Textur zur Vergrößerung mehrfach gezeichnet werden müssen und bei sehr weit entfernten Wänden einige Pixel einfach übersprungen werden. Das funktioniert aber relativ einfach, wenn man die Schrittweite in der vertikalen Richtung durch die Textur beim Zeichnen der Pixel des vertikalen Streifens dem Verhältnis von Höhe des Streifens zur Texturhöhe anpasst.

Das Ergebnis eines solchen texturierten Raycasters sieht dann so aus:
texturierter raycaster

Wer sich für den Quelltext eines solchen Raycasters interessiert oder ihn einmal in Aktion sehen möchte, kann sich ihn ja von meiner Homepage herunterladen.

User Status

Du bist nicht angemeldet.

Aktuelle Beiträge

SDLDuel
Seit einigen Tagen arbeite ich an einem Remake meines...
andreschnabel - 18. Nov, 22:06
Quake 4 - Wirklich so...
Nun ist es schon ein paar Wochen her, dass der neue...
andreschnabel - 7. Nov, 14:30
Morgen leider Musik-Klausur
Derzeitiges Thema in Musik: Liedanalyse. Ist ähnlich...
andreschnabel - 7. Nov, 13:58
Java
Ich kenne nicht viele Leute, welche ein anderes Betriebssystem...
andreschnabel - 27. Okt, 19:51
Raycasting
Da ich mich in diesen Herbstferien mal etwas mit 3D-Programmierung...
andreschnabel - 27. Okt, 18:55

Suche

 

Status

Online seit 6776 Tagen
Zuletzt aktualisiert: 18. Nov, 22:06

Credits


Programmierung
Schulisches
Spiele
Profil
Abmelden
Weblog abonnieren