(C++) QtExample5
February 24, 2017 · View on GitHub
(C++) QtExample5




Qt example 5: moving many changing sprites over a changing background in 2D is a Qt example that shows how to move many changing sprites over a changing background in 2D, like this screenshot (png).
Technical facts
Operating system(s) or programming environment(s)
Lubuntu 15.04 (vivid)
Qt Creator 3.1.1
- G++ 4.9.2
Libraries used:
STL: GNU ISO C++ Library, version
4.9.2
Qt project file: ./CppQtExample5/CppQtExample5.pro
include(../../DesktopApplication.pri) include(../../Libraries/Boost.pri) SOURCES += main.cpp RESOURCES += CppQtExample5.qrc
./CppQtExample5/main.cpp
#include <cassert> #include <iostream> #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Weffc++" #pragma GCC diagnostic ignored "-Wunused-local-typedefs" #include <boost/shared_ptr.hpp> #include <QApplication> #include <QBitmap> #include <QFile> #include <QGraphicsPixmapItem> #include <QGraphicsScene> #include <QGraphicsView> #include <QTimer> #pragma GCC diagnostic pop struct ChangingBackground : public QGraphicsPixmapItem { explicit ChangingBackground(const int width, const int height) : z(0) { QPixmap m(width,height); this->setPixmap(m); } void advance(int) { QImage i = this->pixmap().toImage(); const int width = i.width(); const int height = i.height(); for (int y=0;y!=height;++y) { for (int x=0;x!=width;++x) { QPoint pos(x,y); QColor c((x+z)%256,(y+z)%256,(x+y+z)%256); i.setPixel(pos,c.rgb()); } } this->setPixmap(this->pixmap().fromImage(i)); ++z; } private: int z; }; struct ChangingTransparentSprite : public QGraphicsPixmapItem { explicit ChangingTransparentSprite( const std::string& filename, const QColor& transparency_color = QColor(0,255,0)) //Lime green : dx( ((std::rand() >> 4) % 3) - 1), //Random direction dy( ((std::rand() >> 4) % 3) - 1), //Random direction maxx(0), maxy(0) { QPixmap pixmap(filename.c_str()); const QBitmap mask = pixmap.createMaskFromColor(transparency_color); pixmap.setMask(mask); this->setPixmap(pixmap); //Change color QImage i = this->pixmap().toImage(); const int width = i.width(); const int height = i.height(); const int dz = std::rand(); for (int y=0;y!=height;++y) { for (int x=0;x!=width;++x) { QPoint pos(x,y); QColor color = i.pixel(pos); if (color == QColor(0,0,0)) continue; color.setRed((color.red() + dz) % 256); color.setGreen((color.green() + dz) % 256); color.setBlue((color.blue() + dz) % 256); i.setPixel(pos,color.rgb()); } } this->setPixmap(this->pixmap().fromImage(i)); } void advance(int) { int new_x = this->x(); int new_y = this->y(); new_x+=dx; new_y+=dy; if (new_x<0 || new_x>maxx) dx= -dx; if (new_y<0 || new_y>maxy) dy= -dy; this->setX(new_x); this->setY(new_y); //Change color QImage i = this->pixmap().toImage(); const int width = i.width(); const int height = i.height(); for (int y=0;y!=height;++y) { for (int x=0;x!=width;++x) { QPoint pos(x,y); QColor color = i.pixel(pos); if (color == QColor(0,0,0)) continue; color.setRed((color.red() + 1) % 256); color.setGreen((color.green() + 1) % 256); color.setBlue((color.blue() + 1) % 256); i.setPixel(pos,color.rgb()); } } this->setPixmap(this->pixmap().fromImage(i)); } void setRect(const int width, const int height) { maxx = width - this->pixmap().width(); maxy = height - this->pixmap().height(); } private: int dx; int dy; int maxx; int maxy; }; int main(int argc, char *argv[]) { QApplication a(argc, argv); QGraphicsScene s; QGraphicsView v(&s); ChangingBackground background(512,512); s.addItem(&background); std::vector<boost::shared_ptr<ChangingTransparentSprite> > sprites; //Add multiple sprites const int n_sprites = 3; for (int i=0; i!=n_sprites; ++i) { assert(QFile::exists(":/images/Bloem.png")); boost::shared_ptr<ChangingTransparentSprite> sprite( new ChangingTransparentSprite(":/images/Bloem.png")); const int maxx = background.pixmap().width() - sprite->pixmap().width(); const int maxy = background.pixmap().height() - sprite->pixmap().height(); sprite->setX(std::rand() % maxx); sprite->setY(std::rand() % maxy); sprite->setRect(background.pixmap().width(),background.pixmap().height()); s.addItem(sprite.get()); sprites.push_back(sprite); } v.show(); boost::shared_ptr<QTimer> timer(new QTimer(&s)); timer->connect(timer.get(), SIGNAL(timeout()), &s, SLOT(advance())); timer->start(50); return a.exec(); }