我正在努力学习QT,在学习的同时我想开发一个相同的游戏。 我有一个QGraphicsItem的子类,它是Gem 和QGraphicsScene whics的子类是GameScene。
我将场景中每个Gem的clickedOnMe信号连接到GameScene的点击插槽。 Signal提供指向被点击对象的指针。 GameScene类中包含一个指向Gem的指针列表。
到目前为止,我已经尝试过只删除相同的内容,不替换任何宝石。当我运行游戏并点击某个宝石时,它有时会运行良好并删除所有相同的宝石,有时它会给出分段错误。我无法理解我的问题所在。
void GameScreen::clicked(Gem *cGem){
// cGem is the clicked gem
if(cGem)
{
//find cGem in the list and erase from list
QList<Gem*>::Iterator i = gems->begin();
for(; i != gems->end(); ++i)
{
if(*(*i) == *cGem)
{
gems->erase(i);
break;
}
}
// end of erasing
QList<Gem*> neighbours;
for(i=gems->begin(); i != gems->end(); ++i)
{
if((*i) && (*i)->doesItTouch(cGem) && (*i)->getColor() == cGem->getColor())
neighbours.append(*i);
}
delete cGem;
while(!neighbours.isEmpty())
{
clicked(neighbours.first());
neighbours.removeFirst();
}
}
return;
}
这里是Gem :: doesItTouch(Gem * oGem)
if(oGem)
return (qAbs(x - oGem->getX()) + qAbs(y - oGem->getY())) <= 1;
return false;
答案 0 :(得分:0)
在迭代容器时添加或删除容器不是一个好主意。它使迭代器无效。所有事情都可能发生。
答案 1 :(得分:0)
想象一下你有一个宝石(x
)的情况,它的右边有一个邻居(a
)并且在它下面(b
)。
--xa--
--bc--
现在,当它通过neighbours
列表时,可以说它将右侧的邻居(a
)传递给clicked
函数。现在,如果这个gem下面有一个邻居(c
),它会将它传递给clicked
函数。而现在你处于这个宝石左侧(b
)的宝石与第一个宝石(x
)之下的宝石相同的情况。这将删除该gem,但它仍将位于第一个gem(neighbours
)的x
列表中,这是一个无效指针,它会将它传递给clicked
函数。将尝试删除它。