Go back to Richel Bilderbeek's homepage.

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

 

 

 

 

 

(C++) QtExample9

 

QtQt CreatorLubuntuUbuntu

 

This Qt example shows how to let custom sprites move over custom background, like this screenshot (png).

 

There are multiple ways to do the same, for example, as shown in Qt example 9.2

 

Technical facts

 

Application type(s)

Operating system(s) or programming environment(s)

IDE(s):

Project type:

C++ standard:

Compiler(s):

Libraries used:

 

 

 

 

 

Qt project file: ./CppQtExample9/CppQtExample9.pro

 

exists(../../DesktopApplication.pri) {
  include(../../DesktopApplication.pri)
}
!exists(../../DesktopApplication.pri) {
  QT += core gui
  greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
  TEMPLATE = app

  CONFIG(debug, debug|release) {
    message(Debug mode)
  }

  CONFIG(release, debug|release) {
    message(Release mode)
    DEFINES += NDEBUG NTRACE_BILDERBIKKEL
  }

  QMAKE_CXXFLAGS += -std=c++11 -Wall -Wextra

  unix {
    QMAKE_CXXFLAGS += -Werror
  }
}

exists(../../Libraries/Boost.pri) {
  include(../../Libraries/Boost.pri)
}
!exists(../../Libraries/Boost.pri) {
  win32 {
    INCLUDEPATH += \
      ../../../Projects/Libraries/boost_1_55_0
  }
}

SOURCES += main.cpp

 

 

 

 

 

./CppQtExample9/main.cpp

 

#include <cassert>
#include <cmath>
#include <iostream>

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Weffc++"
#pragma GCC diagnostic ignored "-Wunused-local-typedefs"
#include <boost/math/constants/constants.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/static_assert.hpp>
#include <boost/timer.hpp>
#include <QApplication>
#include <QBitmap>
#include <QDialog>
#include <QGraphicsPixmapItem>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QTimer>
#include <QVBoxLayout>
#pragma GCC diagnostic pop

BOOST_STATIC_ASSERT(sizeof(qreal)==sizeof(double)
  && "Assume use of double is equivalent of qreal");

struct Background : public QGraphicsPixmapItem
{
  explicit Background(const int width = 256, const int height = 256)
  {
    QImage i(width,height,QImage::Format_ARGB32);
    for (int y=0;y!=height;++y)
    {
      for (int x=0;x!=width;++x)
      {
        const int gray = (x + y) % 256;
        i.setPixel(QPoint(x,y),QColor(gray,gray,gray).rgb());
      }
    }
    this->setPixmap(this->pixmap().fromImage(i));
  }
};

struct Sprite : public QGraphicsPixmapItem
{
  explicit Sprite(const int width = 32, const int height = 32)
    : dx(1.0), dy(1.0), maxx(0.0), maxy(0.0)
  {
    QImage i(width,height,QImage::Format_ARGB32);
    for (int y=0;y!=height;++y)
    {
      for (int x=0;x!=width;++x)
      {
        const int gray = ((8 * x) + (8 * y)) % 256;
        i.setPixel(QPoint(x,y),QColor(gray,gray,gray).rgb());
      }
    }
    this->setPixmap(this->pixmap().fromImage(i));
  }
  void advance(int)
  {
    double new_x = this->x();
    double new_y = this->y();
    new_x+=dx;
    new_y+=dy;
    if (new_x<0.0 || new_x>maxx) dx= -dx;
    if (new_y<0.0 || new_y>maxy) dy= -dy;
    this->setX(new_x);
    this->setY(new_y);
  }
  void setRect(const int width, const int height)
  {
    maxx = static_cast<double>(width  - this->pixmap().width() );
    maxy = static_cast<double>(height - this->pixmap().height());
  }
  private:
  double dx;
  double dy;
  double maxx;
  double maxy;
};

int main(int argc, char *argv[])
{
  QApplication a(argc, argv);

  //Start with creating a scene
  boost::shared_ptr<QGraphicsScene> scene(new QGraphicsScene);

  //Add background to scene
  boost::shared_ptr<Background> background(new Background);
  scene->addItem(background.get());

  //Add sprites to scene
  std::vector<boost::shared_ptr<Sprite> > sprites;
  //Add multiple sprites
  {
    const int n_sprites = 20;
    const double midx = background->pixmap().width() / 2.0;
    const double midy = background->pixmap().height() / 2.0;
    const double ray = std::min(midx,midy) * 0.8;
    const double d_angle = boost::math::constants::two_pi<double>() / static_cast<double>(n_sprites);
    double angle = 0.0;
    for (int i=0; i!=n_sprites; ++i)
    {
      boost::shared_ptr<Sprite> sprite(new Sprite);
      const double x = midx + (std::sin(angle) * ray) - (sprite->pixmap().width() / 2);
      const double y = midy - (std::cos(angle) * ray) - (sprite->pixmap().height() / 2);
      sprite->setX(x);
      sprite->setY(y);
      sprite->setRect(background->pixmap().width(),background->pixmap().height());
      scene->addItem(sprite.get());
      sprites.push_back(sprite);
      angle+=d_angle;
    }
  }

  //Connect a view to display the scene
  boost::shared_ptr<QGraphicsView> view(new QGraphicsView);
  view->setScene(scene.get());

  //Create a layout to put the scene in
  boost::shared_ptr<QVBoxLayout> layout(new QVBoxLayout);
  layout->addWidget(view.get());

  //Create a dialog to display to laid-out-scene
  boost::shared_ptr<QDialog> dialog(new QDialog);
  dialog->setLayout(layout.get());
  dialog->setGeometry(view->rect());

  //Create a timer to call 'advance' on all sprites'
  boost::shared_ptr<QTimer> timer(new QTimer(scene.get()));
  timer->connect(timer.get(), SIGNAL(timeout()), scene.get(), SLOT(advance()));
  timer->start(20);

  //Show the graphicsscene with its sprites
  dialog->show();

  return a.exec();
}

 

 

 

 

 

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

Go back to Richel Bilderbeek's homepage.

 

Valid XHTML 1.0 Strict

This page has been created by the tool CodeToHtml