Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

20.01.2016, 18:20

Grundlegendes Verständnisproblem bei OOP

Hi,

ich programmiere zur Übung und aus Spaß an einem eigenen Spiel mit Java und libGdx rum und bin dabei auf ein erstaunliches Problem gestoßen:
Ich scheine ein Problem damit zu haben, OOP-Konzepte vernünftig anzuwenden.

Folgende Situation:
Ich habe einen GameScreen, der alle Elemente (Texturen, Kamera usw.) anzeigen soll. Einen Manager, der bisher nur zum Laden der Texturen benutzt wird, wahrscheinlich aber später auch andere Sachen managen soll. Zum Ausprobieren habe ich bisher fast den ganzen Code in der GameScreen Klasse geschrieben, ich möchte diesen jetzt aber in andere Klassen umlagern, der Struktur halber. Und zwar in eine Klasse für den Hauptcharakter (seine Bewegungen und Angriffe), eine für Feinde in der Luft und eine für Feinde am Boden (sobald ein Feind in der Luft abgeschossen wurde, tauchen nach einiger Zeit Gegner am Boden auf).
Ich bekomme allerdings Probleme mit den Zugriffen zwischen den Klassen. Wenn ich beispielsweise beim Hauptcharakter einen Boolean "abgeschossen" habe, möchte ich den in der "Feinde am Boden" Klasse nutzen, um da loszulegen.
Dann kommen allerdings Probleme, weil "abgeschossen" nicht static ist oder ähnliches.

Daher erstmal eine allgemeine Frage, bevor ich dann versuche es umzusetzen und weitere Probleme wohl auch hier posten werde:
Wie würdet ihr die Situation angehen?
Sollte es zum Beispiel vielleicht eine Art "Hauptklasse" geben (könnte hier der Manager sein), der die Variablen die für mehrere Klassen wichtig sind deklariert? Wenn ja, sollte das dann in der main-Methode sein? Wenn nein, was würde dann Sinn machen?

Hoffe auf Anregungen und bedanke mich schonmal :).

DeKugelschieber

Community-Fossil

Beiträge: 2 641

Wohnort: Rheda-Wiedenbrück

Beruf: Software-Entwickler

  • Private Nachricht senden

2

20.01.2016, 18:54

Erstmal hilft es uns und dir selbst die aktuelle Situation zu modelieren. Dafür bietet sich UML an (gutes Tool). Dann siehst du z.B. welche Entität wie mit den anderen in Beziehung steht, und kannst dies evt. ummodelieren.
Abhängigkeiten kann man entweder bei Bedarf an eine Methode übergeben (z.B. den Hauptcharakter an die Gegnerentität), dafür muss sie in einer übergeordneten Klasse bekannt sein (z.B. dein GameScreen), oder aber man gibt sie als Abhängigkeit in den Konstruktor rein, in dem man dann die Referenz innerhalb der Klasse speichert (als Attribut) und darauf zugreifen kann.
Bei deinem Problem würde ich nicht jedem Gegner die Hauptcharakter Referenz mitgeben, also Variante 1 nehmen.

Ganz allgemein ist dieses Buch (kostenlos als HTML) sehr interessant.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

3

20.01.2016, 21:55

Mir ist nicht ganz klar warum eine Variable einer Klasse für die anderen Klassen relevant sein sollte. Mehr Details bitte.
Ganz klar ist aber, dass das wohl nicht in die main-Funktion gehört. Die sollte nicht länger als 20 Zeilen sein - wie eigentlich die meisten Funktionen und Methoden.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Wirago

Alter Hase

Beiträge: 1 193

Wohnort: Stockerau

Beruf: CRM Application Manager

  • Private Nachricht senden

4

21.01.2016, 09:16

Zum Thema OOP hab ich mal ein kleines Tutorial geschrieben. Vielleicht hilft es dir, da ich versucht habe es möglichst einfach zu erklären -> OOP auf kleincodiert.at
Du solltest unbedingt ein tiefes Verständnis der Objektorientierung haben.

Konkret zu deinem Beispiel:
Für Gegner aller Art bietet sich immer eine art "Enemy Klasse" an die dir deine Gegner verwaltet. Eine entsprechende "Player Klasse" wäre dann für deinen Charakter denkbar.
Ob jetzt ein Spieler abgeschossen ist oder nicht beeinflusst in der Regel das ganze Spiel (Game Over), solche Information sollte überall zugänglich sein. Eine statische Player-Klasse ist aber sicher nicht der richtige Weg.

5

21.01.2016, 11:11

Vielleicht hilft es dir, da ich versucht habe es möglichst einfach zu erklären

Danke dafür, die Prinzipien habe ich alle verstanden :). Vielleicht ist also einfach mein Denkansatz für den Aufbau des Spiels falsch.

Erstmal hilft es uns und dir selbst die aktuelle Situation zu modelieren. Dafür bietet sich UML an (gutes Tool). [...] Ganz allgemein ist dieses Buch (kostenlos als HTML) sehr interessant.

Das Buch werde ich mir auf jeden Fall ansehen, danke. Und in das Tool schaue ich heute auch noch rein, um die Ergebnisse hier zu posten.

Mehr Details bitte.

Die versuche ich später mit UML zu geben, aber jetzt erstmal noch in Textform:
Wenn ich verschiedene Klassen habe (Spieler, Gegner etc.), dann beeinflussen sich diese Klassen natürlich gegenseitig. In meinem Beispiel also etwa wenn der Spieler ("Spieler-Klasse") Gegner 1 ("Gegner in der Luft"-Klasse) abschießt, dann soll Gegner 2 ("Gegner-am-Boden"-Klasse) spawnen. Mein Ansatz wäre jetzt, das erstmal ganz simpel über eine boolean zu regeln. Aber vielleicht ist das keine gute Lösung?

6

21.01.2016, 15:49

So, ich habe jetzt mal ein UML-Diagramm erstellt (allerdings mit Violet, weil ich damit besser zurecht kam).


(Link)


Vielleicht noch ein paar Informationen, die man haben sollte:
  • Das ScreenInterface ist von libGdx und stellt hauptsächlich Methoden zur Verfügung, die die Handhabung von einzelnen Bildschirmen vereinfacht, also zum Beispiel rendern etc.
  • Beim Start des Spiels erscheint der SplashScreen, während alle Texturen geladen werden. Dann geht es über zum GameScreen.
  • Auch von libGdx ist der Manager, der hier einmal alle Texturen lädt, um möglichst effizient mit Speicher umzugehen.
  • In dieser Aufteilung ist der Manager aber auch die übergeordnete Klasse, die den Wechsel zwischen den Screens managed oder das Spawnen von Aliens erlaubt, nachdem das UFO abgeschossen wurde.
  • Da die Gegner alle ein paar gemeinsame Eigenschaften haben, habe ich eine Oberklasse erstellt. Die zwei Unterklassen davon teilen die Gegner in fliegende (oberer Teil des Bildschirms) und laufende (unterer Teil) auf. Darauf werden dann die einzelnen Gegner Klassen folgen. Da die ersten Gegner sich aber nur bewegen können, sind deren Klassen noch trivial.
Macht diese Aufteilung so Sinn? Auch was die Pakete angeht?

Nimelrian

Alter Hase

Beiträge: 1 216

Beruf: Softwareentwickler (aktuell Web/Node); Freiberuflicher Google Proxy

  • Private Nachricht senden

7

21.01.2016, 16:56

Dein "Manager" ist eine Godclass. Wieso erbt FirstUFO von UFOs? Wieso benennst du eine Klasse mit einem Plural?
Ich bin kein UserSideGoogleProxy. Und nein, dieses Forum ist kein UserSideGoogleProxyAbstractFactorySingleton.

8

21.01.2016, 17:06

Aha, habe gerade ergoogelt, dass Godclass gar nicht mal so gut ist. Aber wie gehe ich die Aufteilung dann an?
UFOs ist im Plural, weil es verschiedene Typen davon geben wird. Da diese alle die Gemeinsamkeit haben, dass sie oberhalb des Spielers sind, habe ich diesen Gegnern eine eigene Klasse zugewiesen (das ist auch das, was FirstUFO von UFOs erbt). Natürlich kann ich die Klasse auch einfach UFO nennen.

Sylence

Community-Fossil

Beiträge: 1 663

Beruf: Softwareentwickler

  • Private Nachricht senden

9

21.01.2016, 17:19

Vererbung ist immer eine "ist-ein" Beziehung. Ist ein FirstUFO ein UFOs?

Auch hilfreich ist es, sich an das Single-Responsibility-Prinzipzu halten

10

21.01.2016, 18:01

So wie du es schreibst, klingt es wirklich doof, also wird die Klasse UFO genannt. Und ja, FirstUFO ist natürlich ein UFO :).
Das Prinzip kannte ich so nicht, klingt aber durchaus sinnvoll und ich werde versuchen, es anzuwenden.
Aber würde das dann nicht bedeuten, dass ich viel mehr Klassen brauche?
Zum Beispiel einen Textur Manager zur Bereitstellung der Texturen, einen Screen Manager zum Wechseln der Fenster, einen Manager der checkt, ob das UFO abgeschossen wurde usw.
Warum sollte man das nicht in einer Klasse (mit unterschiedlichen Funktionen) zusammenfassen?

Werbeanzeige