【问题标题】:Add a tiled base map to a GraphicsScene将平铺底图添加到 QGraphicsScene
【发布时间】:2014-10-14 16:44:03
【问题描述】:

我尝试使用 Qt GUI 创建平铺底图: 我有两个类:一个用于设置从 QGraphicPixmapItem 继承的平铺图像,一个用于从文本文件加载我的地​​图,该文本文件是由数字 1、0 和 2 组成的二维数组,并将其添加到场景中: 但是我的程序却意外退出了,我也不知道break在哪里:

我的瓷砖类:

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;

};

我的班级地图:

地图.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;
}

抱歉,大家发了这么长的帖子,但我卡住了! 关于我错过了什么的任何想法?

【问题讨论】:

    标签: c++ qt map qgraphicsscene tiled


    【解决方案1】:

    嗯,你的代码至少有五个问题:

    • myTile 添加到场景时,您不能共享相同的实例。每次向场景中添加图块时,都需要创建一个新图块。目前,您只在 Map::paintMap 的开头创建一个实例。

    • 您的 myTile 类继承自 QGraphicsPixmapItem,但它也有一个 QGraphicsPixmapItem *image; 成员,它未初始化(因此它是一个漫游指针),但随后它在 image-&gt;setPixmap(QPixmap(":/mpa/castledoors.png")); 中使用它会崩溃.相反,您只需调用 setPixmap(QPixmap(":/mpa/castledoors.png"))(调用超类的函数)。

    • 在上述项目中,您可能已经注意到您将“map”拼错为“mpa”,但这不是导致崩溃的原因。

    • mapTile::syncPixmapMap::paintMap 中,您忘记了switch 中的break; 语句。没有这些,所有的瓷砖都会看起来像火瓷砖。

    • 您将切片大小添加到 ij 迭代器中,就好像它们是像素坐标一样,但同时您将它们用作数组索引。您需要为像素坐标使用单独的变量,或者在调用setPos 时将ij 乘以TILE_SIZE

    祝你好运!

    【讨论】:

    • 嘿!谢谢你的回复!我把所有错过的休息时间,我在我的地图类中创建了3个不同的mapTile对象,初始化了我的QGraphicPixmapItem,我决定将我的i和我的j乘以setPos()中的TILE_SIZE,就像你说的那样,最后它不再崩溃了:) 我有一个窗口,但什么都没有!事实上,当我在我的主要调用函数paintMap() 时,我确实使用了一个场景,该函数期望一个场景作为参数,但是我如何才能将不是场景本身的地图添加到我的视图中呢??
    • 是的,它是“地图”而不是“mpa”;)
    • 您不需要将地图添加到场景中,因为您的 paintMap 函数已经向其中添加了应该显示的图块。我不知道为什么你的瓷砖不会出现。尝试在您的代码中添加一些调试打印(包括QDebug 并使用qDebug() &lt;&lt; ...)来尝试找出发生了什么。
    【解决方案2】:

    我终于找到了解决问题的方法: 我在我的函数 paintMap 中添加了一个场景,用于将每个项目添加到我的场景中,并创建了一个返回场景的 QGraphicScene* getScene(),然后我只需编写即可将其称为我的 mainWindow

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

    此外,在我的mapTile 课程中,我不再使用函数 setTile()。我删除了它,然后将我的QGraphicPixmapItem *image 更改为QPixmap image 并在我的函数syncbitmap() 中做了 this-&gt;setPixmap(image.scaled(TILE_SIZE,TILE_SIZE));在我的开关结束时!为什么?因为我的图块已经是QGraphicsPixmapItem(继承)所以我只需要为它设置一个像素图!我把它放在开关的末尾,因为如果我之前设置了图像,图像将永远不会改变,因为它已经设置好了!最后在构造函数中,我删除了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);
    

    在每种情况下!瞧! 我希望这将有助于像我这样的新手,至少了解背后的逻辑!我不确定这是最好的方法,但这种方法对我有用! :)

    【讨论】:

      猜你喜欢
      • 2021-10-05
      • 2011-08-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多