Hilfe bei der Fehlersuche
-
Hi Leute, habe folgendes Problem. Ich habe mein Programm etwas Sortiert.
Es Zeigt ein Hauptmenü mit 3 Buttons wenn ich auf den Button Option klicke wird
die Variable GameState auf 4 gesetzt was bewirkt das folgende Header Datei ausgeführt wird. Das ganze habe ich bereits mit dem Hauptmenü und dem Beenden button erfolgreich Vollzogen.
doch hier scheint sich ein Fehler eingeschlichen zu haben den ich nicht finde.
ich bekomem beim beenden des Programms eine fehlermeldung.
ich weis das es an diesem Teil des Programms liegen muss da ich ohne ihn keine Fehlermeldung erhalte.
dieser Teil soll folgendes ausführen.Er öffnet das Optionsmenü.Stellt dann eine hintergrundgrafik da und eine Grafik mit einem leeren Kästchen. Wenn ich mit der Maus in das leere Kästchen klicke
wird dieses durch die grafik eiens vollen kästchens ersetzt.dadurch wird die Musik abgespielt udn die Lautstärke auf hundert gesetzt. klicke ich wieder drauf soll das Musikvolumen auf 0 gesetzt werden und wieder ein leeres kästchen dargestellt werden.das problem beim klick in das leere kästchen tu sich nichts
das ganze habe ich vorher in der main realiesiert und da lief es ich habe es dann lediglich in eine header datei ausgelagert.
kann mir jemand helfen?
void Optionen(sf::RenderWideow *App, int *GameState) { int MausX = 0; // Speichert Mausabfrage X int MausY = 0; // Speichert Mausabfrage X int MusicStatus = 0; sf::Image BackgroundImage; sf::Sprite Background; BackgroundImage.LoadFromFile("D:\\Entwicklung\\Laufende Projekte\\Projekt001\\Grafiken\\BGProjekt001.png"); Background.SetImage(BackgroundImage); sf::Image MusikKaestchenleerImage; sf::Sprite MusikKaestchenleer; MusikKaestchenleer.SetPosition(480,350); MusikKaestchenleerImage.LoadFromFile("D:\\Entwicklung\\Laufende Projekte\\Projekt001\\Grafiken\\KästchenLeer32x32.png"); MusikKaestchenleer.SetImage(MusikKaestchenleerImage); sf::Event Event; sf::Input Input; while(*GameState == 4) { while(App->GetEvent(Event)) { if((Event.Type == sf::Event::KeyPressed)&&(Event.Key.Code == sf::Key::Escape)) { *GameState = 1; } if(Event.Type == sf::Event::MouseMoved) { MausX = static_cast<int>(App->GetInput().GetMouseX()); MausY = static_cast<int> (App->GetInput().GetMouseY()); } } if(MausX >= 480 && MausX <= 512 && MausY >= 350 && MausY <= 382 ) { if(App->GetInput().IsMouseButtonDown(sf::Mouse::Left)) { if(MusicStatus == 0) { MusikKaestchenleerImage.LoadFromFile("D:\\Entwicklung\\Laufende Projekte\\Projekt001\\Grafiken\\KästchenVoll32x32.png"); MusikKaestchenleer.SetImage(MusikKaestchenleerImage); PlayMusic(); MusicStatus=1; } if(MusicStatus == 1) { MusikKaestchenleerImage.LoadFromFile("D:\\Entwicklung\\Laufende Projekte\\Projekt001\\Grafiken\\KästchenLeer32x32.png"); MusikKaestchenleer.SetImage(MusikKaestchenleerImage); StopMusic(); MusicStatus=0; } } } App->Clear(sf::Color(0,0,0)); App->Draw(Background); App->Draw(MusikKaestchenleer); App->Display(); } }
-
MusikKaestchenleer.SetPosition(480,350);
, if(MausX >= 480 && MausX <= 512 && MausY >= 350 && MausY <= 382 )Passt nicht zusammen.. wieso verwendest du nicht MusikKaestchenleer.GetPosition.x() oder je nachdem wie es benannt ist?
Und mach Dir doch für diesen Test eine Funktion die Du als bsp. isPointInside nennen könntest... erleichtert das lesen des Codes später.
rya.
-
habe den fehler gefunden und der knopf läst sich nun drücken auch die musik wird dadurch abgespielt. ich erhalte aber nach wie vor eine fehlermeldung wenn das programm beendet wird hier ist mal der code in dem ich die musik funktionen habe.
#include <SFML/Audio.hpp> sf::Music Music; //Music Laden void LoadMusic() { Music.OpenFromFile("D:\\Entwicklung\\Laufende Projekte\\Projekt001\\Basil Poledouris - Hymn To Red October.ogg"); Music.SetLoop(true); }; //Music Abspielen void PlayMusic() { Music.Play(); Music.SetVolume(100); }; void DownMusic() { Music.SetVolume(0); }; void StopMusic() { Music.Stop(); };
die fehlermeldung lautet: die anwendung xyz verweisst auf speicher in xyz. der vorghang read konnte nicht auf dem speicher durchgeführt werden.
hoffe ihr könnt mir helfen
-
Du greifst irgendwo auf einen Speicherbereich zu der nicht mehr gültig ist.
Was sagt der Debugger?
rya.
-
ich hab mit dem debugger noch nie gearbeitet ich benutze code blocks kannst mir hilfestellugn damit geben?
Welche möglichkeiten habe ich um den fehler zu finden und wie funktioniert das?
es muss definitiv an der msuik liegen. habe den musik teil entfernt und dann erfolgt keine Warnung.
-
http://wiki.codeblocks.org/index.php?title=Debugging_with_Code::Blocks
Wo genau der Fehler liegt kann ich Dir von hier aus auch nicht sagen. Zumindest nicht mit dem Code den Du hier zeigst. Eventuell ist nach dem stoppen der MusikThread noch aktiv. Füge mal ein Sleep(1000) ein am Ende. Aber warum verwendest Du eigentlich keine Klassen? Dann könnte man wenigstens deine ganzen Globalen in einen Destruktor packen und gezielt zerstören bzw wüsste wann es zerstört wird.
rya.
-
wie meisnt du das mit sleep?
ich verwende noch keien klassen da ich mir das thema noch erst noch angucken mussich hab zwar schonmal reingeschnuppert aber mir fehlt noch das hintergrund wissenhier ist die main datei
#include <SFML/Graphics.hpp> #include "music.h" #include "Hauptmenü.h" #include "HMSpielBeenden.h" #include "Optionen.h" int main() { LoadMusic(); int MusicStatus = 0; int GameState = 1; sf::RenderWindow App(sf::VideoMode(1024,768,32), "Projekt 001",sf::Style::Fullscreen); App.SetFramerateLimit(60); //Hauptprogrammschleife while(App.IsOpened()) { if(MusicStatus == 1) PlayMusic();//Musik abspielen if(MusicStatus == 0) DownMusic();//Lautstärke auf 0 setzen if(GameState == 1) { Hauptmenue(&App,&GameState); } if(GameState == 2) { SpielBeenden(&App,&GameState); } if(GameState == 4) { Optionen(&App,&GameState,&MusicStatus); } }//Hauptprogrammschleife Ende StopMusic();//Music beenden return 0; }
hier der hauptmenü header
// Hier ist das Hauptmenü definiert.Grafiken und Buttonsteuerung #include <SFML/graphics.hpp> void Hauptmenue(sf::RenderWindow *App, int *GameState) { int MausX = 0; // Speichert Mausabfrage X int MausY = 0; // Speichert Mausabfrage X while(*GameState ==1) { ////// Ladender Grafiken/////////////////// //HintergrundGrafik sf::Image i_Background; i_Background.LoadFromFile("D:\\Entwicklung\\Laufende Projekte\\Projekt001\\Grafiken\\BGProjekt001.png"); sf::Sprite Background; Background.SetImage(i_Background); //Neues SpielButton sf::Image i_ButtonStart; i_ButtonStart.LoadFromFile("D:\\Entwicklung\\Laufende Projekte\\Projekt001\\Grafiken\\ButtonGameStartInactive240x60.png"); sf::Sprite ButtonStart; ButtonStart.SetImage(i_ButtonStart); ButtonStart.SetPosition(380,300); // Optionen Button sf::Image i_ButtonOption; i_ButtonOption.LoadFromFile("D:\\Entwicklung\\Laufende Projekte\\Projekt001\\Grafiken\\ButtonOptionenInactive240x60.png"); sf::Sprite ButtonOption; ButtonOption.SetImage(i_ButtonOption); ButtonOption.SetPosition(380,400); //BeendenButton sf::Image i_ButtonBeenden; i_ButtonBeenden.LoadFromFile("D:\\Entwicklung\\Laufende Projekte\\Projekt001\\Grafiken\\ButtonBeendenInactive240x60.png"); sf::Sprite ButtonBeenden; ButtonBeenden.SetImage(i_ButtonBeenden); ButtonBeenden.SetPosition(380,500); //Abfrage der Events im Hauptmenü sf::Event Event; sf::Input Input; //Hauptmenüschleife while(App->GetEvent(Event)) { if((Event.Type == sf::Event::KeyPressed)&&(Event.Key.Code == sf::Key::Escape)) { App->Close(); } if(Event.Type == sf::Event::MouseMoved) { MausX = static_cast<int>(App->GetInput().GetMouseX()); MausY = static_cast<int> (App->GetInput().GetMouseY()); } } // Abfrage ob die einzelnen Buttons gedrückt wurden // In den if-blöcken werden die Gamestates geändert if(MausX >= 397 && MausX <= 603 && MausY >= 317 && MausY <= 343 ) { i_ButtonStart.LoadFromFile("D:\\Entwicklung\\Laufende Projekte\\Projekt001\\Grafiken\\ButtonGameStartActive240x60.png"); ButtonStart.SetImage(i_ButtonStart); if(App->GetInput().IsMouseButtonDown(sf::Mouse::Left)) { *GameState = 3; } } if(MausX >= 397 && MausX <= 603 && MausY >= 417 && MausY <= 443 ) { i_ButtonOption.LoadFromFile("D:\\Entwicklung\\Laufende Projekte\\Projekt001\\Grafiken\\ButtonOptionenActive240x60.png"); ButtonOption.SetImage(i_ButtonOption); if(App->GetInput().IsMouseButtonDown(sf::Mouse::Left)) { *GameState = 4; } } if(MausX >= 397 && MausX <= 603 && MausY >= 517 && MausY <= 543 ) { i_ButtonBeenden.LoadFromFile("D:\\Entwicklung\\Laufende Projekte\\Projekt001\\Grafiken\\ButtonBeendenActive240x60.png"); ButtonBeenden.SetImage(i_ButtonBeenden); if(App->GetInput().IsMouseButtonDown(sf::Mouse::Left)) { *GameState = 2; } } // Zeichfunktionen des Hauptmenüs App->Draw(Background); App->Draw(ButtonStart); App->Draw(ButtonOption); App->Draw(ButtonBeenden); App->Display(); } }
und hier der spiel beenden header
void SpielBeenden(sf::RenderWindow *App, int *GameState) { int MausX = 0; // Speichert Mausabfrage X int MausY = 0; // Speichert Mausabfrage X while(*GameState == 2) { //Hintergrundbild Laden sf::Image i_Background; sf::Sprite Background; i_Background.LoadFromFile("D:\\Entwicklung\\Laufende Projekte\\Projekt001\\Grafiken\\BGProjekt001.png"); Background.SetImage(i_Background); //JA-Button Laden sf::Image i_ButtonJa; sf::Sprite ButtonJa; i_ButtonJa.LoadFromFile("D:\\Entwicklung\\Laufende Projekte\\Projekt001\\Grafiken\\ButtonJaInactive240x60.png"); ButtonJa.SetImage(i_ButtonJa); ButtonJa.SetPosition(380,300); //NEIN-Button Laden sf::Image i_ButtonNein; sf::Sprite ButtonNein; i_ButtonNein.LoadFromFile("D:\\Entwicklung\\Laufende Projekte\\Projekt001\\Grafiken\\ButtonNeinInactive240x60.png"); ButtonNein.SetImage(i_ButtonNein); ButtonNein.SetPosition(380,400); sf::Event Event; sf::Input Input; //Eventabfrage für SpielBeenden while(App->GetEvent(Event)) { if((Event.Type == sf::Event::KeyPressed)&&(Event.Key.Code == sf::Key::Escape)) { App->Close(); } if(Event.Type == sf::Event::MouseMoved) { MausX = static_cast<int>(App->GetInput().GetMouseX()); MausY = static_cast<int> (App->GetInput().GetMouseY()); } } //Maus-Abfrage für den Button Ja if(MausX >= 397 && MausX <= 603 && MausY >= 317 && MausY <= 343 ) { i_ButtonJa.LoadFromFile("D:\\Entwicklung\\Laufende Projekte\\Projekt001\\Grafiken\\ButtonJaActive240x60.png"); ButtonJa.SetImage(i_ButtonJa); if(App->GetInput().IsMouseButtonDown(sf::Mouse::Left)) { App->Close(); } } if(MausX >= 397 && MausX <= 603 && MausY >= 417 && MausY <= 443 ) { i_ButtonNein.LoadFromFile("D:\\Entwicklung\\Laufende Projekte\\Projekt001\\Grafiken\\ButtonNeinActive240x60.png"); ButtonNein.SetImage(i_ButtonNein); if(App->GetInput().IsMouseButtonDown(sf::Mouse::Left)) { *GameState = 1; } } App->Draw(Background); App->Draw(ButtonJa); App->Draw(ButtonNein); App->Display(); } }
und das ist der header für optionen ich aktiviere die musik nun in der hauptschleife und nicht mehr unter optionen
void Optionen(sf::RenderWindow *App, int *GameState,int *MusicStatus) { int MausX = 0; // Speichert Mausabfrage X int MausY = 0; // Speichert Mausabfrage X sf::Image BackgroundImage; sf::Sprite Background; BackgroundImage.LoadFromFile("D:\\Entwicklung\\Laufende Projekte\\Projekt001\\Grafiken\\BGProjekt001.png"); Background.SetImage(BackgroundImage); sf::Image MusikKaestchenleerImage; sf::Sprite MusikKaestchenleer; MusikKaestchenleer.SetPosition(480,350); MusikKaestchenleerImage.LoadFromFile("D:\\Entwicklung\\Laufende Projekte\\Projekt001\\Grafiken\\KästchenLeer32x32.png"); MusikKaestchenleer.SetImage(MusikKaestchenleerImage); sf::Event Event; sf::Input Input; while(*GameState == 4) { int pusched = 0; while(App->GetEvent(Event)) { if((Event.Type == sf::Event::KeyPressed)&&(Event.Key.Code == sf::Key::Escape)) { *GameState = 1; } if(Event.Type == sf::Event::MouseMoved) { MausX = static_cast<int>(App->GetInput().GetMouseX()); MausY = static_cast<int> (App->GetInput().GetMouseY()); } if(MausX >= 480 && MausX <= 512 && MausY >= 350 && MausY <= 382 && pusched == 0 ) { if(App->GetInput().IsMouseButtonDown(sf::Mouse::Left)) { if(*MusicStatus == 0&&pusched == 0) { MusikKaestchenleerImage.LoadFromFile("D:\\Entwicklung\\Laufende Projekte\\Projekt001\\Grafiken\\KästchenVoll32x32.png"); MusikKaestchenleer.SetImage(MusikKaestchenleerImage); *MusicStatus=1; pusched = 1; } if(*MusicStatus == 1 && pusched == 0) { MusikKaestchenleerImage.LoadFromFile("D:\\Entwicklung\\Laufende Projekte\\Projekt001\\Grafiken\\KästchenLeer32x32.png"); MusikKaestchenleer.SetImage(MusikKaestchenleerImage); *MusicStatus=0; pusched = 1; } } } } App->Clear(sf::Color(0,0,0)); App->Draw(Background); App->Draw(MusikKaestchenleer); App->Display(); } }
-
Saibot1988 schrieb:
wie meisnt du das mit sleep?
ich verwende noch keien klassen da ich mir das thema noch erst noch angucken mussich hab zwar schonmal reingeschnuppert aber mir fehlt noch das hintergrund wissenAm Rande. Die ; am Ende jeder Funktion sind unnötiger Tand.
#include <SFML/Audio.hpp> class MyMusic { private: sf::Music Music; public: //Music Laden void LoadMusic() { Music.OpenFromFile("D:\\Entwicklung\\Laufende Projekte\\Projekt001\\Basil Poledouris - Hymn To Red October.ogg"); Music.SetLoop(true); } //Music Abspielen void PlayMusic() { Music.Play(); Music.SetVolume(100); } void DownMusic() { Music.SetVolume(0); } void StopMusic() { Music.Stop(); } };
Das wäre jetzt das ganze als Klasse ;).
Aber vllt solltest Du Dich erstmal mehr mit der Sprache auseinandersetzen :).
Und wie gesagt, ich rate hier ins blaue. An dem Code ist an sich nichts falsch, nur globale Variablen sollte man vermeiden. Eine Klasse lebt nur so lange wie das Objekt oder die Funktion das diese enthält. Instanzier diese Klasse, verwende sie und schau mal obs dann geht.
rya.
-
haha geht ^^ danke schön ich werd bald klassen einsetzen bin in meinem buch bald soweit. ich habe das früher alles schonmal durch gemacht in tutorials nur das war nicht so gründlich
eine frage hätte ich noch.
angenommen ich lade jetzt im hauptmenü ein bild und lege ein sprite an wird dieses dann beim verlassen der hauptmenü funktion wieder gelöscht oder bleibt es bestehen ? wenn ja wie lösche ich es unter sfml wieder?
-
http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization
Les das hier.
Wenn du innerhalb einer Funktion eine Variable anlegst, dann wird diese beim verlassen zerstört. Ich weiss jetzt nicht ob sfml das noch irgendwo anders speichert oder so, aber im Prinzip ist das Sprite weg, sobald es zerstört wird.
Beispielvoid MyFunc() { sf::Audio audio; }
Nach verlassen von MyFunc ist das Objekt audio nicht mehr existent. Kann also auch nix machen. Deswegen gab Bjarne uns Klassen. In denen kannst Du Mitglieder speichern und behalten bis Du das Objekt nicht mehr brauchst. Oder Du legst Dir einen zeiger an den Du weitergibst und zerstörst den am Ende deines Programmes.
Aber les bitte Deine Bücher zu dem Thema. Für die Spieleprogrammierung ist eben eine gute Kenntnis der Sprache nötig. Man muss nicht der Uberpro sein, das bin ich auch nicht, aber die Grundlagen wie Klassen, Zeiger und Verhalten von Objekten sollte man wissen bevor man sich ranwagt.
rya.
-
werds mir merken danke für die hilfe nochma also ähm .... däumchen