SFML Objekt laden



  • Hallo Leute,
    es geht um folgendes: Ich hab vor kurzem mit SFML angefangen. Nun habe ich mir ein kleines Programm geschrieben, in dem ich einfach einen Sprite einer Textur erstelle, welchen man einfach mit den Pfeiltastet bewegen kann.

    Texture txtMensch;
    txtMensch.loadFromFile("bild.png");
    
    Sprite sprtMensch(txtMensch);
    ...
    

    Wenn ich das ganze jetzt aber in Klassen machen möchte, funktioniert es nicht mehr. Ich erstelle dann eine header-Datei namens mensch.h und eine klasse namens Mensch. Ich schreibe dann als Parameter beim Konstruktor String texPfad.

    #include <SFML\Graphics.hpp>
    #include <iostream>
    
    using namespace sf;
    
    class Mensch
    {
    public:
    	void Update	(RenderWindow &Window, float ElapsedTime);
    	void Render	(RenderWindow &Window);
    	Raumschiff	(String texPfad);
    private:
    	float Speed;
    	Texture Textur;
    	Sprite Sprite;
    };
    

    Wenn ich dann in der mensch.cpp im Konstruktor schreibe:

    #include "mensch.h"
    
    Mensch::Mensch(String texPfad){
    	Textur.loadFromFile(texPfad);
    }
    

    und das ganze in der main.cpp verwende:

    //     MAIN_CPP     //
    
    #include <SFML\Graphics.hpp>
    #include "mensch.h"
    
    using namespace sf;
    
    int main(){
    
    	RenderWindow winWindow(VideoMode(1200,800), "YSSupergame");
    	Mensch objektMensch("bild.png");
    
    	//     HAUPTSCHLEIFE     //
    	while(winWindow.isOpen()){
    
    		//     EVENTS     //
    		Event evtWindow;
    
    		while(winWindow.pollEvent(evtWindow)){
    			if(evtWindow.type == Event::Closed) winWindow.close();
    		}
    		//
    
    		winWindow.clear(Color::White);
    		//objektMensch.Update(winWindow, ElapsedTime);
    		//objektMensch.Render(winWindow);
    		winWindow.display();
    	}
    
    	return 0;
    }
    

    dann bekomm ich nicht direkt eine Fehlermeldung, sondern erst, wenn sich die Konsole schon geöffnet hat und das fenster gerendert wurde. Dann bekomm ich folgendes:
    Windows hat einen Haltepunkt in YSSupergame.exe ausgelöst.

    Dies kann auf eine Beschädigung des Heaps zurückzuführen sein, die auf ein Problem in YSSupergame.exe oder in einer der geladenen DLLs hinweist.

    Dies kann auch darauf zurückzuführen sein, dass der Benutzer F12 drückt, während YSSupergame.exe den Fokus hat.

    Weitere Analyseinformationen finden Sie möglicherweise im Ausgabefenster.
    Unterbrechen Weiter Ignorieren, wobei der ignorieren button nicht gedrückt werden kann...

    ich hoffe ihr versteht mein anliegen und bedanke mich im vorraus schon einmal...
    PS. Ja ich bin noch ein absoluter Anfänger 😃

    lg YS



  • Deine Klasse Mensch hat keinen Konstruktor für Mensch, sondern für Raumschiff.

    Außerdem übergibst du einen String, aber ich denke, dass ein std::string korrekter wäre.



  • Mhh ja sorry... ich habe 2 Projekte, eins mit einnem kleinem männchen und eins mit einem Raumschiff... Da hab ich mich beim rauskopieren wohl bisschen verzettelt... 😉

    Aber der String hat nicht den Namespace std::, sondern sf:: da er von SFML ist.

    Danke aber für die schnelle Antwort 😉 🙂



  • Ok, ich poste mal den kompletten Quellcode vom Raumschiffprojekt:

    main.cpp

    //     MAIN_CPP     //
    
    #include <SFML\Graphics.hpp>
    #include "raumschiff.h"
    
    using namespace sf;
    
    int main(){
    
    	RenderWindow winWindow(VideoMode(1200,800), "YSSupergame");
    	Raumschiff objRaumschiff("rocet.png");
    	Clock clock;
    
    	//     HAUPTSCHLEIFE     //
    	while(winWindow.isOpen()){
    
    		float ElapsedTime = 2; //clock.restart().asMilliseconds(); <- konnte nicht in eine floatVariable Convertirt werden //
    
    		//     EVENTS     //
    		Event evtWindow;
    
    		while(winWindow.pollEvent(evtWindow)){
    			if(evtWindow.type == Event::Closed) winWindow.close();
    		}
    		//
    
    		winWindow.clear(Color::White);
    		objRaumschiff.Update(winWindow, ElapsedTime);
    		objRaumschiff.Render(winWindow);
    		winWindow.display();
    	}
    
    	return 0;
    }
    

    raumschiff.h

    #include <SFML\Graphics.hpp>
    #include <iostream>
    
    using namespace sf;
    
    class Raumschiff
    {
    public:
    	void Update	(RenderWindow &Window, float ElapsedTime);
    	void Render	(RenderWindow &Window);
    	Raumschiff	(String texPfad);
    private:
    	float Speed;
    	Texture Textur;
    	Sprite Sprite;
    };
    

    raumschiff.cpp

    #include "raumschiff.h"
    
    Raumschiff::Raumschiff(String texPfad){
    
    	Speed = 1;
    	if(!Textur.loadFromFile(texPfad)){
    		std::cout << "ERROR::Textur konnte nicht geladen werden." << std::endl;
    	}else{
    		std::cout << "Textur erfolgreich geladen." << std::endl;
    	}
    
    	Textur.setSmooth(false);
    	Sprite.setTexture(Textur);
    	Sprite.setOrigin(400.f,254.f);
    	Sprite.setPosition(160.f,120.f);
    }
    
    void Raumschiff::Update(RenderWindow &Window, float ElapsedTime){
    	if(Keyboard::isKeyPressed(Keyboard::Up)){
    		Sprite.move(0,-Speed*ElapsedTime);
    	}
    }
    
    void Raumschiff::Render(RenderWindow &Window){
    	Window.draw(Sprite);
    }
    

    Wenn ich jetzt allerdings den Teil aus der raumschiff.cpp ändere:

    if(!Textur.loadFromFile("rocet.png")){ // Der Pfad wurde von texString in "rocet.png" geändert
    		std::cout << "ERROR::Textur konnte nicht geladen werden." << std::endl;
    	}else{
    		std::cout << "Textur erfolgreich geladen." << std::endl;
    	}
    

    funktioniert das ganze. 🙂 😉

    😉



  • Wie gesagt, probier doch mal aus, dass du std::string nutzt ( #include <string> nicht vergessen):

    Raumschiff  (std::string texPfad);
    


  • 👍
    Funktioniert... DANKEEEE 🙂 🙂
    aber warum ist das so ? 😃
    es geht auch nur wenn ich string klein schreibe... aber string hat doch nichts mit iostream zu tun !?
    Übrigens, ich muss <string> nicht ncludieren 😉
    Keine Ahnung wieso, aber es Funktioniert 😉 😃 🙂 👍 👍 😃



  • Es gibt sf::String (aus SFML) und std::string (aus der C++ Standardbibliothek).

    Das sf::String ist nur eine Klasse, die einen Text darstellt, den man dann auch mit SFML rendern lassen kann. Zum Beispiel um die Anzahl der Leben zu rendern oder so...

    Das heißt, sf::String hat mit einem std::string so gut wie gar nichts gemeinsam und die Funktion loadFromFile erwartet einen std::string, kann also mit einem sf::String nichts anfangen. Siehst du auch in der Doku:
    http://www.sfml-dev.org/documentation/2.0/classsf_1_1Texture.php#a8e1b56eabfe33e2e0e1cb03712c7fcc7

    Na ja, jedenfalls bietet sf::String aber auch Funktionen, usw. an um daraus einen std::string zu machen. Und genau das ist wohl auch passiert und deshalb ist das Programm problemlos kompiliert. Warum es dann abgestürzt ist, keine Ahnung, vielleicht war SFML noch nicht fertig geladen oder so.

    Es ist auch recht wichtig, dass du immer sf::RenderWindow als erstes schreibst und erst danach Objekte von SFML erzeugst. Ich glaube nämlich, dass mit dem erzeugen des Windows erst der ganze Krams benutztbar ist...



  • Okay... das hört sich logisch an... 😉
    VIIEEELEN DANK 😉
    jetzt noch eine kleine frage 😃

    In der main.cpp findet man dies hier 😃 Ich bekomme einfach die millisekunden nicht in eine float variable 😃

    float ElapsedTime = 2; //clock.restart().asMilliseconds(); <- konnte nicht in eine floatVariable Convertirt werden //
    

    Sprich: ich möchte eigentlich das hier haben:

    float ElapsedTime = clock.restart().asMilliseconds();
    


  • Rechne einfach mit Sekunden. Da bekommst du ein float zurück und dann ist die Konvertierung kein Problem, weil float nicht mehr in float konvertiert werden muss.

    Sprich:

    float ElapsedTime = clock.restart().asSeconds();
    


  • Okay... funktioniert nun auch... jetzt musste ich nur gewaltig meine speed variable erhöhen 😃 aber geht jetzt 😉
    Vielen danke nochmals 😉 hat mir wirklich sehr geholfen ;))



  • gjkhjkhjk schrieb:

    Das sf::String ist nur eine Klasse, die einen Text darstellt, den man dann auch mit SFML rendern lassen kann.

    Du musst aufpassen. Das war in SFML 1.6 so, diese Version ist aber schon seit Jahren veraltet.

    In SFML 2 gibt es sf::String , eine Klasse, welche die Konvertierung von und zu mehreren Stringformaten zulässt. Ausserdem gibt es sf::Text , was zur grafischen Darstellung von Text verwendet wird.

    ghjghjghj schrieb:

    float ElapsedTime = clock.restart().asSeconds();
    

    Warum nicht gleich den dafür entwickelten Typen sf::Time verwenden? Dann wird dein Code aussagekräftiger und typsicherer. Bei Bedarf kannst du immer noch lokal zu float konvertieren.

    sf::Time elapsedTime = clock.restart();
    

    Von using namespace ist übrigens abzuraten, ganz besonders im Header!



  • Es ist auch nicht sonderlich klug, dass jedes Raumschiff eine eigene Kopie der Textur hat.


Anmelden zum Antworten