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

Lindraupe

Frischling

  • »Lindraupe« ist der Autor dieses Themas

Beiträge: 62

Wohnort: Wien

  • Private Nachricht senden

1

05.02.2016, 21:44

Problem mit Singletons und Stack

Ich versuch grad mein Spiel zu erweitern, und dazu brauch ich die Position vom Spieler als Singleton.
Ich nehm mal an, dass ich irgendwas beim Stack falsch gemacht hab, hab selber aber keine Lösung gefunden, obwohl ich so ziemlich das gleiche schon mal gemacht hab. :fie:

Also zur Erklärung: Ich will das Rechteck m_Player auch in einer anderen Datei verwenden. Dazu hab ich ein Singleton gemacht, und folgende Funktion erstellt (cout zum Testen)

C-/C++-Quelltext

1
SDL_Rect GetRect() { cout << m_Player.x << endl; return m_Player; }

Diese Funktion liefert mir dann aber nicht m_Player so wie er in (.ccp) Z. 11 und 27 geändert wurde zurück, sondern z.b. m_Player.x = 0.
Liegt das daran, dass es vor der Funktion auf den Stack kommt, und nachher wieder so wie vorher ist?

(gekürzter Quellcode)
Der Header

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
#ifndef PLAYER_HPP
#define PLAYER_HPP

#include <list>
#include"Singleton.hpp"

#define g_pPlayer CPlayer::Get()
class CPlayer : public TSingleton<CPlayer>
{
public:
    void Update();
    void Reset();
    SDL_Rect GetRect() { cout << m_Player.x << endl; return m_Player; }

private:
    void ProcessMoving();
    float m_fXPos;          // X-Position des Spielers
    float m_fYPos;          // Y-Position des Spielers
    SDL_Rect m_Player;
    
};

#endif


Die .cpp Datei

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
#include "Player.hpp"
// Reset
//
// Aufgabe: Spielerwerte auf Standard setzen
//
void CPlayer::Reset()
{
    // Startposition des Spielers
    m_fXPos = 376.0f;
    m_fYPos = 520.0f;
    m_Player.x = 376;
    m_Player.y = 520;
    m_Player.h = 64;
    m_Player.w = 64;

} // Reset

// Update
//
// Aufgabe: Spieler updaten
//
void CPlayer::Update()
{
    // Bewegung des Spielers
    ProcessMoving();

    m_Player.x = static_cast<int> (m_fXPos);
    m_Player.y = static_cast<int> (m_fYPos);
} // Update

CeDoMain

Alter Hase

Beiträge: 587

Wohnort: Ilmenau

Beruf: Student für Mechatronik

  • Private Nachricht senden

2

05.02.2016, 21:56

Nein, ich vermute nicht, dass der Auslöser ein "fehlerhafter" Stack ist. Setz doch bitte mal einen Haltepunkt in Z.11 und Z. 27 der .cpp und schau dir mal an, welchen Wert die Variable vor und welchen nach dem Aufruf hat. Dasselbe mach auch mal für Z.13 im Header. Vielleicht fällt da schon auf, woran es liegt bzw. du kannst eingrenzen wo der Fehler erzeugt wird.
Mit freundlichem Gruß
CeDo
Discord: #6996 | Skype: cedomain

Lass solche persönlichen Angriffe lieber bleiben, meine sind härter.

3

06.02.2016, 00:38

Ich versuch grad mein Spiel zu erweitern, und dazu brauch ich die Position vom Spieler als Singleton.
Ich nehm mal an, dass ich irgendwas beim Stack falsch gemacht hab, hab selber aber keine Lösung gefunden, obwohl ich so ziemlich das gleiche schon mal gemacht hab. :fie:

Also zur Erklärung: Ich will das Rechteck m_Player auch in einer anderen Datei verwenden. Dazu hab ich ein Singleton gemacht, und folgende Funktion erstellt (cout zum Testen)

Naja, zunächst einmal solltest du aus dem Singleton eine globale Variable machen, denn das ist, wonach du scheinbar eigentlich suchst, und damit ehrlicher (immer gut, Code zu schreiben, der nicht verwirrt). Und als nächstes solltest du dich vielleicht fragen, ob es keine bessere Möglichkeit gibt, als aus dem Spieler eine globale Variable zu machen. In der Regel führt sowas nämlich früher oder später zu Problemen.
Lieber dumm fragen, als dumm bleiben!

Lindraupe

Frischling

  • »Lindraupe« ist der Autor dieses Themas

Beiträge: 62

Wohnort: Wien

  • Private Nachricht senden

4

06.02.2016, 11:59

@CeDoMain Hab ich eh schon versucht. Das Problem dabei war, dass das Spiel eine andere Auflösung hat, und Visual Stuido die irgendwie übernimmt (das heißt ich kann so gut wie gar nix machen). Dann hab ich den betroffenen code in ein neues Projekt kopiert und das dort gemacht, und es halt soweit eingrenzen können, dass der Wert aus der Header-Datei nicht der aus der .cpp Datei ist. Weiter bin ich nicht mehr gekommen :/

@Jonathan_Klein: Wie meinst du das, aus dem Singleton eine globale Variable machen? Den Befehl g_pPlayer->GetRect() kann ich eh auch in der anderen Datei öffnen. Oder meinst du, dass ich SDL_Rect m_Player global mache?
Und ich bin jetzt wirklich auf eine bessere Lösung gekommen ;) Ich hab ja eine Instanz von CPlayer gemacht, also kann ich ja m_pPlayer->GetRect() machen.

P.S. Die Website http://www.c3-soft.de/ gibts nicht mehr.

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

5

06.02.2016, 15:48

@Jonathan_Klein: Wie meinst du das, aus dem Singleton eine globale Variable machen? Den Befehl g_pPlayer->GetRect() kann ich eh auch in der anderen Datei öffnen. Oder meinst du, dass ich SDL_Rect m_Player global mache?
Und ich bin jetzt wirklich auf eine bessere Lösung gekommen Ich hab ja eine Instanz von CPlayer gemacht, also kann ich ja m_pPlayer->GetRect() machen.

Genau darauf wollte er hinaus. Oft wird Singleton benutzt weil man aus Faulheit von überall auf ein Objekt zugreifen möchte. Dafür nimmt man aber eigentlich globale Variablen. Singleton verschleiert in dem Fall eine globale Variable und macht das ganze unübersichtlicher. Globale Variablen sollte man aber auch meiden. Früher oder später macht das Probleme. In deinem Fall, stell dir vor du willst einen zweiten Spieler einbauen. Dann musst du dein komplettes System umschreiben. Mit Instanzen und ein wenig kluger Arbeit beim Design deiner Spielerklasse müsstest du viel viel viel weniger Code anpassen.
„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.“

Lindraupe

Frischling

  • »Lindraupe« ist der Autor dieses Themas

Beiträge: 62

Wohnort: Wien

  • Private Nachricht senden

6

07.02.2016, 11:31

Ich hab sogar vor einen zweiten Spieler zu machen ^^.
Danke für die Erklärung!

Werbeanzeige