0

私は QT を学ぼうとしていますが、学びながら同じゲームを開発したいと思っていました。Gem である QGraphicsItem のサブクラスと、GameScene である QGraphicsScene のサブクラスがあります。

シーン内の各 Gem の clickedOnMe 信号を GameScene の clicked スロットに接続しました。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;
4

2 に答える 2

0

xジェム ( ) があり、その右側 ( a) とその下( ) に隣接するジェムがある状況を想像してくださいb

--xa--
--bc--

リストを通過するときneighbours、その右側の隣人 ( a) をclicked関数に渡すとしましょう。このジェムの下に隣人がいる場合 ( c)、それをclicked関数に渡します。そして今、この宝石の左側の宝石 ( )bが、最初の宝石 ( ) の下にある同じ宝石であるという状況に陥っていますx。これにより、その gem が削除されneighboursますが、最初の gem ( x) のリストに残ります。これは無効なポインターであり、それclickedを削除しようとする関数に渡します。

于 2013-08-14T09:01:26.817 に答える