Go back to Richel Bilderbeek's homepage.

Go back to Richel Bilderbeek's C++ page.

 

 

 

 

 

(C++) Qt How to draw a sprite on a sprite?

 

How to draw a sprite on a sprite? is a Qt FAQ when you want to stretchdraw differently scaled images on top of each other, like this image.

 

 

 

 

 

Project and source code

 

Operating system: Ubuntu 10.04 LTS Lucid Lynx

IDE: Qt Creator 2.0.0

Project type: Qt4 Console Application

Compiler: G++ 4.4.1

Libraries used:

 

 

 

 

 

 

CppQtSpriteOnSprite.pro

 

#-------------------------------------------------
#
# Project created by QtCreator 2010-07-30T20:07:20
#
#-------------------------------------------------
QT += core gui
TARGET = CppQtSpriteOnSprite
TEMPLATE = app
SOURCES += main.cpp\
dialog.cpp
HEADERS += dialog.h
FORMS += dialog.ui
RESOURCES += \
resources.qrc

 

 

 

 

 

main.cpp

 

#include <QtGui/QApplication>
#include "dialog.h"

int main(int argc, char *argv[])
{
  QApplication a(argc, argv);
  Dialog w;
  w.show();
  return a.exec();
}

 

 

 

 

 

dialog.h

 

#ifndef DIALOG_H
#define DIALOG_H

#include <boost/shared_ptr.hpp>
#include <QDialog>
struct QTimer;


namespace Ui {
  class Dialog;
}

class Dialog : public QDialog
{
  Q_OBJECT

public:
  explicit Dialog(QWidget *parent = 0);
  ~Dialog();

protected:
  void changeEvent(QEvent *e);

private:
  Ui::Dialog *ui;
  boost::shared_ptr<QTimer> m_timer;

  void paintEvent(QPaintEvent * event);

private slots:
  void onTimer();

};

#endif // DIALOG_H

 

 

 

 

 

dialog.cpp

 

#include <cassert>
#include <QDesktopWidget>
#include <QImage>
#include <QPainter>
#include <QPixmap>
#include <QTimer>

#include "dialog.h"
#include "ui_dialog.h"

Dialog::Dialog(QWidget *parent) :
    QDialog(parent,Qt::Window), //To allow resizing
    ui(new Ui::Dialog),
    m_timer(new QTimer)
{
  ui->setupUi(this);

  //Put the dialog in the screen center
  const QRect screen = QApplication::desktop()->screenGeometry();
  this->move( screen.center() - this->rect().center() );

  //Make a timer tick ever 1000 ms
  QObject::connect(m_timer.get(),SIGNAL(timeout()),this,SLOT(onTimer()));
  m_timer->start(1000);
}

Dialog::~Dialog()
{
  delete ui;
}

void Dialog::changeEvent(QEvent *e)
{
  QDialog::changeEvent(e);
  switch (e->type()) {
  case QEvent::LanguageChange:
    ui->retranslateUi(this);
    break;
  default:
    break;
  }
}

void Dialog::paintEvent(QPaintEvent *)
{
  //Start the painter
  QPainter painter(this);

  //Load the background from resources
  QPixmap background(":/images/Background11x11.png");
  assert(!background.isNull());

  //StretchDraw the background on the widget
  painter.drawPixmap(
    ui->widget->rect(),
    background);

  //Load the sprite from resources
  QPixmap sprite(":/images/Sprite22x22.png");
  assert(!sprite.isNull());

  //Choose a random x and y coordinate on a white pixel
  int x = 0;
  int y = 0;
  while (1)
  {
    x = 1 + (std::rand() % 9);
    y = 1 + (std::rand() % 9);
    //The new position must be on a white pixel
    if (background.toImage().pixel(x,y)
      == QColor(255,255,255).rgb()) break;
  }

  //Determine the sprite's position on the painter
  const int width = ui->widget->width();
  const int height = ui->widget->height();
  const double block_width = static_cast<double>(width) / 11.0;
  const double block_height = static_cast<double>(height) / 11.0;

  //Draw the sprite on the painter
  painter.drawPixmap(
    static_cast<double>(x) * block_width,
    static_cast<double>(y) * block_height,
    block_width,
    block_height,
    sprite);
}

void Dialog::onTimer()
{
  this->repaint();
}

 

 

 

 

 

Go back to Richel Bilderbeek's C++ page.

Go back to Richel Bilderbeek's homepage.

 

Valid XHTML 1.0 Strict