调试断言在构建SFML蓝图小行星游戏时失败了吗?

时间:2016-07-06 08:08:44

标签: c++ visual-studio debugging sfml

我试图遵循SFML蓝图书。我设法删除所有错误,但代码中仍然存在一个错误。 我试图找到debug-assertion-failed。 我认为这个问题是由于其中一个清单被清空而引起的。

The program crashes

The visual studio debugger says

我的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);
}

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;
};

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;
}; 

1 个答案:

答案 0 :(得分:0)

if (_entities_tmp.size() > 0)
    _entities.merge(_entities_tmp);

这不起作用。 merge适用于两个排序范围。而且你的矢量没有排序。这就是你得到断言的原因。

如果没有对它们进行排序是故意的,你只想连接两个向量,你可以这样做:

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