4 votes

Debug Assertion Failed lors de la construction du blueprint SFML Asteroid game ?

J'ai essayé de suivre le livre SFML Blueprint. J'ai réussi à supprimer toutes les erreurs mais une erreur subsiste dans le code. J'ai essayé de trouver l'erreur debug-assertion-failed. Je pense que ce problème est dû au fait que l'une des listes est vidée.

The program crashes

The visual studio debugger says

Mon code pour le world.cpp

#include "World.h"
#include "Entity.h"

World::World(int x, int y) : _x(x), _y(y) {}
World::~World() { clear(); }

void World::add(Entity* entity){
_entities_tmp.push_back(entity);
}

void World::clear()
{
for (Entity* entity : _entities)
    delete entity;
_entities.clear();
for (Entity* entity : _entities_tmp)
    delete entity;
_entities_tmp.clear();
_sounds.clear();
}

void World::add(Configuration::Sounds sound_id){
std::unique_ptr<sf::Sound> sound(new    sf::Sound(Configuration::sounds.get(sound_id)));
sound->setAttenuation(0);
sound->play();
_sounds.emplace_back(std::move(sound));

}

bool World::isCollide(const Entity& other)
{
for (Entity* entity_ptr : _entities)

    if (other.isCollide(*entity_ptr))
        return true;
    return false;

}

int World::size() {
return _entities.size() + _entities_tmp.size();
}
int World::getX() const{
return _x;
}
int World::getY() const{
return _y;
}

const std::list<Entity*> World::getEntities() const {
return _entities;
}

void World::update(sf::Time deltaTime)
{
if (_entities_tmp.size() > 0)
    _entities.merge(_entities_tmp);
for (Entity* entity_ptr : _entities)
{
    Entity& entity = *entity_ptr;
    entity.update(deltaTime);
    sf::Vector2f pos = entity.getPosition();
    if (pos.x < 0)
    {
        pos.x = _x;
        pos.y = _y - pos.y;
    }
    else if (pos.x > _x)
    {
        pos.x = 0;
        pos.y = _y - pos.y;
    }
    if (pos.y < 0)
        pos.y = _y;
    else if (pos.y > _y)
        pos.y = 0;
    entity.setPosition(pos);
}
const auto end = _entities.end();
for (auto it_i = _entities.begin(); it_i != end; ++it_i)
{
    Entity& entity_i = **it_i;
    auto it_j = it_i;
    it_j++;
    for (; it_j != end; ++it_j)
    {
        Entity& entity_j = **it_j;
        if (entity_i.isAlive() && entity_i.isCollide(entity_j))
            entity_i.onDestroy();
        if (entity_j.isAlive() && entity_j.isCollide(entity_i))
            entity_j.onDestroy();
    }
}
for (auto it = _entities.begin(); it != _entities.end();)
{
    if (!(*it)->isAlive()){
        delete *it;
        it = _entities.erase(it);
    }
    else ++it;
}
_sounds.remove_if([](const std::unique_ptr<sf::Sound>& sound)->
    bool {
    return sound->getStatus() != sf::SoundSource::Status::Playing;
});
}
void World::draw(sf::RenderTarget& target, sf::RenderStates states) const
{
for (Entity* entity : _entities)
    target.draw(*entity, states);
}

Code pour world.hpp

#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
#include <list>
#include <memory>

#include "Configuration.h"

class Entity;
class World : public sf :: Drawable
{
public:
World(const World&) = delete;
World& operator=(const World&) = delete;

World(int x, int y);
~World();

void add(Entity* entity);
void clear();
bool isCollide(const Entity& other);
int size();

void add(Configuration::Sounds sound_id);

const std::list<Entity*> getEntities() const;
int getX() const;
int getY() const;

void update(sf::Time deltaTime);

private:
std::list<Entity*> _entities;
std::list<Entity*> _entities_tmp;

std::list<std::unique_ptr<sf::Sound>> _sounds;
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override;

const int _x;
const int _y;
};

code pour Entity.h

class World;
class Entity : public sf::Drawable
{
public:
//Constructors
Entity(const Entity&) = delete;
Entity& operator= (const Entity&) = delete;

Entity(Configuration::Textures tex_id, World& world);
virtual ~Entity();
//Helpers
virtual bool isAlive() const;

const sf::Vector2f& getPosition() const;
template<typename ... Args>
void setPosition(Args&& ... args);
virtual bool isCollide(const Entity& other) const = 0;

//Updates
virtual void update(sf::Time deltaTime) = 0;
virtual void onDestroy();

protected:
friend class Meteor;
friend class Player;
friend class Saucer;
friend class ShootPlayer;
friend class ShootSaucer;

sf::Sprite _sprite;
sf::Vector2f _impulse;
World& _world;
bool _alive;

private:
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
};

0voto

nvoigt Points 20484
if (_entities_tmp.size() > 0)
    _entities.merge(_entities_tmp);

Cela ne fonctionne pas. merge fonctionne avec deux trié des gammes. Et votre vecteur n'est pas trié. C'est pourquoi vous obtenez une assertion.

Si le fait de ne pas les trier est volontaire et que vous voulez simplement concaténer les deux vecteurs, vous pouvez le faire :

_entities.reserve( _entities.size() + _entities_tmp.size() );
_entities.insert( _entities.end(), _entities_tmp.begin(), _entities_tmp.end() );

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X