[Projekt]First Strike - Firestorm (shot em up)
Verfasst: 22.03.2017, 11:44
Dieser Text beschreibt die Entwicklung des Spiels First Strike – Firestorm. Das Spiel nutzt die DirectX7 Schnittstelle von Microsoft und wurde mit Blitz3D entwickelt. Der Autor erhebt keinen Anspruch auf Professionalität oder Vollständigkeit.
Demo
Hier könnt Ihr die Demo-Version runterladen. Über Feedback würde ich mich freuen.
klick hier -> http://gombolo.bplaced.net/Firestorm/
Video
[youtube]JpjCViTxGxg[/youtube]
Einführung
In der Regel lernt man das Programmieren von Spielen am besten wenn man selber ein paar kleine Projekte macht. Üblicherweise sind das Spiele wie Pong, Tetris oder Snake. Die nächste Stufe ist dann ein Shot em up. So war es jedenfalls bei mir.
Die erste Version meines Shot em up wurde noch in C/C++ programmiert. Das Spiel nutzte giDX², eine selbstentwickelte 2D Engine, und war auch nur zum Testen der 2D Engine gedacht.
Vor ein paar Jahren entdeckte ich für mich Blitz3D. Selbstverständlich begann ich mit der Programmierung eines neuen Shot em ups, aber diesmal in 3D. Die Spielmechanik schaute ich mir von einem anderen Spiel ab. Das Spiel nennt sich Cho Ren Sha und kommt aus dem Mutterland der Shot em ups aus Japan.
Den ersten Code für das neue Spiel schrieb ich am 1.5.2011. Nun haben wir das Jahr 2017 und ich möchte das Spiel der Öffentlichkeit vorstellen, aber warum dauert ein Spiel so lange? Nun, das ist eine Angewohnheit von mir. Ich programmiere nur alle paar Jahre mal was und dann kann es auch mal passieren das so ein Spiel ein Jahr lang auf der Festplatte schlummert. Trotzdem denke ich mein Ziel erreicht zu haben. Das Spiel funktioniert :)
Das Grundgerüst
Ich möchte noch einmal daran erinnern dass ich kein Profi bin. Ich möchte nur meine Erfahrung mit euch teilen.
Meine Spiele baue ich immer nach einem bestimmten Schema auf. Es ist dabei nicht wichtig mit welcher Programmiersprache man programmiert. Mir erleichtert es die Handhabung und die Übersicht.
Die Grafik ist ein Versuch das zu verdeutlichen. Wer sich das genauer anschauen will. Kann hier http://gombolo.bplaced.net/quellcodes/ den Quellcode von zwei Spielen runterladen. Die Spiele sind in C/C++ programmiert und nutzen giDX² für die Grafikausgabe, Sound und Input. Es gilt. Theorie ist nichts ohne die Praxis.
Gegner erzeugen und ein eigener Script
Die Gegner und das Verhalten werden in einer eigenen Script-Sprache definiert. Wie es sich bewegt, welche Grafik verwendet wird und welche Art von Waffen der Gegner hat. So auch die Bewegung.
Es gibt eine Datei in der alle Gegnertypen beschrieben sind. Die Levels werden dann aus dieser Liste zusammengebaut. Heute würde ich das anders machen. Ich würde einen Emitter programmieren der eine bestimmte Art von Gegner erzeugt. Wie eine Partikel-Engine. Ich würde nicht jeden Gegner einzeln positionieren, sondern nur den Emitter. Den Rest würde dieser erledigen.
Performance bei so vielen Geschossen
Als ich die erste Version fertig hatte merkte ich dass die FPS schon beim ersten Schuss in den Keller sank. Wenn man mehrere hundert Geschosse und auch noch ein paar Sterne bewegen will stößt man an Grenzen.
Die Rotation und die Bewegung der Objekte rechnet man in DirectX und auch OpenGL mit Rotations- und Transformationsmatrizen. Bevor ein Objekt jetzt gerendert wird, müssen einige Renderstates, die Textur sowie die Rotations- und Transformationsmatrizen gesetzt werden. Hat man mehrere Objekte, muss das für jedes dieser 3D Objekte gemacht werden. In meinem Fall waren es mehrere hunderte.
Die Lösung war es aus diesen hunderten einzelner 3D Objekte eins zu machen. Jedes Geschoss besteht aus einem Quad (Vier Vertices die zu einem Rechteck zusammengefügt werden). Ihr müsst euch die vielen Quads, die im Spiel erstellt werden, als ein einziges Objekt vorstellen. Die Vertices müssen nicht miteinander zusammenhängen. Nur vier Vertices werden zu einem Quad zusammengefügt. Um die Rotation, die Skalierung und Transformation muss man sich selber kümmern.
Der Vorteil ist nun, dass alle Geschosse in einem Rutsch gerendert werden. Denn diese sind für die Grafikkarte nun ein einziges 3D Objekt.
Kollisionsabfrage
Es ist nicht sinnvoll, Objekte die nicht zu sehen sind oder nicht aktiviert auf Kollision zu prüfen. Das Spiel erstellt eine Liste mit allen Objekten die aktiv sind und prüft nur diese auf Kollision. Wir ein Gegner zerstört oder das Geschoss trifft einen Gegner wird es aus dieser Liste gelöscht. Auch das bringt einen Performanceschub.
Demonstration oder wie zeichnet man ein Spiel auf
Wenn man nach dem Start des Spiels ein paar Sekunden wartet erscheint die Highscore-List und noch mal ein paar Sekunden später startet eine Demonstration des Spiels. Es scheint als ob der Computer selber spielt. Was er nicht tut. Das Ganze ist nur eine Aufzeichnung. Ich habe mir lange überlegt wie ich das am besten realisiere. Ich hätte es gerne so gehabt das jedes Spiel aufgezeichnet wird und wieder abgespielt werden kann. Leider habe ich das nicht so sauber hinbekommen, aber die Aufzeichnung funktioniert. Das kann man an der Demonstration sehen. Auch hier bin ich am Ende schlauer als vorher. Ich habe die Aufzeichnung Zeitabhängig gemacht. Heute würde ich die Position speichern und interpolieren, aber nun ist es so wie es ist. Beim nächsten Projekt wird es besser ;)
Zum Schluss
Das war ein kleiner Blick hinter die Kulissen der Entwicklung dieses Spiels. Ideen sind oft nicht so schwer umzusetzen. Im Detail liegen oft die schweren Brocken. Das Thema Optimierung hat viel Nerven gekostet. Und am Ende bin ich wieder etwas schlauer und denke mir heute hätte ich das anders gemacht.
Ich habe auch eine Version von diesem Spiel bei der man den Monitor senkrecht aufstellen muss. Meine Idee war es einen eigenen Spielautomaten zu bauen. Mal sehen wann das fertig wird :)
Demo
Hier könnt Ihr die Demo-Version runterladen. Über Feedback würde ich mich freuen.
klick hier -> http://gombolo.bplaced.net/Firestorm/
Demo
Hier könnt Ihr die Demo-Version runterladen. Über Feedback würde ich mich freuen.
klick hier -> http://gombolo.bplaced.net/Firestorm/
Video
[youtube]JpjCViTxGxg[/youtube]
Einführung
In der Regel lernt man das Programmieren von Spielen am besten wenn man selber ein paar kleine Projekte macht. Üblicherweise sind das Spiele wie Pong, Tetris oder Snake. Die nächste Stufe ist dann ein Shot em up. So war es jedenfalls bei mir.
Die erste Version meines Shot em up wurde noch in C/C++ programmiert. Das Spiel nutzte giDX², eine selbstentwickelte 2D Engine, und war auch nur zum Testen der 2D Engine gedacht.
Vor ein paar Jahren entdeckte ich für mich Blitz3D. Selbstverständlich begann ich mit der Programmierung eines neuen Shot em ups, aber diesmal in 3D. Die Spielmechanik schaute ich mir von einem anderen Spiel ab. Das Spiel nennt sich Cho Ren Sha und kommt aus dem Mutterland der Shot em ups aus Japan.
Den ersten Code für das neue Spiel schrieb ich am 1.5.2011. Nun haben wir das Jahr 2017 und ich möchte das Spiel der Öffentlichkeit vorstellen, aber warum dauert ein Spiel so lange? Nun, das ist eine Angewohnheit von mir. Ich programmiere nur alle paar Jahre mal was und dann kann es auch mal passieren das so ein Spiel ein Jahr lang auf der Festplatte schlummert. Trotzdem denke ich mein Ziel erreicht zu haben. Das Spiel funktioniert :)
Das Grundgerüst
Ich möchte noch einmal daran erinnern dass ich kein Profi bin. Ich möchte nur meine Erfahrung mit euch teilen.
Meine Spiele baue ich immer nach einem bestimmten Schema auf. Es ist dabei nicht wichtig mit welcher Programmiersprache man programmiert. Mir erleichtert es die Handhabung und die Übersicht.
Die Grafik ist ein Versuch das zu verdeutlichen. Wer sich das genauer anschauen will. Kann hier http://gombolo.bplaced.net/quellcodes/ den Quellcode von zwei Spielen runterladen. Die Spiele sind in C/C++ programmiert und nutzen giDX² für die Grafikausgabe, Sound und Input. Es gilt. Theorie ist nichts ohne die Praxis.
Gegner erzeugen und ein eigener Script
Die Gegner und das Verhalten werden in einer eigenen Script-Sprache definiert. Wie es sich bewegt, welche Grafik verwendet wird und welche Art von Waffen der Gegner hat. So auch die Bewegung.
Es gibt eine Datei in der alle Gegnertypen beschrieben sind. Die Levels werden dann aus dieser Liste zusammengebaut. Heute würde ich das anders machen. Ich würde einen Emitter programmieren der eine bestimmte Art von Gegner erzeugt. Wie eine Partikel-Engine. Ich würde nicht jeden Gegner einzeln positionieren, sondern nur den Emitter. Den Rest würde dieser erledigen.
Performance bei so vielen Geschossen
Als ich die erste Version fertig hatte merkte ich dass die FPS schon beim ersten Schuss in den Keller sank. Wenn man mehrere hundert Geschosse und auch noch ein paar Sterne bewegen will stößt man an Grenzen.
Die Rotation und die Bewegung der Objekte rechnet man in DirectX und auch OpenGL mit Rotations- und Transformationsmatrizen. Bevor ein Objekt jetzt gerendert wird, müssen einige Renderstates, die Textur sowie die Rotations- und Transformationsmatrizen gesetzt werden. Hat man mehrere Objekte, muss das für jedes dieser 3D Objekte gemacht werden. In meinem Fall waren es mehrere hunderte.
Die Lösung war es aus diesen hunderten einzelner 3D Objekte eins zu machen. Jedes Geschoss besteht aus einem Quad (Vier Vertices die zu einem Rechteck zusammengefügt werden). Ihr müsst euch die vielen Quads, die im Spiel erstellt werden, als ein einziges Objekt vorstellen. Die Vertices müssen nicht miteinander zusammenhängen. Nur vier Vertices werden zu einem Quad zusammengefügt. Um die Rotation, die Skalierung und Transformation muss man sich selber kümmern.
Der Vorteil ist nun, dass alle Geschosse in einem Rutsch gerendert werden. Denn diese sind für die Grafikkarte nun ein einziges 3D Objekt.
Kollisionsabfrage
Es ist nicht sinnvoll, Objekte die nicht zu sehen sind oder nicht aktiviert auf Kollision zu prüfen. Das Spiel erstellt eine Liste mit allen Objekten die aktiv sind und prüft nur diese auf Kollision. Wir ein Gegner zerstört oder das Geschoss trifft einen Gegner wird es aus dieser Liste gelöscht. Auch das bringt einen Performanceschub.
Demonstration oder wie zeichnet man ein Spiel auf
Wenn man nach dem Start des Spiels ein paar Sekunden wartet erscheint die Highscore-List und noch mal ein paar Sekunden später startet eine Demonstration des Spiels. Es scheint als ob der Computer selber spielt. Was er nicht tut. Das Ganze ist nur eine Aufzeichnung. Ich habe mir lange überlegt wie ich das am besten realisiere. Ich hätte es gerne so gehabt das jedes Spiel aufgezeichnet wird und wieder abgespielt werden kann. Leider habe ich das nicht so sauber hinbekommen, aber die Aufzeichnung funktioniert. Das kann man an der Demonstration sehen. Auch hier bin ich am Ende schlauer als vorher. Ich habe die Aufzeichnung Zeitabhängig gemacht. Heute würde ich die Position speichern und interpolieren, aber nun ist es so wie es ist. Beim nächsten Projekt wird es besser ;)
Zum Schluss
Das war ein kleiner Blick hinter die Kulissen der Entwicklung dieses Spiels. Ideen sind oft nicht so schwer umzusetzen. Im Detail liegen oft die schweren Brocken. Das Thema Optimierung hat viel Nerven gekostet. Und am Ende bin ich wieder etwas schlauer und denke mir heute hätte ich das anders gemacht.
Ich habe auch eine Version von diesem Spiel bei der man den Monitor senkrecht aufstellen muss. Meine Idee war es einen eigenen Spielautomaten zu bauen. Mal sehen wann das fertig wird :)
Demo
Hier könnt Ihr die Demo-Version runterladen. Über Feedback würde ich mich freuen.
klick hier -> http://gombolo.bplaced.net/Firestorm/