1

Qt GUI を使用してタイル ベース マップを作成しようとしています。2 つのクラスがあります。と 2 をシーンに追加します。

私のタイルクラス:

class mapTile: public QGraphicsPixmapItem
{
public:
    enum Tile {DOOR, GRASS, FIRE};

    mapTile(): QGraphicsPixmapItem(),currentTile(GRASS){
        syncBitmap();
    }

    Tile getTile() const {return currentTile;}

    void setTile(Tile newTile){
        if(currentTile!= newTile){
            currentTile=newTile;
            syncBitmap();
        }
    }

private:
    void syncBitmap() {//Set my image to my tile
        switch(currentTile) {
        case DOOR:
            image->setPixmap(QPixmap(":/mpa/castledoors.png"));
        case GRASS:
            image->setPixmap(QPixmap(":/map/grass3_blur.jpg"));
        case FIRE:
            image->setPixmap(QPixmap(":/map/feu1/png"));
        }
    }

    Tile currentTile;
    QGraphicsPixmapItem *image;

};

私のクラスマップ:

Map.h:

class Map
{

public:
    static const int TILE_SIZE=20; //value of the tile in pixels!!!->20X20=a tile
    void paintMap(QGraphicsScene *scene);
    Map();

 private:

    static const int WIDTH= 13;// width of the grid cell
    static const int HEIGHT= 9;//height  of the grid cell

    //my grid cell map !!!!
    int array[WIDTH][HEIGHT];
    mapTile *tile; //my tile

};

そして Map.cpp

/*Create a default Map*/
Map::Map()
{
    QFile myfile("path to my file");
    if (!myfile.open(QIODevice::ReadOnly | QIODevice::Text))
    {
         QMessageBox::information(0, "error", myfile.errorString());
    }

    QTextStream in(&myfile);
    QString line ;
    QStringList fields;
    int i=0;
    int j=0;

    while (!in.atEnd()) {
        //Fill my array with my list--> convert Qtring into Int
        for (i=0; i<HEIGHT; i++ ) {

           line = in.readLine();
           fields = line.split(" ");

           for(j=0;j<WIDTH;j++)
           {
               //cout<<fields[j].toInt();
                array[i][j] = fields[j].toInt();
           }
        }
    }
}



//Paint my map with my tile
void Map::paintMap(QGraphicsScene *scene){

    int i=0, j=0;
    tile= new mapTile();

    for (i=0; i<HEIGHT; i++){
        for(j=0; j<WIDTH; j++){

            switch(array[i][j]){

            case 0:

                tile->setTile(mapTile::GRASS);
                tile->setPos(i,j);
                scene->addItem(tile);
                j+=TILE_SIZE;

            case 1:

                tile->setTile(mapTile::FIRE);
                tile->setPos(i,j);
                scene->addItem(tile);
                j+=TILE_SIZE;
            case 2:

                tile->setTile(mapTile::DOOR);
                tile->setPos(i,j);
                scene->addItem(tile);
                j+=TILE_SIZE;
            }

            i+=TILE_SIZE;//
        }
    }

}

そして最後に私のメインウィンドウ(file.cppを直接渡します):

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    myMap= new Map;
    scene= new QGraphicsScene(this);

    myMap->paintMap(scene);
    ui->graphicsView->setScene(scene);

}

MainWindow::~MainWindow()
{
    delete ui;
}

長い投稿で申し訳ありませんが、私は立ち往生しています! 私が逃したものについてのアイデアはありますか?

4

2 に答える 2

1

コードには少なくとも 5 つの問題があります。

  • myTileそれらをシーンに追加するときに、同じインスタンスを共有することはできません。タイルをシーンに追加するたびに、新しいタイルを作成する必要があります。現時点では、 の開始時にインスタンスを 1 つだけ作成していますMap::paintMap

  • あなたのmyTileクラスはから継承しますが、初期化されていないままQGraphicsPixmapItemのメンバーもありますQGraphicsPixmapItem *image;(したがって、ローミングポインターです)が、それを使用するimage->setPixmap(QPixmap(":/mpa/castledoors.png"));とクラッシュします。代わりに、単に呼び出したいsetPixmap(QPixmap(":/mpa/castledoors.png"))(スーパークラスの関数を呼び出す) 必要があります。

  • 上記の項目で、「map」のスペルを「mpa」と間違えたことに気付いたかもしれませんが、これはクラッシュの原因ではありません。

  • mapTile::syncPixmapと同様に、のステートメントMap::paintMapを忘れてしまいました。それらがなければ、すべてのタイルが火のタイルのように見えます。break;switch

  • ピクセル座標であるかのようにタイル サイズをiおよびjイテレータに追加していますが、同時にそれらを配列インデックスとして使用しています。ピクセル座標に個別の変数を使用するか、代わりに呼び出すときに乗算する必要がiあります。jTILE_SIZEsetPos

幸運を!

于 2014-10-14T19:30:31.947 に答える
0

私は最終的に私の問題の解決策を見つけました:私は自分のシーンに各アイテムを追加するために自分の関数 paintMap にシーンを追加し、シーンを返す QGraphicScene* getScene() を作成しました。

ui->graphicsView->setScene(myMap->getScene())

さらに、私のmapTileクラスでは、関数 setTile() を使用しなくなりました。私はそれを削除し、次にQGraphicPixmapItem *imageaQPixmap imageで変更し、関数でスイッチの最後に変更syncbitmap()this->setPixmap(image.scaled(TILE_SIZE,TILE_SIZE));ました! なんで?私のタイルは既にQGraphicsPixmapItem(継承) であるため、それに pixmap を設定するだけです! そして、スイッチの最後に置いたのは、前に画像を設定すると、画像が既に設定されているため、画像が決して変わらないからです! 最後に、削除したコンストラクターで、コンストラクターにcurrentTile(GRASS)Tile 変数を引数として追加し、コンストラクターに入れcurrentTile= name of your variable、syncBitmap 関数を呼び出しました。したがって、 paintMap() では、次のことを行う必要があります。

tile= new mapTile(mapTile::GRASS);
tile->setPos(j*TILE_SIZE,i*TILE_SIZE);
scene->addItem(tile);

いずれの場合にも!ほら!私のような初心者が、少なくとも背後にあるロジックを理解するのに役立つことを願っています! それが最善の方法かどうかはわかりませんが、この方法は私にとってはうまくいきます!:)

于 2014-10-16T07:59:43.117 に答える