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
Operating system(s) or programming environment(s)
- Lubuntu 15.04 (vivid)
- Qt Creator 3.1.1
- G++ 4.9.2
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
#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(); }