我尝试使用Qt GUI创建平铺的基本地图: 我有两个类:一个用于设置继承自QGraphicPixmapItem的切片图像,一个用于从文本文件加载我的地图,该文本文件是由数字1,0和2组成的2D数组,并将其添加到场景中: 但我的计划意外退出,我不知道休息在哪里:
我的瓷砖类:
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;
}
对不起家伙的长篇文章,但我被卡住了! 关于我错过的任何想法?
答案 0 :(得分: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 :(得分:0)
我终于找到了解决问题的方法: 我在我的函数paintMap中添加了一个场景,用于将每个项目添加到我的场景中,并创建了一个返回场景的QGraphicScene * getScene(),然后我只是通过编写
将其称为我的mainWindowui->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);
在每种情况下!瞧! 我希望能帮助像我这样的新手,至少要了解背后的逻辑!我不确定这是最好的方法,但这种方式适合我! :)