SDL_FreeSurface() in Schleife benutzen?
-
Hallo,
Ich möchte gerne eine Text ausgabe mit SDL_ttf machen dafür brauch
ich aber noch eine Variable die den stand der Lebensenergie eines
Gegners angibt, jedoch ist das Problem das ich leider nicht weiß
wie ich das mit den String machen soll, so sieht die Zeile aus:SDL_Surface* text_type3 = TTF_RenderText_Shaded(sdlFont, "Hp:", textColor, backgroundColor); //Die Variable soll neben Hp: erscheinen. //Die Variable besitzt den Wert 100 und wurde über dieser Zeile defeniert
So, jedoch wollte ich auch noch wissen wie es möglich ist mit
SDL_Freesurface() es so hinzubekommen das wenn diese Funktion in
einer Schleife ist die bei Knopfdruck von dem Buchstaben "x" ausgelöst wird
den Gegner vom Bildschirm zu entfernen, jedoch wenn ich das Spiel starte
und den Buchstaben drücke stürzt das Spiel ab bei der Kollision mit dem Gegner.Diese Frage schwirrt mir schon die ganze zeit im Kopf bisjetzt
hab ich es immer so gelöst wenn ich was vom bildschirm weghaben wollte
das ich die x Position des Objektes so hoch eingestellt hab das er von dem
Bildschirm weg war, was defenitiv nicht gerade die eleganteste lösung ist...Liebe Grüße Neuling2003!
-
Dieser Thread wurde von Moderator/in pumuckl aus dem Forum C++ in das Forum Spiele-/Grafikprogrammierung verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
Da du deine Frage ursprünglich im C++-Forum gestellt hast, gehe ich mal davon aus, dass dir auch entsprechende Sprachmittel zur Verfügung stehen.
Textausgabe
Das ließe sich über einen String-Stream realisieren. Diese funktionieren ähnlich wie std::cout.
Ein kleines (kompilierbares) Beispiel:
#include <iostream> #include <sstream> int main() { std::stringstream ss; int hitpoints = 10; ss << "Hp: " << hitpoints; std::string example = ss.str(); std::cout << example << std::endl; // Als const char * std::cout << example.c_str() << std::endl; // Oder in einer Zeile std::cout << ss.str().c_str() << std::endl; }
Das "Problem", welches du mit der SDL haben wirst, ist dass std::stringstream::str einen std::string zurück gibt [1]. SDL, da es eine C-Bibliothek ist, wird einen 'const char *' erwarten. std::string bietet jedoch eine Methode, welche einen solchen Typ zurück gibt (std::string::c_str) [2].
SDL_Freesurface
Diese Funktion sorgt nicht dafür, dass eine Grafik nicht mehr angezeigt wird, sondern sie gibt den von ihr belegten Speicher wieder frei. Wenn du Zeiger auf eine freigegebene SDL_Surface weiter verwendest, kommt es (im besten Fall) zum Crash (im schlimmsten Fall läuft das Programm mit undefiniertem Verhalten einfach weiter).
SDL_Surfaces sind Resourcen. Diese werden zu Beginn angefordert/geladen etc. um am Ende des Programmes wieder freigegeben zu werden.
Soll ein Gegner nicht gezeichnet werden, dann zeichne (SDL_Blit) ihn einfach nicht.
SFML[3] ist auch etwas, was du dir mal ansehen könntest. Es passt besser zu C++.
Grüße... Heiko
--
[1] http://www.cplusplus.com/reference/iostream/stringstream/str/
[2] http://www.cplusplus.com/reference/string/string/c_str/
[3] http://sfml-dev.org
-
Hallo ich bin Neuling,
Ja ich kenne mich mit C++ aus und mir ist auch klar das
SDL_FreeSurface zur Speicher freigabe ist, ich habe es nur grob formuliert.Leider muss ich sagen das ich das mit den Strings nicht verstanden
hab, ich weiß nicht wie ich das in meinen Code "einbauen" soll.
Um es nochmal zu verdeutlichen hier die 2 Surfaces für den Text:SDL_Surface* text_type1 = TTF_RenderText_Solid(sdlFont, "Highscore:", textColor); SDL_Surface* text_type2 = TTF_RenderText_Shaded(sdlFont, "Hp:", textColor, backgroundColor);
Das heißt nicht das ich nich weiß was strings sind jedoch konnte ich sie
noch nie richtig in Programmen mit einem Fenster statt einer Konsole verwenden.Und das mit dem SDL_BlitSurface, ich glaube an der Stelle hast
du mich falsch verstanden weil ich möchte das nachdem der int Wert
Hp auf 0 landet, der schon gezeichnete Gegner vom Bildschirm entfernt
wird. Oder geht das auch mit SDL_BlitSurface weil mit meiner Suchmaschine
finde ich leider nichts dazu..Trotzdem danke schonmal für deinen Beitrag!
-
Das mit den Strings findest du noch selbst raus. Suche mal nach den Zusammenhang und Unterschied zwischen std::string und **const char ***. Auch bei vielen Funktionen aus der C++-Standardbibliothek musst du das beachten.
Was das ominöse Problem mit deinem SDL_Freesurface angeht, solltest du etwas mehr Code posten. Sollte der Quelltext zu lang werden, verwende am besten einen Dienst wie paste.pocoo.org oder nopaste.org.
Grüße... Heiko
-
if ( rcChuckles.x < 0 ) { rcChuckles.x = 0; } else if ( rcChuckles.x > SCREEN_WIDTH-SPRITE_SIZE ) { rcChuckles.x = SCREEN_WIDTH-SPRITE_SIZE; } if ( rcChuckles.y < 0 ) { rcChuckles.y = 0; } else if ( rcChuckles.y > SCREEN_HEIGHT-SPRITE_SIZE ) { rcChuckles.y = SCREEN_HEIGHT-SPRITE_SIZE; } //Kollision /////////////// if (rcChuckles.x + rcChuckles.w >= rcItem1.x && rcChuckles.x <= rcItem1.x + rcItem1.w && rcChuckles.y + rcChuckles.h >= rcItem1.h && rcChuckles.y <= rcItem1.y + rcItem1.h) { rcSrc.x = 1400; rcItem1.x = rcChuckles.x; rcItem1.y = rcChuckles.y +3; } if (rcItem1.x + rcItem1.w >= rcRobot.x && rcItem1.x <= rcRobot.x + rcRobot.w && rcItem1.y + rcItem1.h >= rcRobot.h && rcItem1.y <= rcRobot.y + rcRobot.h) { rcRobot.x -= 5; } //Kollision Ende ////////////////// //Skill 1 ////////////////// keystate = SDL_GetKeyState(NULL); if (keystate[SDLK_x] ) { SDL_BlitSurface(skill1, 0, screen, &rcSkill1); SDL_UpdateRect(screen, 0, 0, 0, 0); rcSkill1.y = rcChuckles.y; rcSkill1.x += 10; } //Kollsion von skill 1: if (rcRobot.x + rcRobot.w >= rcSkill1.x && rcRobot.x <= rcSkill1.x + rcSkill1.w && rcRobot.y + rcRobot.h >= rcSkill1.h && rcRobot.y <= rcSkill1.y + rcSkill1.h) { SDL_BlitSurface(text_type2, 0, 0, &text_pos2); SDL_Surface* text_type3 = TTF_RenderText_Shaded(sdlFont, "RobotsHp: 80%", textColor, backgroundColor); SDL_Rect text_pos3 = {190, 0, 0, 0}; SDL_BlitSurface(text_type3, NULL, screen, &text_pos3); SDL_UpdateRect(screen, 0, 0, 0, 0); rcRobot.x += 3; } if (RobotsHp = 0) { rcRobot.y = 100; } //Skill1 Ende ////////////////////////// ///////////////////////// // Hintergrund Zeichnen for (int x = 0; x < SCREEN_WIDTH / SPRITE_SIZE; x++) { for (int y = 0; y < SCREEN_HEIGHT / SPRITE_SIZE; y++) { rcGround.x = x * SPRITE_SIZE; rcGround.y = y * SPRITE_SIZE; SDL_BlitSurface(ground, NULL, screen, &rcGround); } } //Spirits zeichnen SDL_BlitSurface(chuckles, &rcSrc, screen, &rcChuckles); SDL_BlitSurface(leiste, 0, screen, &rcLeiste); SDL_BlitSurface(item1, 0, screen, &rcItem1); SDL_BlitSurface(robot, 0, screen, &rcRobot); SDL_BlitSurface(text_type1, NULL, screen, &text_pos1); SDL_BlitSurface(text_type2, NULL, screen, &text_pos2); //Back und Front Buffer tauschen SDL_Flip(screen); //Screen Updaten SDL_UpdateRect(screen, 0, 0, 0, 0); } // Sauber machen SDL_FreeSurface(chuckles); SDL_FreeSurface(ground); SDL_FreeSurface(leiste); SDL_FreeSurface(item1); SDL_FreeSurface(skill1); SDL_FreeSurface(robot); SDL_FreeSurface(text_type1); SDL_FreeSurface(text_type2); SDL_Quit(); //TTF Font löschen TTF_CloseFont(sdlFont); //SDL_ttf wieder beenden TTF_Quit(); //Runter fahren von FMOD Sound result = FMOD_Sound_Release(sound1); ERRCHECK(result); result = FMOD_System_Close(system); ERRCHECK(result); result = FMOD_System_Release(system); ERRCHECK(result);
So, das Ziel ist es mit skill 1 oder item 1 den robot zu vernichten
jeder schlag zieht 20hp von 100hp ab (lebensenergie), wenn man nun öferts
rauf haut wird logischer weise irgendwann die negative hp Zahl 100 sein,
also 100-100= 0.
So jetzt würde ich gerne eine Schleife machen die etwa so aussieht:if (hp = 0) { //So nun bräuchte ich irgend eine möglich keit den Robot vom Bildschirm //zu entfernen, und genau das ist mein Problem da ich keine möglichkeit //hab deswegen geht es eigentlich nicht um SDL_Surface sondern einfach //darum diesen Sprite (robot) vom Bildschirm zu entfernen wenn die //bedingung von if also hp = 0 erfüllt würd. }
Und genau deswegen dachte ich mir ich benutze SDL_Surface dafür
aber wie gesagt das Spiel wird gecrasht genau wenn der Robot die 0 hp erreicht.
Deswegen brauche ich eine andere Variante
-
Die Antwort hat 'bwbg' dir doch schon geschrieben: zeichne den Robot einfach nicht:
if(RobotsHp > 0) SDL_BlitSurface(..., &rcRobot);
P.S. Gibt dir dein Compiler bei "if (RobotsHp = 0)" eigentlich keine Warnung raus???
-
Fehler von mir ich meinte eigentlich den Operatoren "==",
und du meintest wohl denif(RobotsHp > 0) SDL_BlitSurface(..., &rcRobot);
Operatoren: "<" weil sonst hat das teilweise keinen sinn.
Ok jetzt habe ich zwar das mit den nicht Zeichnen vestanden jedoch
funktioniert das ganze nicht bei mir, also wenn ich allgemein
das nicht Zeichnen benutze funktioniert es aber in der Schleife nicht,
so sieht die Schleife aus,int RobotsHp = 100; /* ... */ if (rcRobot.x + rcRobot.w >= rcSkill1.x && rcRobot.x <= rcSkill1.x + rcSkill1.w && rcRobot.y + rcRobot.h >= rcSkill1.h && rcRobot.y <= rcSkill1.y + rcSkill1.h) { rcRobot.x += 3; RobotsHp -= 100; if( RobotsHp < 1) { SDL_BlitSurface(robot, 0, 0, &rcRobot); } }
Wenn ich jetzt den Skill auf den Roboter abfeuere, ist er leider immer
noch auf dem Bildschirm zusehen obwohl das eig. so funktionieren sollte, oder?Ich weiß ich frag ziemlich viel aber ich bin leider noch ein Anfänger
was die Spieleprogrammierung betrifft.Ich hoffe ihr könnt mir noch einen Tipp geben.
-
Du solltest dir mal deine Bedingung zum Zeichnen des Roboters noch einmal genau ansehen. Generell solltest du deinen Quelltext aufräumen. Das sieht recht nach "irgendwo gelesen und irgendwie reingewurschtelt" aus.
Das SDL-Tutorial hat ein paar gute Ansätze, die man durchaus (und gerade zu Beginn) auch umsetzen sollte.
Grüße... Heiko