Item scaling and rendering

I am making a small game in C ++ 11 with Qt. However, I'm having trouble scaling.

The background of my card is an image. Each pixel of this image represents a tile that the main character can act on and enemies / medical packs can be.

To set the size of the tile, I calculate the maximum number (for example, imageRows and imageCols are the number of pixels on the x and y axis of the background image):

QRect rec = QApplication::desktop()->screenGeometry();
int maxRows = rec.height() / imageRows;
int maxCols = rec.width() / imageCols;
if(maxRows < maxCols){
    pixSize = maxRows;
} else{
    pixSize = maxCols;
}

      

Now that I have the size of the tile, I add a background image to the scene (in GameScene ctor

, continues from QGraphicsScene

):

auto background = new QGraphicsPixmapItem();
background->setPixmap(QPixmap(":/images/map.png").scaledToWidth(imageCols * pixSize));
this->addItem(background);

      

Then to add enemies (they range from QGraphicsPixMapItem

):

Enemy *enemy = new Enemy();
enemy->setPixmap(QPixmap(":/images/enemy.png").scaledToWidth(pixSize));
scene->addItem(enemy);

      

This all works great, except that on large maps the images are scaled once (to a height of, say, 2 pixels) and when scaled on that element it becomes obscure but remains a large pixel. Here's an example: the left one is on a small map, where the pixSize is quite large, the second one has a rather small pixSize.

Image on a small mapSame QGraphicsPixMapItem on a large map

So how do I solve this? In general, with pixSize based on screen resolution is not very useful as it QGrapicsScene

changes according to QGraphicsView

what it is in, so at the end the view still determines how large the pixels are displayed on the screen.

MyGraphicsView w;
w.setScene(gameScene);
w.fitInView(gameScene->sceneRect(), Qt::KeepAspectRatio);

      

+3


source to share


1 answer


I think you might need to look at an example from Qt (link to Qt5, but also works for Qt4).

Something that might help you is in the chip.cpp file :

in method paint

:

const qreal lod = option->levelOfDetailFromTransform(painter->worldTransform());

      

where painter

is just a QPainter

and option

is of type QStyleOptionGraphicsItem

. This value returns you the current zoom level of yours QGraphicsView

and thus, as in the example, you can customize what is being done at which level, for example.



if (lod < 0.2) {
    if (lod < 0.125) {
        painter->fillRect(QRectF(0, 0, 110, 70), fillColor);
        return;
    }

    QBrush b = painter->brush();
    painter->setBrush(fillColor);
    painter->drawRect(13, 13, 97, 57);
    painter->setBrush(b);
    return;
}

      

[...]

if (lod >= 2) {
    QFont font("Times", 10);
    font.setStyleStrategy(QFont::ForceOutline);
    painter->setFont(font);
    painter->save();
    painter->scale(0.1, 0.1);
    painter->drawText(170, 180, QString("Model: VSC-2000 (Very Small Chip) at %1x%2").arg(x).arg(y));
    painter->drawText(170, 200, QString("Serial number: DLWR-WEER-123L-ZZ33-SDSJ"));
    painter->drawText(170, 220, QString("Manufacturer: Chip Manufacturer"));
    painter->restore();
}

      

Does it help?

+1


source







All Articles