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

Daedra22

Treue Seele

  • »Daedra22« ist der Autor dieses Themas

Beiträge: 115

Wohnort: Osten

Beruf: Student Informationstechnik

  • Private Nachricht senden

1

15.08.2013, 11:12

Heiko Kalista - Unnötige Deklaration von Surfaces und Häufige Verwendung von Get Funktionen

Hallo,

Habe mir beim Durchstöbern des 12. Kapitels die Frage gestellt, warum Heiko sehr oft dieselben Surfaces in den verschiedenen Klassen deklariert und ob dadurch Speicher- oder Leistungseinbußen einhergehen.

Beispiel:

C-/C++-Quelltext

1
2
3
4
Class CSprite{public:SDL_Surface* GetPlayer(){return Player;}
private:SDL_Surface* Player;
};
Class CPlayer{private:SDL_Surface* Player;public:void Init(){Player= Player2->GetPlayer();}CSprite* Player2};



so ungefähr, (Beispiel stark vereinfacht und nicht genauso im Buch verwendet, aber recht ähnlich )

Gibt es hier nun irgendwelche Speichereinbußen, oder ist nur ein bisschen mehr Text da und da ja die SDL_Surface* Instanz einfach übergeben wird, gibt es keine Nachteile?
Oder hat Kalista einfach zur Vereinfachung dies so zusammengefasst, statt Zeiger und Referenzen zu erzeugen ... ?

Danke für die Hilfe und eure Zeit im voraus !
Who are you? - I am a game designer.
No you are not! - I am a game designer.
What kind of a designer ? - I am a game designer.
You mean you play games ? - I am a game designer.

Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von »Daedra22« (15.08.2013, 11:53)


BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

2

15.08.2013, 11:39

Ein Pointer sind 4, bzw. 8 Bytes. Ich weiß nicht genau, auf was Du jetzt hinaus willst.
Die Zuweisung in der Init-Methode sieht allerdings sehr merkwürdig aus. Kürzungen sind zwar nett, aber enden oft darin, dass die wichtigen Sachen ganz anders sind im Original.
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]

Daedra22

Treue Seele

  • »Daedra22« ist der Autor dieses Themas

Beiträge: 115

Wohnort: Osten

Beruf: Student Informationstechnik

  • Private Nachricht senden

3

15.08.2013, 11:45

ahja sry hab zwei syntaxfehler nun behoben

ok dann mal kurz ungekürzt:



class CAsteroid
{
public:
void Init (CSprite *pSpriteAsteroid, float fXPos, float fYPos);
void Update ();
void Render ();
bool IsAlive () {return m_bIsAlive;}
void SetAlive (bool bIsAlive) {m_bIsAlive = bIsAlive;}
SDL_Rect GetRect () {return m_Rect;}

private:
CSprite *m_pSpriteAsteroid; // Zeiger auf Asteroiden-Sprite
float m_fXPos; // X-Position des Asteroiden
float m_fYPos; // Y-Position des Asteroiden
float m_fAnimPhase; // Akt. Animationsphase des Asteroiden
bool m_bIsAlive; // "Lebt" der Asteroid noch?
SDL_Rect m_Rect; // Rect des Asteroiden

};


//----------------------


class CGame
{
public:
CGame ();

void Init ();
void Run ();
void Quit ();

private:
void ProcessEvents ();
void SpawnAsteroids ();
void RenderAsteroids ();
void CheckCollisions ();

CPlayer *m_pPlayer; // Spieler-Instanz
CSprite *m_pSpriteBackground; // Sprite für den Hintergrund
CSprite *m_pSpriteAsteroid; // Sprite für die Asteroiden
float m_fAsteroidTimer; // Zeitgeber für nächsten Asteroiden
bool m_bGameRun; // Läuft das Spiel noch?
list<CAsteroid> m_AsteroidList; // Liste der Asteroiden

};

//----------------


class CSprite
{
public:
CSprite ();
~CSprite ();

void Load (const string sFilename);
void Load (const string sFilename, int NumFrames,
int FrameWidth, int FrameHeight);
void SetColorKey (int R, int G, int B);
void SetPos (float fXPos, float fYPos);
void Render ();
void Render (float fFrameNumber);
SDL_Rect GetRect () {return m_Rect;}

private:
SDL_Surface *m_pScreen; // Zeiger auf den Screen des Frameworks
SDL_Surface *m_pImage; // Das eigentliche Bild des Sprites
SDL_Rect m_Rect; // Rect des Sprites
SDL_Rect m_FrameRect; // Ausschnitt für Animationsphase
int m_NumFrames; // Anzahl der Animationsphasen
int m_FrameWidth; // Breite einer Animationsphase
int m_FrameHeight; // Höhe einer Animationsphase
int m_NumFramesX; // Wie viele Anim-Phasen in X-Richtung?

};


void CAsteroid::Init (CSprite *pSpriteAsteroid, float fXPos, float fYPos)
{
// Zeiger auf Sprite kopieren und Koordinaten setzen
m_pSpriteAsteroid = pSpriteAsteroid;
m_fXPos = fXPos;
m_fYPos = fYPos;

// Animation beginnt beim ersten Einzelbild
m_fAnimPhase = 0.0f;

// Rect initialisieren
m_Rect.x = static_cast<int>(fXPos);
m_Rect.y = static_cast<int>(fYPos);
m_Rect.w = pSpriteAsteroid->GetRect().w;
m_Rect.h = pSpriteAsteroid->GetRect().h;

// Asteroid aktivieren
m_bIsAlive = true;

} // Init


hab alles relevante nunmal hervormarkiert, um die suche ein wenig zu vereinfachen,
Cobold ich hab leider keine Vorstellung ob diese 4 oder 8 Byte nun viel oder wenig sind, wenn ich in jeder meiner Klassen nun die AsteroidenSprite-Surface deklariere sind es bald nun nicht nur 4 Byte sondern weitaus mehr, ob das wenig ist kann ich nicht einschätzen, deshalb frag ich ja. Ist es effektiv was Heiko da verübt ?

Ist es nicht schlimm in den objekten framework, oder game, asteroid 3 mal das Surface screen zu deklarieren, solang ich über GetFunktionen die Instanzen bzw. Zeiger hin und her schieben kann ?
Who are you? - I am a game designer.
No you are not! - I am a game designer.
What kind of a designer ? - I am a game designer.
You mean you play games ? - I am a game designer.

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Daedra22« (15.08.2013, 11:52)


BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

4

15.08.2013, 11:49

Du hast noch immer zwei Member-Variablen mit den selben Namen.
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]

Daedra22

Treue Seele

  • »Daedra22« ist der Autor dieses Themas

Beiträge: 115

Wohnort: Osten

Beruf: Student Informationstechnik

  • Private Nachricht senden

5

15.08.2013, 11:54

Du hast noch immer zwei Member-Variablen mit den selben Namen.
jetzt richtig ?
Who are you? - I am a game designer.
No you are not! - I am a game designer.
What kind of a designer ? - I am a game designer.
You mean you play games ? - I am a game designer.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

6

15.08.2013, 12:09

4 Bytes sind nichts. Ein Bild mit nur 100x100 Pixeln hat 40.000 Bytes.
Ein Bild mit 1920x1080 Pixeln hat 8.294.400 Bytes.
Der Code für eine Variablen-Zuweisung braucht allein 2-8 Byte Platz im Code-Segment!
Die Sprites als Pointer zu übergeben und intern als Referenz/Pointer zu halten ist deutlich besser als ständig irgendwelche Get-Methoden aufzurufen.
Heiko tut da offenbar auch was anderes als Du. Er übergibt einen Pointer und speichert den in seiner Klasse, damit er später darauf zugreift. Das ist genau richtig so. Bei Deinem gekürzten Beispiel holst Du den Pointer aus einem anderen Pointer per get und es ist unklar, woher die gültige Instanz für den ersten überhaupt kommt.

Init-Methoden sind übrigens Unfug. Dafür ist der Konstruktor da.
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]

Sacaldur

Community-Fossil

Beiträge: 2 301

Wohnort: Berlin

Beruf: FIAE

  • Private Nachricht senden

7

15.08.2013, 12:10

Wenn ein Pointer verwendet wird, dann hat man beispielsweise für eine Textur einen Speicherbedarf von (vereinfacht gesagt) Breite der Textur * Höhe der Textur * Farbtiefe der Textur (in Byte) + 4 Byte * Anzahl der Pointer auf diese Textur. Bei einer 512x512 Textur mit 32 Bit farbtiefe (4 Byte) und 10 Pointern darauf kommt man also auf 1048616 Byte, also etwas mehr als 1 MB.
Wenn man im gleichen Fall keine Pointer verwenden würde, hätte man für jede Stelle, an der die Textur verwendet werden würde eine eigene Instanz und der Speicherbedarf wäre dann eher Textur * Höhe der Textur * Farbtiefe der Textur (in Byte) * Anzahl der Vorkommnisse und somit 10485760 Byte bzw. 10 MB.

Bitte beachte aber, dass diese Berechnung stark vereinfacht ist. Ich habe beispielsweise mit 4 Byte für die Größe der Pointer gerechnet, was auf 64 Bit Systemen wiederum nicht stimmen würde.

Allerdings solltest du dir nicht vorrangig um jeden einzelnen verwendeten Byte Gedanken machen, sondern darüber, ob das Design an und für sich sauber ist. Es dürfte wesentlich einfacher (und Zeiteffizienter) sein, ein Programm sauber zu schreiben und dann zu optimieren, als es direkt optimiert schreiben zu wollen. Ich will damit nicht sagen, dass man beim Schreiben nicht schon auf bestimmte Dinge Rücksicht nehmen sollte, allerdings muss man irgendwoher wissen, was das ist, und muss man wohl Grundsätzlich aus der Erfahrung heraus wissen.
Spieleentwickler in Berlin? (Thema in diesem Forum)
---
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].

xardias

Community-Fossil

Beiträge: 2 731

Wohnort: Santa Clara, CA

Beruf: Software Engineer

  • Private Nachricht senden

8

15.08.2013, 12:11

Wenn du nicht gerade im low level Bereich arbeitest brauchst du dir um ein paar Zeiger mehr oder weniger keine Sorgen machen.
Du musst das im Verhaeltnis zum Gesamtspeicher sehen. In 1GB RAM hast du Platz um mehr als 16 mio Pointer zu speichern, da ist es durchaus ok mal 1, 2 Pointer zu verschwenden wenn du dafuer Code schreiben kannst der uebersichtlicher und einfacher zu warten ist.

Databyte

Alter Hase

Beiträge: 1 040

Wohnort: Na zu Hause

Beruf: Student (KIT)

  • Private Nachricht senden

9

15.08.2013, 12:13

Ein Pointer ist immer gleich groß. je nachdem ob du 32bit oder 64 bit kompilierst, ist der Zeiger 4 bzw. 8 Byte groß. Also jeden Asteroiden, den du erzeugst, wird so einen Pointer haben.
In dem Beispiel brauchen die Asteroiden den Pointer auf das spirte, denn sonst wüßten sie ja in der Render-methode nicht, was sie zeichnen sollten.
Das CSprite ist dabei nur eine Klasse, die die Benutzung der SDL vereinfachen soll.

Wegen Speicher brauchst du dir keine Gedanken zu machen. Selbst wenn du 10000 Asteroieden auf einem 64bit system erzeugst, sind dass gerade mal 10000*8 = 78kb für die pointer. Wieviel hauptspeicher hat dein rechner? 4 gb?
Also da ist noch genug platz ;)

PS: Die AsteroidenSprite-Surfaces werden in den Klassen nicht deklariert, sondern definiert! ich bin erst total durcheinandergekommen :ninja: Deklarationen führen nie zu Speicherverbrauch.
Siehe dazu das hier. besonders den zweiten Beitrag ;)

Edit
Ist ja witzig jetzt haben 4 Leute das gleiche gepostet.... Spieleprogrammierer.de, da werden sie geholfen ;)

Daedra22

Treue Seele

  • »Daedra22« ist der Autor dieses Themas

Beiträge: 115

Wohnort: Osten

Beruf: Student Informationstechnik

  • Private Nachricht senden

10

15.08.2013, 12:18

ah ok, danke für die vielen Antworten, bin bisschen schlauer geworden ^^
Who are you? - I am a game designer.
No you are not! - I am a game designer.
What kind of a designer ? - I am a game designer.
You mean you play games ? - I am a game designer.

Werbeanzeige