0

我正在尝试学习 QT,在学习的同时我想开发一个相同的游戏。我有一个 QGraphicsItem 的子类,它是 Gem,而 QGraphicsScene 的一个子类是 GameScene。

我将场景中每个 Gem 的 clickedOnMe 信号连接到 GameScene 的 clicked slot。Signal 提供指向被点击对象的指针。GameScene 类包含一个指向 Gem 的指针列表。

到目前为止,我只尝试找到结束删除相同的内容,没有替换任何 gem。当我运行游戏并单击一个 gem 时,它有时运行良好并删除所有相同的 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;
4

2 回答 2

0

在迭代容器时添加或删除容器不是一个好主意。它使迭代器无效。各种事情都有可能发生。

于 2013-08-14T08:35:58.850 回答
0

想象一下这样一种情况,您有一个 gem ( x),它的右侧 ( a) 和下方 ( b) 有一个邻居。

--xa--
--bc--

现在,当它遍历neighbours列表时,假设它将右侧的邻居 ( a) 传递给clicked函数。现在,如果这个 gem 在它下面有一个邻居 ( c),它将把它传递给clicked函数。现在您处于这种情况下,该宝石左侧 ( b) 的宝石与第一个宝石 ( x) 下方的宝石相同。这将删除那个 gem,但它仍然在neighbours第一个 gem ( x) 的列表中,这是一个无效的指针,它将把它传递给clicked试图删除它的函数。

于 2013-08-14T09:01:26.817 回答