2017-04-05 117 views
2

我開始爲我在C++和sfml中開發的遊戲編寫我自己的粒子效果系統。 在我的更新方法中,我正在移除生命週期已經過期的粒子,同時迭代矢量。 我以爲我小心不要在清除元素後使迭代器失效,就像您在方法底部看到的一樣,但是我得到的是exec_bad_access代碼= 1或代碼= 2。 該例外總是指向擦除(it)行。 任何想法可能是錯誤的?無效std ::向量迭代器

void ParticlesNode::updateCurrent(sf::Time dt) 
{ 
    for(particleIterator it = _mParticles.begin(), end = _mParticles.end(); it != end;) 
{ 
    // calculate new color RGBA 
    float nr = it->color.r + it->colorDis.r * dt.asSeconds(); 
    float ng = it->color.g + it->colorDis.g * dt.asSeconds(); 
    float nb = it->color.b + it->colorDis.b * dt.asSeconds(); 
    float na = it->color.a + it->colorDis.a * dt.asSeconds(); 
    it->color = sf::Color{static_cast<Uint8>(nr),static_cast<Uint8>(ng),static_cast<Uint8>(nb),static_cast<Uint8>(na)}; 

    // new position 
    it->pos = sf::Vector2f(it->pos.x + it->vel.x * dt.asSeconds(), it->pos.y + it->vel.y * dt.asSeconds()); 

    // new velocity by linear accelaration. 
    float length = getLength(it->vel); 
    float newLength = length + _mPData.accel * dt.asSeconds(); 
    float radians = cartesianToPolar(it->vel).y; 

    it->vel = polarToCartesian(newLength, radians); 
    // new velocity by gravity 
    // new velocity by radial acceleration. 


    // new remaining life time 
    it->lifeSpan -= dt.asSeconds(); 
    if (it->lifeSpan <= 0) 
     _mParticles.erase(it); 
    else 
     ++it; 
} 
} 

回答

4

erase後迭代it變得無效,但它仍然用於下一次迭代。

您應該通過返回值erase來指定它,它指向擦除元素後面的迭代器。

it = _mParticles.erase(it); 

而且注意,不僅在該點的迭代器erase成爲後無效,所有的迭代器,包括end()也變得無效。所以,你需要評估end()每次迭代,即改變for的條件

for(particleIterator it = _mParticles.begin(); it != _mParticles.end();) 
+0

謝謝,我試圖左右逢源,以分配和沒有,仍然崩潰。 –

+0

@BennyAbramovici編輯回答。 – songyuanyao

+0

嘿,你的第二個建議工作,我沒有重新評估結束迭代器,那是curlpit。感謝您將我拉直!有一件事,我不相信有必要指定它= _mParticles.erase(it);無論如何它會在那裏。再次感謝。 –