I try to create a tiled base map by using Qt GUI: I have two classes: one to set my tile images that inherits from QGraphicPixmapItem, one to load my map from a text file that is a 2D array composed of the numbers 1, 0 and 2, and add it to a scene: But my program quits unexpectedly and I do not know where is the break:
my tile class:
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;
};
my class map:
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
};
And 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;//
}
}
}
and finally my mainwindow (I directly give the 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;
}
Sorry guys for the long post but I am stuck! Any ideas on what I missed?
Well, there are at least five problems in your code:
You can't share the same myTile
instance when adding them to the scene. You need to create a new one each time you're adding a tile to the scene. At the moment you're creating only one instance at the start of Map::paintMap
.
Your myTile
class inherits from QGraphicsPixmapItem
, however it also has a QGraphicsPixmapItem *image;
member which it leaves uninitialized (so it's a roaming pointer), but then it uses it in image->setPixmap(QPixmap(":/mpa/castledoors.png"));
which will crash. Instead, you'll want to just call setPixmap(QPixmap(":/mpa/castledoors.png"))
(calling the function of your superclass).
In the above item you may have noticed that you misspelled "map" as "mpa", though this will not be the reason of your crash.
In mapTile::syncPixmap
as well as in Map::paintMap
, you forgot the break;
statements in the switch
. Without those, all tiles would appear like fire tiles.
You're adding your tile size to the i
and j
iterators, as if they were the pixel coordinates, but at the same time you're using them as array indexes. You need to either use separate variables for the pixel coordinates or multiply i
and j
by the TILE_SIZE
when calling setPos
instead.
Good luck!