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

21.05.2015, 00:38

Frage zu meinem StateManager

Hallöle,
ich entwickle gerade meinen State-Manager und wollte mal von euch wissen wo oder was ich vllt verbessern könnte. Immoment ist mein liebes Stück noch sehr Basic. Haber aber hier und da meine Zweifel.

Die GameState.hpp:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
#pragma once
class CGameState
{
public:
    
    virtual ~CGameState(){};
    virtual void Update(){};
    virtual void Render(){};
};

Meine Steuereinheit, StateManager.hpp:

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
#pragma once
#include "TSingleton.hpp"
#include "GameState.hpp"
#define StateManager CStateManager::Get()

class CStateManager : public TSingleton<CStateManager>
{
private:

    CGameState * GameState;

public:

    CStateManager();
    ~CStateManager();
    void Update();
    void Render();

    enum GameStates {Menu,Game}State;

    void Init(GameStates NGS);
};

Die .cpp dazu:

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
32
33
34
35
36
37
#include "StateManager.hpp"
#include "Game.hpp"
#include "Menu.hpp"

CStateManager::CStateManager()
{
}

void CStateManager::Init(GameStates NGS)
{

    switch (NGS)
    {
    case CStateManager::Menu: GameState = new CMenu
        break;
    case CStateManager::Game: GameState = new CGame;
        break;
    default:
        break;
    }

}

void CStateManager::Update()
{
    GameState->Update();
}

void CStateManager::Render()
{
    GameState->Render();
}


CStateManager::~CStateManager()
{
}

main.cpp:

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
int main()
{
    sf::RenderWindow window(sf::VideoMode(200, 200), "ich bin ein Fenster!");
    


    StateManager->Init(StateManager->Game);

    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();
        }

        window.clear();
        StateManager->Update();
        StateManager->Render();
        window.display();
    }

    return 0;
}


Meine Frage ist eigentlich ob das so "in Ordnung" ist. Oder falle ich damit später mit mehreren States auf die Nase. Habe das gefühl das ich das nicht ganz effizient angehe.
Und dann noch eine gezieltere Frage. Bei der Init-Methode, die in der main.cpp aufgerufen wird, soll eigentlich die Enum "State" benutzt werden. Aber irgendwie kriege ich das nicht ganz hin. So wie ich das gerade mache wird doch im Grunde bei jeden aufrufen ein neues GameStates kreiert oder nicht?

Mfg Urprimat
Most good programmers do programming not because they expect to get paid or get adulation by the public, but because it is fun to program.

Linus Torvalds

Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von »Urprimat« (21.05.2015, 00:50)


2

21.05.2015, 05:19

Das wird wohl so nicht Funktionieren wie du dir das Vorstellst.

Die Init Methode erstellt, jedesmal einen neuen State. Du möchtest aber mit Sicherheit später nicht jedesmal den State neu erzeugen sondern den bestehenden fortsetzen.
Ich würde es über eine addState-Methode (dem StateManager einen State Bekannt machen) und eine changeState-Methode (für das wechseln der States) machen. Weiter hin würde ich die States in einem Container speichen (so wie du es hast geht nur ein State).

Gruß Koschi
Wer aufhört besser werden zu wollen hört auf gut zu sein!

aktuelles Projekt:Rickety Racquet

3

21.05.2015, 08:31

Deine addState-Methode erscheint mir sinnvoll da ich dadurch ein wening dynamischer bin und dann von Extern einen neuen State erschaffen kann. Das Problem von changeState was ich immoment habe ist, dass ich nicht genau weiß wie ich den State ändern soll. Mein aktueller versuch scheint ja nicht gerade gut zu sein. Immoment steht mir ja nur die Enum zur verfügung. Meinst du mit Speichern in einem Container, das ich statt des Enums ein Vector bentuzen soll? doch wie weiß ich dann wie der State heißt?

grüßte Urprimat
Most good programmers do programming not because they expect to get paid or get adulation by the public, but because it is fun to program.

Linus Torvalds

Nimelrian

Alter Hase

Beiträge: 1 216

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

  • Private Nachricht senden

4

21.05.2015, 09:07

doch wie weiß ich dann wie der State heißt?

grüßte Urprimat
Stichwort Polymorphie

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class State {
  virtual void update() = 0;
  virtual void render() = 0;
};

class GameState : public State {
  void update();
  void render();
};

class MenuState : public State {
  void update();
  void render();
};
Ich bin kein UserSideGoogleProxy. Und nein, dieses Forum ist kein UserSideGoogleProxyAbstractFactorySingleton.

5

21.05.2015, 10:54

CGame und CMenu erben von der GameState klasse und überschreieben jeweils die Update und Render Funktion. Somit benutze ich es doch schon oder?

Meine Frage ist vielmehr wie ich das mit dem Container bewerkstelligen soll. Soll ich das GameState Obejekt in einem Vector speichern?! oder wie ist das jetzt gemeint?
ich habe verständnissprobleme wie ich den State Hinzufügen, Speichern und Ändern kann...
Most good programmers do programming not because they expect to get paid or get adulation by the public, but because it is fun to program.

Linus Torvalds

6

21.05.2015, 10:57

doch wie weiß ich dann wie der State heißt?

grüßte Urprimat
Stichwort Polymorphie

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class State {
  virtual void update() = 0;
  virtual void render() = 0;
};

class GameState : public State {
  void update();
  void render();
};

class MenuState : public State {
  void update();
  void render();
};

Da weiß er immer noch nicht wie der aktuelle State heist!

Ja du sollst anstelle des Pointers ein Vector oder Map oder Liste benutzen. In dem Zusammenhang schau dir auch mal http://www.cplusplus.com/reference/utility/make_pair/ an. Dein Pointer behältst als aktuellen State (wird neu gesetzt bei changeState) genauso kannst du eine enum haben/setzen die dir sagt wie der aktuelle State heist.
Oder du gibst dem state mit wir er heist.
Wer aufhört besser werden zu wollen hört auf gut zu sein!

aktuelles Projekt:Rickety Racquet

7

21.05.2015, 11:40

Also zur verstädniss.

Ich Lege eine Map in meinem StateManger an. Diese wird dann mit den abgeleiteten Klassen von CGameState, Zb CGame & CMenu geüllt. Der Partner des Elementes in der Map könnte ja der Name des States sein. Wenn ich jetzt in meiner main.cpp ChangeState("Menu") aufrufe, wird nach dem Key "Menu" gesucht und der Partner, indem fall die Klasse CMenu, wird als Pointer dem Objekt GameState zugewiesen. Somit spare ich mir ja das lästige Swtichen. Jedoch muss ich den Container bei der Initalisierung des StateManger manuell Füllen. Wie meintest du das mit dem AddState?
Allerdings finde ich das für den Anfang nicht weiter hinderlich

Iich hoffe ich habe das richtig verstanden :crazy:

Grüße Urprimat
Most good programmers do programming not because they expect to get paid or get adulation by the public, but because it is fun to program.

Linus Torvalds

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Urprimat« (21.05.2015, 11:46)


Nimelrian

Alter Hase

Beiträge: 1 216

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

  • Private Nachricht senden

8

21.05.2015, 11:44

doch wie weiß ich dann wie der State heißt?

grüßte Urprimat
Stichwort Polymorphie

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class State {
  virtual void update() = 0;
  virtual void render() = 0;
};

class GameState : public State {
  void update();
  void render();
};

class MenuState : public State {
  void update();
  void render();
};

Da weiß er immer noch nicht wie der aktuelle State heist!


Kannst du mir eben einen Fall sagen, in dem man den "Namen" eines States wissen muss, statt einfach zu wissen, welcher State es ist?
Ich bin kein UserSideGoogleProxy. Und nein, dieses Forum ist kein UserSideGoogleProxyAbstractFactorySingleton.

9

21.05.2015, 11:46

Ja so hört sich das gut an.
Die map aber über addState befüllen.
Wer aufhört besser werden zu wollen hört auf gut zu sein!

aktuelles Projekt:Rickety Racquet

10

21.05.2015, 11:56

@Nimelrian
Hmm naja wenn ich zb einen State wechseln möchte. ich will das ca so Realisieren:
ChangeState("Menu")
Somit soll dann ins Menu gewächselt werden. ich wüsste nicht wie das machen soll ohne dem State den namen "Menu" zu geben.


Ja so hört sich das gut an.
Die map aber über addState befüllen.


Soll ich dann von Extern den StateManager befüllen? also AddState("Menu")? Aber wie weiß dann der StateManager das Menu zu CMenu gehört? wie Regel ich das dann mit den #Includes?
Most good programmers do programming not because they expect to get paid or get adulation by the public, but because it is fun to program.

Linus Torvalds

Werbeanzeige