SFML-Löschproblem von iterator(bei Schüssen)



  • Hallo Community,
    ich bin noch relativ neu im Sfml-Gebiet und bin gerade dabei ein eigenes kleines Spiel zu Programmieren in dem man mit einem Raumschiff Asteroide abschießen kann.
    Die Klasse von meinen Asteroiden ist fast gleich aufgebaut, doch der einzige Unterschied ist, dass die Asteroiden- Listeobjekte beim Verlassen des Bildschirms gelöscht werden und es funktioniert, die Schüsse aber bei Verlassen des Bildschirm ein Problem hervorrufen und dass Programm einen error meldet.

    Bitte um Hilfe 🙂

    Schuss.cpp

    #include "Schuss.hpp"
    
    Shot::Shot(std::string imagepath)
    {
    	sf::Image I;
    	I.loadFromFile(imagepath);
    	I.createMaskFromColor(sf::Color::White);
    
    	TShot.loadFromImage(I);
    	TShot.setSmooth(false);
    
    }
    
    void Shot::Update(float XPos, float YPos)
    {
    	if (sf::Keyboard::isKeyPressed(sf::Keyboard::Space) && SpawnTimer.getElapsedTime().asSeconds() > 0.1)
    	{
    		sf::Sprite *SShot;
    		SShot = new sf::Sprite;
    
    		SShot->setTexture(TShot);
    		SShot->setPosition(XPos, YPos);
    
    		ShotList.push_back(*SShot);
    		std::cout << "Schusse: " << ShotList.size() << std::endl;
    		SpawnTimer.restart();
    	}
    
    }
    
    void Shot::Render(sf::RenderWindow *rw, float Frametime, std::list<sf::Sprite>::iterator *AsteroidIt)
    {
    	for (ShotIt = ShotList.begin(); ShotIt != ShotList.end(); ShotIt++)
    	{
    		ShotIt->move(0, -12000 * Frametime);
    
    		if (ShotIt->getPosition().y < -20)
    		{
    			ShotList.erase(ShotIt);
    			ShotIt = ShotList.begin();
    		}
    
    		rw->draw(*ShotIt);
    
    	}
    
    }
    


  • dass Programm einen error meldet

    Lass mich raten: der Fehler wird auf russisch angezeigt. Oder warum postest du nicht die Fehlermeldung?

    SShot = new sf::Sprite;
    

    Wo ist dein delete? Memory Leak!

    if (ShotIt->getPosition().y < -20) 
             { 
                 ShotList.erase(ShotIt); 
                 ShotIt = ShotList.begin(); 
             } 
    
             rw->draw(*ShotIt); 
    
         }
    

    Was wenn ShotList eer ist und ShotIt keine Elemente enthaelt? Ausserdem sollte erase einen Iterator zurueckliefern, der auf das naechste Element zeigt. Es ist nicht noetig, staendig von vorne anzufangen.
    [coo]std::listsf::Sprite::iterator *AsteroidIt[/cpp]Mir ist auch voellig unklar, warum man einen Zeiger auf einen Iterator braucht. Psst: rhetorische Frage.



  • Hier ist die Fehlermeldung:

    Debug Assertion Failed!
    
    Program: C:\Windows\system32\MSVCP120D.dll
    File: c:\program files (x86)\microsoft visual studio 12.0\vc\include\list
    Line: 210
    
    Expression: list iterator not dereferencable
    
    For information on how your program can cause an assertion
    failure, see the Visual C++ documentation on asserts.
    


  • erase und for-Schleife beißt sich.



  • Wie funktioniert es dann bei meiner Asteroiden-Klasse?



  • Mach drei Schritte draus:

    1. Alle bewegen.
    2. Löschen, was weg muss. Nimm erase und remove_if, das ist erprobt.
    3. Zeichnen, was noch übrig ist.



  • Ok danke für die Hilfe:)


Log in to reply