Добавьте плиточную базовую карту в GraphicsScene

Я пытаюсь создать плиточную базовую карту с помощью Qt GUI:
У меня есть два класса: один, чтобы установить мои мозаичные изображения, которые наследуются от QGraphicPixmapItem, другой, чтобы загрузить мою карту из текстового файла, который представляет собой 2D-массив, состоящий из чисел 1, 0 и 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;//
}
}

}

и, наконец, мое главное окно (я даю файл .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;
}

Извините, ребята за длинный пост, но я застрял!
Любые идеи о том, что я пропустил?

1

Решение

Ну, в вашем коде как минимум пять проблем:

  • Вы не можете поделиться тем же myTile экземпляр при добавлении их на сцену. Вам нужно создавать новый каждый раз, когда вы добавляете плитку к сцене. На данный момент вы создаете только один экземпляр в начале 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 а также j посредством TILE_SIZE при звонке setPos вместо.

Удачи!

1

Другие решения

Я наконец нашел решение своих проблем:
Я добавил сцену в свою функцию paintMap для добавления каждого элемента в мою сцену и создал QGraphicScene * getScene (), который возвращает сцену, затем я просто вызываю его как mainWindow, просто написав

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

Да еще по моему mapTile класс я больше не использую функцию setTile (). Я удалил его, затем изменил мой QGraphicPixmapItem *image по QPixmap image и в моей функции syncbitmap() я сделал
this->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);

в каждом случае! Вуаля!
Я надеюсь, что это поможет новичку, как я, по крайней мере, понять логику позади! Я не уверен, что это лучший способ, но этот способ работает для меня! 🙂

0

По вопросам рекламы [email protected]