2016-07-06 41 views
1

我正在嘗試遵循SFML藍圖書。我設法刪除所有的錯誤,但是代碼中仍然存在一個錯誤。 我試圖找到關於debug-assertion-failed的內容。 我認爲這個問題是由於列表中的一個清空而引起的。Debug Assertion構建SFML藍圖時失敗Asteroid game?

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

什麼錯誤?你***必須***在你的OP(問題)中粘貼一些相關的錯誤***作爲文本***。 –

+0

程序中沒有錯誤。但是當我運行我的代碼時,它表示調試斷言失敗的表達式序列沒有排序。並且Visual Studio將斷點指向World.cpp update(); for(Entity * entity_ptr:_entities)後面的for循環 –

+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()); 
+0

Asteroid.exe中0x00434FA9未處理的異常:0xC0000005:訪問衝突讀取位置0x00000010。 –

+0

哪裏,哪條線?你需要寫出更好的問題,我們不能總是猜到你想說什麼...... – nvoigt

+0

我替換了行 _entities.merge(_entities_tmp);與_enties.insert(_entities.end(),_entities_tmp.begin(),_entities_tmp.end());函數_entities.reserve()在這裏不起作用,因爲它是一個std :: list而不是一個向量。是的新的中斷點entity.update(增量時間)後實體&實體= * entity_ptr; –