Go back to Richel Bilderbeek's homepage.

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

 

 

 

 

 

(C++) Qt example 9.2: custom sprites over custom background

 

Alternative code for doing the same as Qt example 9: custom sprites over custom background, like this screenshot (png).

 

 

 

 

 

 

Qt project file: GamePong.pro

 

QT       += core gui

TARGET = GamePong
TEMPLATE = app


SOURCES += main.cpp\
        pongmaindialog.cpp

HEADERS  += pongmaindialog.h

FORMS    += pongmaindialog.ui

 

 

 

 

 

main.cpp

 

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

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

 

 

 

 

 

pongmaindialog.h

 

#ifndef PONGMAINDIALOG_H
#define PONGMAINDIALOG_H

#include <QDialog>

namespace Ui {
class PongMainDialog;
}

class PongMainDialog : public QDialog
{
  Q_OBJECT
    
public:
  explicit PongMainDialog(QWidget *parent = 0);
  ~PongMainDialog();
    
private:
  Ui::PongMainDialog *ui;
};

#endif // PONGMAINDIALOG_H

 

 

 

 

 

pongmaindialog.cpp

 

#include <cmath>
#include <QGraphicsPixmapItem>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QTimer>
#include <QVBoxLayout>

#include "pongmaindialog.h"
#include "ui_pongmaindialog.h"



struct Background : public QGraphicsPixmapItem
{
  Background(
    QGraphicsItem * parent = 0,
    QGraphicsScene * scene = 0,
    const int width = 256,
    const int height = 256)
    : QGraphicsPixmapItem(parent,scene)
  {

    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
{
  Sprite(
    QGraphicsItem * parent = 0,
    QGraphicsScene * scene = 0,
    const int width = 32,
    const int height = 32)
    : QGraphicsPixmapItem(parent,scene),
      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;
};




PongMainDialog::PongMainDialog(QWidget *parent) :
  QDialog(parent),
  ui(new Ui::PongMainDialog)
{
  ui->setupUi(this);


  //Start with creating a scene
  QGraphicsScene * const scene(new QGraphicsScene(this));

  //Connect a view to display the scene
  QGraphicsView * const view(new QGraphicsView(scene));
  //view->setScene(scene);

  //Create a layout to put the scene in
  QVBoxLayout * const layout(new QVBoxLayout(this));
  layout->addWidget(view);

  //Add background to scene
  Background * const background(new Background(0,scene));

  //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 = 2.0 * M_PI / static_cast<double>(n_sprites);
    double angle = 0.0;
    for (int i=0; i!=n_sprites; ++i)
    {
      Sprite * const sprite(new Sprite(0,scene));
      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());
      angle+=d_angle;
    }
  }

  //Create a dialog to display to laid-out-scene
  //this->setLayout(layout);
  this->setGeometry(view->rect());

  //Create a timer to call 'advance' on all sprites'
  QTimer * const timer(new QTimer(scene));
  timer->connect(timer, SIGNAL(timeout()), scene, SLOT(advance()));
  timer->start(20);

}

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

 

 

 

 

 

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

Go back to Richel Bilderbeek's homepage.

 

Valid XHTML 1.0 Strict