01
von 05
Einführung in die Tutorials zur Spieleprogrammierung
Dies ist das erste von mehreren Tutorials zum Programmieren von Spielen in C für Anfänger. Anstatt sich auf das Unterrichten von C zu konzentrieren und dann Beispielprogramme zu zeigen, unterrichten sie C, indem sie Ihnen vollständige Programme (dh Spiele) in C zur Verfügung stellen
Einfach halten
Das erste Spiel in der Serie ist eine Konsole (d. H. Ein textbasiertes Spiel namens Star Empires). Star Empires ist ein einfaches Spiel, in dem Sie alle 10 Systeme in der Galaxie erfassen müssen, während Sie Ihren KI-Gegner daran hindern, dasselbe zu tun.
Sie beginnen, System 0 zu besitzen, während Ihr Feind System 9 besitzt. Die verbleibenden acht Systeme (1-8) starten alle neutral. Alle Systeme beginnen innerhalb eines Quadrats von 5 Parsec x 5 Parsec, sodass kein System mehr als 6 Parsec voneinander entfernt ist. Die am weitesten entfernten zwei Punkte sind (0,0) und (4,4). Nach dem Satz von Pythagoras ist der weiteste Abstand zwischen zwei Systemen die Quadratwurzel ((4)).
2 + (4)2) das ist die Quadratwurzel von 32, die ungefähr 5.657 ist.Bitte beachten Sie, dass dies nicht die endgültige Version ist und geändert wird. Letzte Änderung: 21. August 2011.
Rundenbasiert und in Echtzeit
Das Spiel ist rundenbasiert und in jeder Runde befehlen Sie, eine beliebige Anzahl von Flotten von einem beliebigen System auf ein anderes System zu verschieben. Wenn Sie mehr als ein System besitzen, können Sie Flotten anweisen, von all Ihren Systemen zum Zielsystem zu wechseln. Dies erfolgt anteilig aufgerundet, wenn Sie drei Systeme (1,2,3) mit 20, 10 und 5 vorhandenen Flotten besitzen und Sie bestellen 10 Flotten, um zu System 4 zu gelangen, dann gehen 6 von System 1, 3 von System 2 und 1 von System 3. Jede Flotte bewegt sich 1 Parsec pro Runde.
Jede Runde dauert 5 Sekunden, obwohl Sie die Geschwindigkeit ändern können, um sie zu beschleunigen oder zu verlangsamen, indem Sie die 5 in dieser Codezeile auf 3 oder 7 oder was auch immer Sie wählen, ändern. Suchen Sie nach dieser Codezeile:
Onesec = clock () + (5 * CLOCKS_PER_SEC);
C Programmier-Tutorial
Dieses Spiel wurde programmiert und setzt voraus, dass Sie keine C-Programmierung kennen. Ich werde C-Programmierfunktionen in diesem und den nächsten zwei oder drei Tutorials vorstellen, während sie fortschreiten. Zunächst benötigen Sie jedoch einen Compiler für Windows. Hier sind zwei kostenlose:
- Versuchen CC386
- Oder Visual C ++ 2010 Express
Der Artikel CC386 führt Sie durch die Erstellung eines Projekts. Wenn Sie diesen Compiler installieren, müssen Sie lediglich das Hello World-Programm wie beschrieben laden, den Quellcode kopieren und über das Beispiel einfügen, speichern und dann F7 drücken, um ihn zu kompilieren und auszuführen. Ebenso erstellt der Visual C ++ 2010-Artikel ein Hallo-Welt-Programm. Überschreiben Sie es und drücken Sie F7, um Star Empires zu erstellen. F5, um es auszuführen.
Auf der nächsten Seite - Star Empires funktionieren lassen
02
von 05
Star Empires zum Laufen bringen
Star Empires zum Laufen bringen
Wir müssen Informationen auf Flotten und Systemen im Spiel speichern. Eine Flotte besteht aus einem oder mehreren Schiffen mit dem Befehl, von einem System zum anderen zu wechseln. Ein Sternensystem besteht aus mehreren Planeten, ist jedoch in diesem Spiel eher eine abstrakte Einheit. Wir müssen die folgenden Informationen für eine Flotte speichern.
- Ursprungssystem (1-10).
- Zielsystem (1-10)
- Wie viele Schiffe (1-viele)
- Dreht sich um anzukommen
- Wessen Flotte ist das? 0 = Spieler, 9 = Feind
Wir werden eine Struktur in C verwenden, um dies zu halten:
Strukturflotte {
int fromsystem;
int tosystem;
int dreht sich;
int flottengröße;
int Eigentümer;
};
Eine Struktur ist eine Sammlung von Daten, in diesem Fall 5 Zahlen, die wir als eine bearbeiten. Jede Nummer hat einen Namen, zB fromsystem, tosystem. Diese Namen sind Variablennamen in C und können Unterstriche wie diese, jedoch keine Leerzeichen enthalten. In C sind Zahlen entweder ganzzahlig; ganze Zahlen wie 2 oder 7 werden als Ints oder Zahlen mit Dezimalteilen wie 2,5 oder 7,3333 bezeichnet und diese werden als Floats bezeichnet. In ganz Star Empires verwenden wir Floats nur einmal. In einem Codestück wird der Abstand zwischen zwei Stellen berechnet. Jede andere Zahl ist ein Int.
Flotte ist also der Name für eine Datenstruktur mit fünf int-Variablen. Das ist für eine Flotte. Wir wissen nicht, wie viele Flotten wir halten müssen, also werden wir mithilfe eines Arrays großzügigen Platz für 100 Personen zuweisen. Stellen Sie sich eine Struktur wie einen Esstisch mit Platz für fünf Personen (Ints) vor. Ein Array ist wie eine lange Reihe von Esstischen. 100 Tische bieten Platz für 100 x 5 Personen.
Wenn wir tatsächlich diese 100 Esstische servieren würden, müssten wir wissen, welcher Tisch welcher ist, und wir tun dies durch Nummerierung. In C nummerieren wir Elemente von Arrays immer beginnend bei 0. Der erste Esstisch (Flotte) ist die Nummer 0, der nächste ist 1 und der letzte ist 99. Ich erinnere mich immer daran, wie viele Esstische dieser Tisch von Anfang an hat. Der erste ist am Start, also ist 0 entlang.
So deklarieren wir die Flotten (dh unsere Esstische).
Flottenflotten strukturieren [100];
Lesen Sie dies von links nach rechts. Strukturflotte bezieht sich auf unsere Struktur, um eine Flotte zu halten. Der Name Flotten ist der Name, den wir allen Flotten geben, und [100] sagt uns, dass die Flottenvariable 100 x Strukturflotten enthält. Jedes int belegt 4 Speicherplätze (Bytes genannt), sodass eine Flotte 20 Bytes und 100 Flotten 2000 Bytes belegt. Es ist immer eine gute Idee zu wissen, wie viel Speicher unser Programm benötigt, um seine Daten zu speichern.
In der Strukturflotte enthält jede der Ints eine Ganzzahl. Diese Nummer wird in 4 Bytes gespeichert und reicht von -2.147.483.647 bis 2.147.483.648. Meistens verwenden wir kleinere Werte. Es gibt zehn Systeme, sodass sowohl fromsystem als auch tosystem die Werte 0 bis 9 enthalten.
Auf der nächsten Seite: Systeme und Zufallszahlen
03
von 05
Über Systeme und Zufallszahlen
Jedes der neutralen Systeme (1-8) startet mit 15 Schiffen (eine Nummer, die ich aus der Luft ausgesucht habe!), Und die anderen beiden (Ihr: System 0 und Ihr Computergegner bei System 9) haben jeweils 50 Schiffe. Mit jeder Runde wird die Anzahl der Schiffe an einem System um 10% erhöht. Wenn Sie sie also nach einer Runde nicht bewegen, werden Ihre 50 zu 55 und jedes der neutralen Systeme hat 16 (15 + 1,5 abgerundet). Beachten Sie, dass die Anzahl der Flotten, die auf ein anderes System umziehen, nicht zunimmt.
Die Anzahl der Schiffe auf diese Weise zu erhöhen mag etwas seltsam erscheinen, aber ich habe es getan, um das Spiel am Laufen zu halten. Anstatt dieses Tutorial mit zu vielen Designentscheidungen zu überladen, habe ich einen separaten Artikel über die Designentscheidungen von Star Empires geschrieben.
Systeme implementieren
Zu Beginn müssen wir alle Systeme generieren und auf die Karte setzen, mit maximal einem System in Jeder Standort. Da sich in unserem 5 x 5-Raster 25 Standorte befinden, werden zehn Systeme und 15 leer sein Standorte. Wir generieren sie mit der Funktion GenMapSystems (), die wir auf der nächsten Seite betrachten werden.
Ein System wird in einer Struktur mit den folgenden 4 Feldern gespeichert, die alle int sind.
Struktursystem {
int x, y;
int numfleets;
int Eigentümer;
};
Die Galaxie (alle 10 Systeme) wird wie bei Flotten in einem anderen Array gespeichert, außer dass wir 10 Systeme haben.
Struktursystemgalaxie [10];
Zufällige Zahlen
Alle Spiele benötigen Zufallszahlen. C hat eine eingebaute Funktion rand (), die ein zufälliges int zurückgibt. Wir können dies in einen Bereich zwingen, indem wir die maximale Anzahl übergeben und den Operator% verwenden. (Modul). Dies ist wie eine Taktarithmetik, außer dass wir anstelle von 12 oder 24 eine int-Zahl mit dem Namen max übergeben.
/ * gibt eine Zahl zwischen 1 und max zurück * /
int Random (int max) {
return (rand ()% max) +1;
}
Dies ist ein Beispiel für eine Funktion, bei der es sich um einen Code handelt, der in einem Container verpackt ist. Die erste Zeile hier, die / * beginnt und * / endet, ist ein Kommentar. Es sagt, was der Code tut, wird aber vom Compiler ignoriert, der die C-Anweisungen liest und sie in Anweisungen konvertiert, die der Computer versteht und sehr schnell ausführen kann.
- Frage mich, was ein Compiler ist? Lesen Was ist ein Compiler? (Artikel)
Eine Funktion ist wie eine mathematische Funktion wie Sin (x). Diese Funktion besteht aus drei Teilen:
int Random (int max)
Das int gibt an, welche Art von Zahl zurückgegeben wird (normalerweise int oder float). Zufällig ist der Name der Funktion und (int max) sagt, dass wir eine int-Zahl übergeben. Wir könnten es so verwenden:
int Würfel;
Würfel = zufällig (6); / * gibt eine Zufallszahl zwischen 1 und 6 zurück * /
Die Linie:
return (rand ()% max) +1;
Auf der nächsten Seite: Generieren einer zufälligen Startkarte
04
von 05
Generieren einer zufälligen Startkarte
Dieser Code unten generiert die Startkarte. Das ist es oben gezeigt.
void GenMapSystems () {
int i, x, y;
für (x = 0; x für (y = 0; y Layout [x] [y] = '';
}
InitSystem (0,0,0,50,0);
InitSystem (9,4,4,50,1);
/ * Finde einen freien Platz für die restlichen 8 Systeme * /
für (i = 1; ich mache {
x = zufällig (5) -1;
y = zufällig (5) -1;
}
while (Layout [x] [y]! = '');
InitSystem (i, x, y, 15, -1);
}
}
Beim Generieren von Systemen werden die Systeme des Spielers und des Gegners (bei 0,0) und (4,4) hinzugefügt und anschließend 8 Systeme an den verbleibenden 23 leeren Stellen zufällig hinzugefügt.
Der Code verwendet drei durch die Zeile definierte int-Variablen
int i, x, y;
Eine Variable ist ein Speicherort im Speicher, der einen int-Wert enthält. Die Variablen x und y enthalten die Koordinaten der Systeme und einen Wert im Bereich von 0 bis 4. Die Variable i wird zum Zählen in Schleifen verwendet.
Um die 8 zufälligen Systeme im 5x5-Raster zu platzieren, müssen wir wissen, ob an einem Standort bereits ein System vorhanden ist, und verhindern, dass ein anderes an demselben Standort platziert wird. Dazu verwenden wir ein einfaches zweidimensionales Array von Zeichen. Der Typ char ist ein anderer Variablentyp in C und enthält ein einzelnes Zeichen wie 'B' oder 'x'.
Grundierung für Datentypen in C.
Der grundlegende Variablentyp in C ist int (ganze Zahlen wie 46), char (ein einzelnes Zeichen wie 'A') und float (zum Halten von Zahlen mit Gleitkomma wie 3,567). Arrays [] dienen zum Speichern von Listen desselben Elements. Also definiert char [5] [5] eine Liste von Listen; eine zweidimensionale Anordnung von Zeichen. Stellen Sie sich das wie 25 Scrabble-Teile vor, die in einem 5 x 5-Raster angeordnet sind.
Jetzt schleifen wir!
Jedes Zeichen wird anfänglich mit zwei for-Anweisungen auf ein Leerzeichen in einer Doppelschleife gesetzt. Eine for-Anweisung besteht aus drei Teilen. Eine Initialisierung, ein Vergleichsteil und ein Änderungsteil.
für (x = 0; x für (y = 0; y Layout [x] [y] = '';
}
- x = 0; Dies ist der Initialisierungsteil.
- x
- x ++. Dies ist der Änderungsteil. Es addiert 1 zu x.
Also (für (x = 0; x
Innerhalb der for (x-Schleife befindet sich eine for y-Schleife, die dasselbe für y tut. Diese y-Schleife tritt für jeden Wert von X auf. Wenn X 0 ist, wird Y von 0 bis 4 wiederholt, wenn X 1 ist, wird Y wiederholt und so weiter. Dies bedeutet, dass jede der 25 Positionen im Layout-Array mit einem Leerzeichen initialisiert wird.
Nach der for-Schleife wird die Funktion InitSystem mit fünf int-Parametern aufgerufen. Eine Funktion muss vor dem Aufruf definiert werden, sonst weiß der Compiler nicht, wie viele Parameter sie haben soll. InitSystem hat diese fünf Parameter.
Auf der nächsten Seite: Das Erstellen einer zufälligen Startkarte wird fortgesetzt ...
05
von 05
Das Generieren einer zufälligen Startkarte wird fortgesetzt
Dies sind die Parameter für InitSystem.
- Systemindex - ein Wert von 0 bis 9.
- x- und y-Koordinaten des Systems (0-4).
- Anzahl Schiffe - wie viele Schiffe gibt es in diesem System.
- Inhaber. Wem gehört ein System? 0 bedeutet der Spieler, 9 bedeutet der Feind.
Die Linie InitSystem (0,0,0,50,0) initialisiert also System 0 an den Positionen x = -0, y = 0 mit 50 Schiffen an Eigentümer 0.
C hat drei Arten von Schleifen, während Schleifen, for-Schleifen und do-Schleifen, und wir verwenden for und do in der Funktion GenMapSystems. Hier müssen wir die restlichen 8 Systeme irgendwo in der Galaxie platzieren.
für (i = 1; ich mache {
x = zufällig (5) -1;
y = zufällig (5) -1;
}
while (Layout [x] [y]! = '');
InitSystem (i, x, y, 15,0);
}
Dieser Code enthält zwei verschachtelte Schleifen. Die äußere Schleife ist eine for-Anweisung, die die Variable i von einem Anfangswert von 1 bis zu einem Endwert von 8 hochzählt. Wir werden i verwenden, um auf das System zu verweisen. Denken Sie daran, dass wir System 0 und 9 bereits initialisiert haben. Jetzt initialisieren wir die Systeme 1-8.
Alles von do {bis while (Layout [x] [y] ist die zweite Schleife. Die Syntax lautet do {Something} while (Bedingung ist wahr); Also weisen wir x und y zufällige Werte zu, wobei jeder Wert im Bereich von 0 bis 4 liegt. Random (5) gibt einen Wert im Bereich von 1 bis 5 zurück. Wenn Sie 1 subtrahieren, erhalten Sie den Bereich 0-4.
Wir möchten nicht zwei Systeme an die gleichen Koordinaten setzen, daher sucht diese Schleife nach einem zufälligen Ort, der ein Leerzeichen enthält. Wenn dort ein System vorhanden ist, ist das Layout [x] [y] kein Leerzeichen. Wenn wir InitSystem aufrufen, wird dort ein anderer Wert angegeben. Übrigens! = Bedeutet ungleich und == bedeutet gleich.
Wenn der Code nach einer Weile das InitSystem erreicht (layout [x] [y]! = ''), Beziehen sich x und y definitiv auf eine Stelle im Layout, die ein Leerzeichen enthält. Wir können also InitSystem aufrufen und dann die for-Schleife umrunden, um einen zufälligen Speicherort für das nächste System zu finden, bis alle 8 Systeme platziert wurden.
Der erste Aufruf von InitSystem richtet System 0 an Position 0,0 (oben links im Raster) mit 50 Flotten ein und wird von mir gewonnen. Der zweite Aufruf initialisiert System 9 an Position 4,4 (unten rechts) mit 50 Flotten und gehört Spieler 1. Wir werden uns im nächsten Tutorial genau ansehen, was InitSystem tatsächlich macht.
#definieren
Diese Zeilen deklarieren Literalwerte. Es ist üblich, sie in Großbuchstaben zu schreiben. Überall dort, wo der Compiler MAXFLEETS sieht, verwendet er den Wert 100. Ändern Sie sie hier und es gilt überall:
- #Breite 80 definieren
- #HÖHE 50 definieren
- #define MAXLEN 4
- # MAXFLEETS 100 definieren
- # MAXSYSTEMS definieren 10
- #define FIGHTMARKER 999
Fazit
In diesem Tutorial haben wir Variablen und die Verwendung von int, char und struct behandelt, um sie zu gruppieren, sowie Array, um eine Liste zu erstellen. Dann einfaches Looping mit for und do. Wenn Sie den Quellcode untersuchen, werden immer wieder dieselben Strukturen angezeigt.
- für (i = 0; i
- für (i = 0; i
Tutorial Wir werden uns die in diesem Tutorial erwähnten Aspekte von C ansehen.