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
Vieles wurde ja schon gesagt. Anstatt dein CText per Zeiger zu halten und jedes mal mit new zu erstellen kannst du einfach ein CText Objekt benutzen. Es gibt ja keinen Grund warum du da ein Objekt auf dem Heap benutzt. Weiterhin benutzt du C-Strings was nicht besonders schon ist. Damit ist dein Char Array gemeint. In C++ gibt es die Klasse std::string. Das sind zwei Punkte die schnell umgesetzt sind. Vor allem der erste Punkt ist wichtig. Stell dir vor beim erstellen deines CText Objektes geht etwas schief. Kurz danach rufst du die Render Funktion darauf auf. Dann würde es krachen. Die Zeilen 53 bis 57 könntest du dir dann einsparen. Bevor du einen Zeiger mit delete freigibst musst du übrigens nicht prüfen ob dieser valide ist. Du kannst das selbst mal testen. An sich solltest du dir diese Raw Pointer aber allgemein abgewöhnen. Wurde ja schon gesagt. Ich weiß du wolltest nicht hören dass du "modernes" C++ benutzen sollst, den Punkt wollte ich trotzdem noch anmerken.
Ansonsten wäre es nett wenn du noch mal kurz sagen könntest was dann nun genau das Problem ist. Dein Speicher läuft immer noch voll? Na genau deshalb benutzt man ja Smartpointer. Weil diese ganzen Fehlerquellen dann nicht mehr vorhanden sind. Ich kann ich dem Code den du da gepostet hast aktuell nicht sehen was da nicht gelöscht wird. Bist du dir sicher dass aktuell hier das Problem ist? Sicher dass du nicht in einer der anderen Methoden Objekte erstellst ohne sie zu löschen? Oder geht es aktuell um ein anderes Problem? Beschreibe das vielleicht noch mal und gegebenenfalls müssten wir dann mehr Code sehen.
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 |
// Game.hpp // #ifndef GAME_HPP #define GAME_HPP #include "Player.hpp" #include "Banana.hpp" #include "Text.hpp" #include <list> class CGame { public: CGame (); void Init (); void Run (); void Quit (); void Menu (); private: void ProcessEvents (); bool m_bGameRun; // Läuft das Spiel noch? bool m_bMenu; // Läuft das Hauptmenü noch? int m_Score; // Der Score für ein Spiel CText m_tScore; // Text - Score }; #endif |
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 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
// Run // // Aufgabe: Der eigentliche "Herzschlag" des Spiels // void CGame::Run() { char TextBuffer_Score[15]; // Die "Herzschlag"-Schleife while (m_bGameRun == true) { // Hauptmenü aufrufen, falls noch aktiv if (m_bMenu == true) { Menu (); } // Menu // Framework updaten und Buffer löschen g_pFramework->Update (); g_pFramework->Clear (); // Events überprüfen ProcessEvents (); // Hintergrundbild rendern m_pSpriteGame->Render (); // Spieler updaten und rendern m_pPlayer->Update (); m_pPlayer->Render (); // Neue Bananas hinzufügen SpawnBananas (); // Kollisionen überprüfen CheckCollisions (); // Bananas rendern RenderBananas (); sprintf_s(TextBuffer_Score, "Score: %i", m_Score); m_tScore.Draw (g_pFramework->GetRenderer(), "Schriftarten/comic.ttf", 50, TextBuffer_Score, { 0, 0, 0, 0 }); // Gesammelte Bananas anzeigen // Erreichten Score anzeigen m_tScore.display (1320, 15, g_pFramework->GetRenderer()); m_tScore.~CText(); // Falls 'H' gedrückt wird, zum Hauptmenü // zurückkehren und Spielerstand zurücksetzen if (g_pFramework->KeyDown(SDL_SCANCODE_H)) m_bMenu = true; // Spiel darstellen g_pFramework->Render (); } } // Run |
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 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
// Text.cpp // #include "Text.hpp" // Konstruktor // CText::CText () { } void CText::Draw(SDL_Renderer *renderer, const string &font_path, int font_size, const string &message_text, const SDL_Color &color) { m_text_texture = loadFont(renderer, font_path, font_size, message_text, color); SDL_QueryTexture(m_text_texture, nullptr, nullptr, &m_text_rect.w, &m_text_rect.h); } // Destruktor // CText::~CText () { TTF_CloseFont (m_pFont); SDL_DestroyTexture(m_text_texture); m_pFont = NULL; } void CText::display(int x, int y, SDL_Renderer *renderer) { m_text_rect.x = x; m_text_rect.y = y; SDL_RenderCopy(renderer, m_text_texture, nullptr, &m_text_rect); } SDL_Texture *CText::loadFont(SDL_Renderer *renderer, const string &font_path, int font_size, const string &message_text, const SDL_Color &color) { TTF_Font *m_pFont = TTF_OpenFont(font_path.c_str(), font_size); if (!m_pFont) { cout << "failed to load font!" << endl; } auto m_text_surface = TTF_RenderText_Solid (m_pFont, message_text.c_str(), color); if (!m_text_surface) { cout << "failed to load surface!" << endl; } if (!message_text.c_str()) { cout << "failed to load message!" << endl; } auto text_texture = SDL_CreateTextureFromSurface(renderer, m_text_surface); if (!text_texture) { cout << "failed to load texture!" << endl; } SDL_FreeSurface (m_text_surface); return text_texture; SDL_DestroyTexture(text_texture); } |
Administrator
In CText::Draw lädst du jedes Mal die Schrift neu.
In CText::loadFont hast du nach dem return noch eine Anweisung stehen, die natürlich nie ausgeführt wird.
Administrator
Tipp: OpenFont nur im Konstruktor, CloseFont nur im Destruktor.
Werbeanzeige