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

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

11

26.03.2018, 14:02

Worauf BlueCobold hinaus will ist dass du einen Zyklus der Abhängigkeiten hast. Klasse A benutzt Klasse B und Klasse B benutzt Klasse A. Damit das überhaupt erst geht kannst du forward declarations benutzen. Mal ein Beispiel:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
// forward declaration da A den Typ B benutzen will, B aber noch nicht eingeführt wurde.
// Würde man die Definition von B hier oben hinziehen gäbe es das selbe Problem mit Typ A.
class B;

class A{
public:
  B *some_pointer_to_b;
};

class B {
public:
  A *some_pointer_to_a;
};


Was jetzt schöner wäre wäre wenn die Abhängigkeit gar nicht erst da wäre. Das heißt du solltest versuchen deinen Code so umzuschreiben dass es nicht zu dem Fall kennt dass die Abhängigkeiten in einem Kreis verlaufen. In diesem Fall wäre das A kennt B und B kennt A. Es kann aber auch sowas sein wie A kennt B, B kennt C und C kennt A.

In deinem Fall kennt dein Game die GameStates und die GameStates kennen Game. Das ist unschön. Was du jetzt machen könntest wäre dass Game die GameStates kennen, die GameStates aber nicht Game. Damit diese jetzt mit Game kommunizieren können gibt es verschiedene Möglichkeiten. Am einfachsten wäre es eine Form von Event- oder Messagesystem zu implementieren. Ein GameState würde dann ein Event feuern bzw eine Message abgeben, und Game reagiert dann darauf. Je nach Problemfall kann es aber noch einfacher gehen. Ein Beispiel:
Dein GameState soll Game mitteilen das es zu einem neuen GameState wechseln soll. Eine sehr einfache Möglichkeit wäre dass die Update Methode vom GameState den folgenden State zurück gibt.
Du hast ein Enum für die einzelnen GameStates. Update vom GameState gibt jetzt immer den Enum-Wert für sich selbst zurück solange sich nichts ändern soll. Soll der State geändert werden wird der passende Enum-Wert zurück gegeben.

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
enum class EGameState {
  MENU,
  GAME
};

class GameState {
private:
  EGameState own_state;
public:
  GameState(EGameState type) : own_state(type) {
  }

  EGameState type() const {
    return own_type;
  }

  virtual EGameState update();
};

class MenuState : public GameState {
public:
  MenuState() : GameState(EGameState::MENU) {
  }

  EGameState update() {
    if(change_to_game()) {
      return EGameState::GAME;
    }
    return own_state;
  }
};


C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
class Game {
public:
  void update() {
    auto next_state = current_game_state->update();
    if(next_state != current_game_state->type()) {
      // wechsle zum State mit dem Typ next_state
    }
  }
};


In etwa so kann das aussehen. Game kennt und benutzt GameState, bzw die Implementierungen davon, GameState oder dessen Implementierungen kennen aber nicht Game.

PS: Benutz doch bitte die Code-Tags wenn du Code postest. Hier im Editor siehst du oben die schwarzen Buttons mit der Raute, C++, C#, HLSL und Co. Für C++ nimmst du den auf welchem C++ steht. Dann ist der Code schön formatiert und besser lesbar.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“