Gibas11 Temat założony przez niniejszego użytkownika |
Błąd podczas usuwania elementu vectora » 2015-09-11 21:38:52 Jak w tytule, mam klasę, zawierającą vector innej klasy i gdy chcę usunąć któryś element dostaję taki komunikat: pure virtual method called terminate called without an active exception Aborted
Problem leży w linijce 313 w funkcji meteor::contains (linijka pod tą zakomentowaną). Mam na razie rozwiązanie na około z ustawianiem zmiennej exist na false w każdym elemencie do usunięcia i pomijaniem go przy jakichkolwiek operacjach, ale wolałbym go jednak usuwać. #ifndef SPACEOBJECTS_H_INCLUDED #define SPACEOBJECTS_H_INCLUDED
namespace space { sf::RenderTexture rt; class meteorPart { public: sf::Color color; sf::CircleShape hexagon; bool right = true; bool left = true; bool upDown = true; bool Rotated; bool exist; int HP; void create( sf::Color mask, sf::Vector2f pos, bool rotated, int polygons, int hp ); }; void meteorPart::create( sf::Color mask, sf::Vector2f pos, bool rotated, int polygons, int hp ) { hexagon = sf::CircleShape( 29, polygons ); hexagon.setFillColor( mask ); hexagon.setOrigin( 20, 29 ); hexagon.setPosition( pos ); Rotated = rotated; exist = true; HP = hp; hexagon.setRotation(( int ) rotated * 60 ); } class meteor : public sf::Drawable { public: vector < meteorPart > meteorParts; void startCreating( int m, sf::Vector2f Pos, int Polygons, int partsPerClock ); void create(); void update(); void destroy(); void setColor( sf::Color color ); void move( sf::Vector2f vect ); void move( float x, float y ); void move(); void push( sf::Vector2f vect, int mass ); bool contains( sf::Vector2f point, int damage ); sf::Color getColor(); sf::Vector2f getPosition(); bool created = false; bool creating = false; bool destroyed = false; bool moving; int lastDamage; sf::Vector2f pos; private: float momentumX; float momentumY; sf::Texture texture; sf::Sprite sprite; sf::FloatRect rect; virtual void draw( sf::RenderTarget & target, sf::RenderStates states ) const; unsigned int targetParts = 0; unsigned int currentParts = 0; unsigned int polygons; unsigned int parts; unsigned int HPPerPart = 40; int poz1P[ 2 ] = { 29, - 22 }; int poz1L[ 2 ] = { - 20, - 22 }; int poz1B[ 2 ] = { 4, 21 }; int poz2P[ 2 ] = { 20, 22 }; int poz2L[ 2 ] = { - 29, 22 }; int poz2U[ 2 ] = { - 4, - 21 }; }; void meteor::startCreating( int m, sf::Vector2f Pos, int Polygons, int partsPerClock ) { targetParts = m; pos = Pos; polygons = Polygons; created = false; parts = partsPerClock; creating = true; moving = false; momentumX = 0.f; momentumY = 0.f; } void meteor::create() { if( currentParts == targetParts ) { created = true; creating = false; return; } for( unsigned int i = 0; currentParts < targetParts and i < parts; i++ ) { if( currentParts == 0 ) { int i = 85; meteorPart tmp; meteorParts.push_back( tmp ); meteorParts[ meteorParts.size() - 1 ].create( sf::Color( i, i, i, 50 ), pos, true, polygons, HPPerPart ); currentParts++; } else { for( bool done = false; !done; ) { int addTo = rand() % currentParts; if( meteorParts[ addTo ].right or meteorParts[ addTo ].left or meteorParts[ addTo ].upDown ) { bool rotated = !meteorParts[ addTo ].Rotated; sf::Vector2f pos = meteorParts[ addTo ].hexagon.getPosition(); int strona = rand() % 3; for( bool Done = false; !Done; ) { if( strona == 0 ) { if( !meteorParts[ addTo ].right ) strona++; else { if( meteorParts[ addTo ].Rotated ) { pos.x += poz2P[ 0 ]; pos.y += poz2P[ 1 ]; } else { pos.x += poz1P[ 0 ]; pos.y += poz1P[ 1 ]; } meteorParts[ addTo ].right = false; Done = true; } } if( strona == 1 ) { if( !meteorParts[ addTo ].left ) strona++; else { if( meteorParts[ addTo ].Rotated ) { pos.x += poz2L[ 0 ]; pos.y += poz2L[ 1 ]; } else { pos.x += poz1L[ 0 ]; pos.y += poz1L[ 1 ]; } meteorParts[ addTo ].left = false; Done = true; } } if( strona == 2 ) { if( !meteorParts[ addTo ].upDown ) strona = 0; else { if( meteorParts[ addTo ].Rotated ) { pos.x += poz2U[ 0 ]; pos.y += poz2U[ 1 ]; } else { pos.x += poz1B[ 0 ]; pos.y += poz1B[ 1 ]; } meteorParts[ addTo ].upDown = false; Done = true; } } } int i = 85; meteorPart tmp; meteorParts.push_back( tmp ); meteorParts[ currentParts ].create( sf::Color( i, i, i, 50 ), pos, rotated, polygons, HPPerPart ); if( strona == 0 ) meteorParts[ currentParts ].left = false; if( strona == 1 ) meteorParts[ currentParts ].right = false; if( strona == 2 ) meteorParts[ currentParts ].upDown = false; currentParts++; done = true; } } } } if( currentParts == targetParts ) update(); } void meteor::draw( sf::RenderTarget & target, sf::RenderStates states ) const { for( unsigned int i = 0; i < currentParts; i++ ) target.draw( meteorParts[ i ].hexagon, states ); } void meteor::destroy() { meteorParts.clear(); currentParts = 0; destroyed = true; } void meteor::move( float x, float y ) { sf::Vector2f vect( x, y ); for( unsigned int i = 0; i < currentParts; i++ ) meteorParts[ i ].hexagon.setPosition( meteorParts[ i ].hexagon.getPosition() + vect ); update(); pos += vect; } void meteor::move( sf::Vector2f vect ) { for( unsigned int i = 0; i < currentParts; i++ ) meteorParts[ i ].hexagon.setPosition( meteorParts[ i ].hexagon.getPosition() + vect ); update(); pos += vect; } void meteor::move() { sf::Vector2f vect = sf::Vector2f( momentumX, momentumY ); for( unsigned int i = 0; i < currentParts; i++ ) meteorParts[ i ].hexagon.setPosition( meteorParts[ i ].hexagon.getPosition() + vect ); update(); pos += vect; } void meteor::push( sf::Vector2f vect, int mass ) { momentumX +=( vect.x * mass ) / currentParts; momentumY +=( vect.y * mass ) / currentParts; moving = true; } void meteor::setColor( sf::Color color ) { for( unsigned int i = 0; i < currentParts; i++ ) meteorParts[ i ].hexagon.setFillColor( color ); } sf::Color meteor::getColor() { return meteorParts[ 0 ].hexagon.getFillColor(); } sf::Vector2f meteor::getPosition() { return pos; } bool meteor::contains( const sf::Vector2f point, int damage ) { if( rect.contains( point ) ) { bool any = false; for( int i = meteorParts.size() - 1; i >= 0; i-- ) { if( meteorParts[ i ].hexagon.getGlobalBounds().contains( point ) and meteorParts[ i ].exist ) { int tmpHP = meteorParts[ i ].HP; meteorParts[ i ].HP -= damage; if( meteorParts[ i ].HP < 0 ) meteorParts[ i ].HP = 0; if( meteorParts[ i ].HP == 0 ) meteorParts.erase( meteorParts.begin() + i ); lastDamage = tmpHP - meteorParts[ i ].HP; any = true; break; } } bool existBuf = false; for( int i = meteorParts.size() - 1; i >= 0; i-- ) { if( !meteorParts[ i ].exist ) meteorParts[ i ].hexagon.setFillColor( sf::Color( 0, 0, 0, 0 ) ); else existBuf = true; } if( !existBuf ) destroy(); return any; } else return false; } void meteor::update() { int top = pos.y; int bottom = pos.y; int right = pos.x; int left = pos.x; for( unsigned int i = 0; i < currentParts; i++ ) { sf::Vector2f tmp = meteorParts[ i ].hexagon.getPosition(); if( tmp.y < top ) top = tmp.y; if( tmp.y > bottom ) bottom = tmp.y; if( tmp.x < left ) left = tmp.x; if( tmp.x > right ) right = tmp.x; } rect.top = top - 30; rect.height =( bottom - top ) + 30; rect.left = left - 30; rect.width =( right - left ) + 30; } bool anyCreating = false; };
vector < space::meteor > meteors;
#endif
|
|
Lora |
» 2015-09-11 22:33:25 if( meteorParts[ i ].HP == 0 ) meteorParts.erase( meteorParts.begin() + i );
lastDamage = tmpHP - meteorParts[ i ].HP;
Usuwasz element wektora, a później się do niego odwołujesz. |
|
Gibas11 Temat założony przez niniejszego użytkownika |
» 2015-09-11 23:04:53 O, rzeczywiście. :) Niestety po poprawieniu tego co napisałeś błąd dalej występował, trzeba było jeszcze dopisać po usuwaniu elementu, ponieważ funkcja update, korzystała z tej zmiennej, a nie sprawdzała rozmiar tablicy. :/ Po poprawieniu tych 2 błędów kod jest w pełni sprawny, dziękuję za pomoc i dla zainteresowanych zamieszczam poniżej: #ifndef SPACEOBJECTS_H_INCLUDED #define SPACEOBJECTS_H_INCLUDED
namespace space { sf::RenderTexture rt; class meteorPart { public: sf::Color color; sf::CircleShape hexagon; bool right = true; bool left = true; bool upDown = true; bool Rotated; int HP; void create( sf::Color mask, sf::Vector2f pos, bool rotated, int polygons, int hp ); }; void meteorPart::create( sf::Color mask, sf::Vector2f pos, bool rotated, int polygons, int hp ) { hexagon = sf::CircleShape( 29, polygons ); hexagon.setFillColor( mask ); hexagon.setOrigin( 20, 29 ); hexagon.setPosition( pos ); Rotated = rotated; HP = hp; hexagon.setRotation(( int ) rotated * 60 ); } class meteor : public sf::Drawable { public: vector < meteorPart > meteorParts; void startCreating( int m, sf::Vector2f Pos, int Polygons, int partsPerClock ); void create(); void update(); void destroy(); void setColor( sf::Color color ); void move( sf::Vector2f vect ); void move( float x, float y ); void move(); void push( sf::Vector2f vect, int mass ); bool contains( sf::Vector2f point, int damage ); sf::Color getColor(); sf::Vector2f getPosition(); bool created = false; bool creating = false; bool destroyed = false; bool moving; sf::Vector2f pos; private: float momentumX; float momentumY; sf::Texture texture; sf::Sprite sprite; sf::FloatRect rect; virtual void draw( sf::RenderTarget & target, sf::RenderStates states ) const; unsigned int targetParts = 0; unsigned int currentParts = 0; unsigned int polygons; unsigned int parts; unsigned int HPPerPart = 40; int poz1P[ 2 ] = { 29, - 22 }; int poz1L[ 2 ] = { - 20, - 22 }; int poz1B[ 2 ] = { 4, 21 }; int poz2P[ 2 ] = { 20, 22 }; int poz2L[ 2 ] = { - 29, 22 }; int poz2U[ 2 ] = { - 4, - 21 }; }; void meteor::startCreating( int m, sf::Vector2f Pos, int Polygons, int partsPerClock ) { targetParts = m; pos = Pos; polygons = Polygons; created = false; parts = partsPerClock; creating = true; moving = false; momentumX = 0.f; momentumY = 0.f; } void meteor::create() { if( currentParts == targetParts ) { created = true; creating = false; return; } for( unsigned int i = 0; currentParts < targetParts and i < parts and !created; i++ ) { if( currentParts == 0 ) { int i = 85; meteorPart tmp; meteorParts.push_back( tmp ); meteorParts[ meteorParts.size() - 1 ].create( sf::Color( i, i, i, 50 ), pos, true, polygons, HPPerPart ); currentParts++; } else { for( bool done = false; !done; ) { int addTo = rand() % currentParts; if( meteorParts[ addTo ].right or meteorParts[ addTo ].left or meteorParts[ addTo ].upDown ) { bool rotated = !meteorParts[ addTo ].Rotated; sf::Vector2f pos = meteorParts[ addTo ].hexagon.getPosition(); int strona = rand() % 3; for( bool Done = false; !Done; ) { if( strona == 0 ) { if( !meteorParts[ addTo ].right ) strona++; else { if( meteorParts[ addTo ].Rotated ) { pos.x += poz2P[ 0 ]; pos.y += poz2P[ 1 ]; } else { pos.x += poz1P[ 0 ]; pos.y += poz1P[ 1 ]; } meteorParts[ addTo ].right = false; Done = true; } } if( strona == 1 ) { if( !meteorParts[ addTo ].left ) strona++; else { if( meteorParts[ addTo ].Rotated ) { pos.x += poz2L[ 0 ]; pos.y += poz2L[ 1 ]; } else { pos.x += poz1L[ 0 ]; pos.y += poz1L[ 1 ]; } meteorParts[ addTo ].left = false; Done = true; } } if( strona == 2 ) { if( !meteorParts[ addTo ].upDown ) strona = 0; else { if( meteorParts[ addTo ].Rotated ) { pos.x += poz2U[ 0 ]; pos.y += poz2U[ 1 ]; } else { pos.x += poz1B[ 0 ]; pos.y += poz1B[ 1 ]; } meteorParts[ addTo ].upDown = false; Done = true; } } } int i = 85; meteorPart tmp; meteorParts.push_back( tmp ); meteorParts[ currentParts ].create( sf::Color( i, i, i, 50 ), pos, rotated, polygons, HPPerPart ); if( strona == 0 ) meteorParts[ currentParts ].left = false; if( strona == 1 ) meteorParts[ currentParts ].right = false; if( strona == 2 ) meteorParts[ currentParts ].upDown = false; currentParts++; done = true; } } } } if( currentParts == targetParts ) update(); } void meteor::draw( sf::RenderTarget & target, sf::RenderStates states ) const { for( unsigned int i = 0; i < currentParts; i++ ) target.draw( meteorParts[ i ].hexagon, states ); } void meteor::destroy() { meteorParts.clear(); currentParts = 0; destroyed = true; } void meteor::move( float x, float y ) { sf::Vector2f vect( x, y ); for( unsigned int i = 0; i < currentParts; i++ ) meteorParts[ i ].hexagon.setPosition( meteorParts[ i ].hexagon.getPosition() + vect ); update(); pos += vect; } void meteor::move( sf::Vector2f vect ) { for( unsigned int i = 0; i < currentParts; i++ ) meteorParts[ i ].hexagon.setPosition( meteorParts[ i ].hexagon.getPosition() + vect ); update(); pos += vect; } void meteor::move() { sf::Vector2f vect = sf::Vector2f( momentumX, momentumY ); for( unsigned int i = 0; i < currentParts; i++ ) meteorParts[ i ].hexagon.setPosition( meteorParts[ i ].hexagon.getPosition() + vect ); update(); pos += vect; } void meteor::push( sf::Vector2f vect, int mass ) { momentumX +=( vect.x * mass ) / currentParts; momentumY +=( vect.y * mass ) / currentParts; moving = true; } void meteor::setColor( sf::Color color ) { for( unsigned int i = 0; i < currentParts; i++ ) meteorParts[ i ].hexagon.setFillColor( color ); } sf::Color meteor::getColor() { return meteorParts[ 0 ].hexagon.getFillColor(); } sf::Vector2f meteor::getPosition() { return pos; } bool meteor::contains( const sf::Vector2f point, int damage ) { if( rect.contains( point ) ) { bool any = false; for( int i = meteorParts.size() - 1; i >= 0; i-- ) { if( meteorParts[ i ].hexagon.getGlobalBounds().contains( point ) ) { meteorParts[ i ].HP -= damage; if( meteorParts[ i ].HP < 0 ) meteorParts[ i ].HP = 0; if( meteorParts[ i ].HP == 0 ) { meteorParts.erase( meteorParts.begin() + i ); currentParts--; } any = true; break; } } if( meteorParts.size() == 0 ) destroy(); return any; } else return false; } void meteor::update() { int top = pos.y; int bottom = pos.y; int right = pos.x; int left = pos.x; for( unsigned int i = 0; i < currentParts; i++ ) { sf::Vector2f tmp = meteorParts[ i ].hexagon.getPosition(); if( tmp.y < top ) top = tmp.y; if( tmp.y > bottom ) bottom = tmp.y; if( tmp.x < left ) left = tmp.x; if( tmp.x > right ) right = tmp.x; } rect.top = top - 30; rect.height =( bottom - top ) + 30; rect.left = left - 30; rect.width =( right - left ) + 30; } bool anyCreating = false; };
vector < space::meteor > meteors;
#endif
|
|
« 1 » |