Wir haben einen langen Weg in diesem Anfängerleitfaden zur objektorientierten Programmierung gefunden und die Prinzipien von besprochen Zusammenhalt, Kupplung, Verkapselung, und Abstraktion. In diesem abschließenden Artikel werden wir das OOP-Prinzip von diskutieren Erbe und seine Verwendung in der Spieleentwicklung.
Hinweis: Obwohl dieses Tutorial mit Java geschrieben wurde, sollten Sie in der Lage sein, in fast jeder Spieleentwicklungsumgebung dieselben Techniken und Konzepte anzuwenden.
Vererbung ist das Prinzip der Klassenhierarchie. Es ist die Fähigkeit eines Objekts, die Zustände, Verhalten und Funktionen eines anderen Objekts zu übernehmen.
Ein Beispiel aus der realen Welt der Vererbung ist die genetische Vererbung. Wir erhalten alle Gene von unseren beiden Eltern, die dann definieren, wer wir sind. Wir teilen die Qualitäten unserer beiden Eltern und unterscheiden sich gleichzeitig von ihnen.
Objekte in OOP können dasselbe tun. Übergeordnete Klassen können über untergeordnete Klassen verfügen (auch als Superklassen bzw. Unterklassen bezeichnet), die dieselben Eigenschaften wie die übergeordnete Klasse haben und neue Zustände, Verhalten und eigene Funktionen definieren können.
Betrachten Sie als Beispiel die folgende Klasse, die als übergeordnete Klasse für verschiedene Formen verwendet werden kann:
öffentliche Klasse Shape protected int height; geschützte int breite public Shape (int h, int w) height = h; Breite = w; public int area () return height * width; public int getHeight () return height; public int getWidth () return width; public void setHeight (int h) Höhe zurückgeben; public void setWidth (int w) return width;
Um diese Klasse zu erweitern, um ein Dreieck zu implementieren, würde es folgendermaßen aussehen:
öffentliche Klasse Dreieck erweitert Shape öffentliches Dreieck (int h, int w) super (h, w); public int area () return super.area () / 2;
Dreieck
hat alle die gleichen Zustände und Funktionen wie Gestalten
, aber definiert das neu Bereich()
Funktion, um den richtigen Bereich von a zurückzugeben Dreieck
(halbe Basiszeiten Höhe).
Das Schlüsselwort Super
wird verwendet, um auf die Oberklasse und ihre Zustände und Funktionen zu verweisen. Deshalb können wir verwenden Super()
den Konstruktor der Superklasse aufrufen und super.area ()
anrufen Bereich()
Funktion der Oberklasse. Also in diesem Fall, super.area ()
kehrt zurück Höhe Breite
.
Das geschützt
Schlüsselwort ist der letzte Modifikator für die Zugriffsebene. Es verhält sich wie der Modifikator für private Zugriffsebenen, ermöglicht jedoch auch allen Unterklassen, auf die Variable oder Funktion zuzugreifen.
Wie Sie sehen, kann Vererbung erheblich dazu beitragen, die Code-Redundanz zwischen ähnlichen Objekten zu reduzieren, indem sie die Gemeinsamkeiten dieser Objekte an einen Ort bringt. Dadurch wird auch mehr wartbarer Code erstellt, da er dazu beiträgt, das DRY-Prinzip einzuhalten und den Welligkeitseffekt bei Codeänderungen zu verhindern.
Wenn Ihnen das alles bekannt vorkommt, liegt dies wahrscheinlich daran, dass die Abstraktion sehr ähnliche Vorteile hatte (wie auch die meisten anderen Prinzipien von OOP). Die Abstraktion steht in engem Zusammenhang mit der Vererbung, da eine abstrahierte Klasse als Oberklasse zum Erstellen von Unterklassen verwendet werden kann. Der einzige Unterschied zwischen einer abstrakten Klasse und einer normalen Klasse besteht darin, dass eine abstrakte Klasse nicht zum Erstellen eines Objekts verwendet werden kann.
Kommen wir noch einmal zu unseren drei Spielen zurück, um zu beschreiben, wie Vererbung angewendet wird.
Denken Sie daran, dass wir eine abstrakte Klasse zum Verschieben von Objekten über einen Bildschirm definiert haben. Denken Sie auch daran, dass wir a definiert haben Schiff
Klasse für das Schiffsobjekt. Um Vererbung auf Asteroiden anzuwenden, können wir die Schiff
Klasse erweitern die Beweglich
Klasse wie folgt:
/ ** * Die Schiffsklasse * / public class Schiff erweitert Movable / ** * Funktion zum Drehen des Schiffes * / public void rotate () // Code, der das Schiff dreht / ** * Funktion zum Auslösen von * / public void fire () // Code zum Abfeuern
Der Code, der zum Bewegen des Schiffes benötigt wird, wird in der Beweglich
abstrakte Klasse, so können wir es aus der entfernen Schiff
Klasse. Alle anderen Objekte für Asteroids könnten auch von der übernommen werden Beweglich
Klasse, so dass Sie ganz einfach ändern können, wie ein Objekt verschoben werden soll.
Bei der Vererbung ist die Möglichkeit der Mehrfachvererbung zu beachten oder die Fähigkeit einer Klasse, von mehreren Klassen gleichzeitig zu erben. Einige Sprachen erlauben es, andere nicht.
Java ist eine der Sprachen, die keine Mehrfachvererbung zulassen. Daher können Sie das Ship-Objekt nicht von beiden erben Beweglich
Klasse und a Zeichenbar
Klasse.
Vererbung kann auf Tetris angewendet werden, indem das Tetrimino und alle Visualisierungen des Spiels vom übernommen werden Zeichenbar
Klasse, die wir im letzten Artikel definiert haben.
Erinnern wir uns daran, dass wir für Pac-Man Objekte identifiziert haben: Pac-Man, ein Ghost und ein Pac-Punkt. In dieser ganzen Serie haben wir nur über diese drei Objekte gesprochen und etwas über das letzte kritische Stück Pac-Man gesagt: das Power-Pellet. Mit der Vererbung sind wir jetzt bereit, darüber zu sprechen.
Ein Power-Pellet ist ein spezieller Pac-Punkt, der es Pac-Man erlaubt, Geister zu essen. Die Zustände und Verhaltensweisen sind genau die gleichen wie bei einem Pac-Punkt. Der einzige Unterschied besteht in der Größe und der Fähigkeit zum Blinzeln. Um das Spiel locker zu koppeln, möchten wir, dass eine andere Klasse überwacht, wann ein Pellet gegessen wird aktiv die changeState ()
Methode der Geister). Dies ist, wenn Vererbung nützlich ist.
Da ein Pac-Punkt und ein Power-Pellet praktisch das gleiche Objekt sind, können wir ein PowerPellet
Klasse, die die erweitert PacDot
Klasse. Das PowerPellet
Die Klasse müsste lediglich einige Zustände ändern, um sie größer zu machen, und das Verhalten beim Wachsen und Verkleinern hinzufügen, um einen Blinkeffekt zu erzeugen. Und das ist es - wir haben jetzt ein Kraftpellet mit wenig zusätzlicher Arbeit. Nicht zu schäbig.
Der Code, wie das aussehen würde, könnte folgendermaßen aussehen:
/ ** * Die Pac-Punkt-Klasse * / Public-Klasse PacDot erweitert Drawable protected int size; geschützte int Score public PacDot () Größe = 10; Score = 10; / ** * Gibt den Wert des Pac-Punkts zurück, der dem Spieler beim Verzehr hinzugefügt wird. * / Public int getScore () return score; / ** * Gibt die Größe des pac-dot zurück * / public int getSize () return size; / ** * Die Power Pellet-Klasse * / public-Klasse PowerPellet erweitert PacDot private int sizeModifier; // müssen keine Größe und Bewertung definieren, da diese // bereits in PacDot definiert sind - PowerPellet erbt sie. public PowerPellet () Größe = 20; Score = 50; sizeModifier = -2; / ** * Die Blinkfunktion, die jedes Mal aufgerufen wird, wenn das Power Pellet * gezogen wird. Ändert den sizeModifier, um einen Blinkeffekt zu simulieren * / public void blink () size + = sizeModifier; if (Größe < 10 || size > 20) sizeModifier = -sizeModifier;Es lohnt sich zu erwähnen, dass Sie zur besseren Übersicht über alle unsere Klassen und die Klassenübernahme von Pac-Man ein Klassendiagramm verwenden können, um visuell zu sehen, wie alles zusammenhängt.
Vererbung ist sehr hilfreich bei der Erstellung von wartungsfähigerem Code, da wir ähnliche Objekte erstellen können, ohne den Code zwischen ihnen zu duplizieren. Es hilft auch, organisierten Code zu erstellen, indem Klassenhierarchie angezeigt wird.
Und das ist es! Wir sind jetzt mit der OOP-Serie hier auf Gamedevtuts + fertig. Ich hoffe, Ihnen hat diese Artikel gefallen und sie haben Ihnen geholfen, besser zu verstehen, wie OOP-Prinzipien auf die Spieleentwicklung angewendet werden können. Folgen Sie uns auf Twitter, Facebook oder Google+, um über die neuesten Beiträge auf dem Laufenden zu bleiben.