Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Ball creation at regular intervals, falling ball game
Forum Updated to NodeBB v4.3 + New Features

Ball creation at regular intervals, falling ball game

Scheduled Pinned Locked Moved Unsolved General and Desktop
4 Posts 3 Posters 502 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • I Offline
    I Offline
    Iftekhar
    wrote on last edited by
    #1

    I am working on Falling ball application, About the application: the balls keep on falling at regular intervals, and there is a basket that catches the balls. If caught then we earn a point if not then lose one life.

    For this application, I am using qt and CPP. I have created one class Sprite with specifications regarding the initial position of the ball(x and y) and speed (dx and dy). I am using one timer for the speed of the ball, but I need to another timer for ball creation at regular intervals. Could anyone help me with how to implement the ball creation at regular intervals?

    sprite.h
    --------
    #ifndef SPRITE_H
    #define SPRITE_H
    
    #include <QTimer>
    #include <QPainter>
    #include <QWidget>
    
    /**
     * Header class for Sprite
     */
    class Sprite : public QTimer
    {
    public:
        Sprite(QWidget *parent);
        //draw() to draw a sprite
        void draw(QPainter &painter);
    protected:
        //This timerEvent will be called after certain time prescribed.
        virtual void timerEvent(QTimerEvent *e) override;
    
        int x;//position of sprite in x-direction.
        int y;//position of sprite in y-direction.
        int dx;//difference in x-direction position.
        int dy;//difference in y-direction position.
        int x1;//position of the basket in x-direction
        int y1;//position of the basket in y-direction.
        QWidget *parent;//parent class for all widgets.
    
    };
    #endif // SPRITE_H
    
    
    sprite.cpp
    -----------
    #include "sprite.h"
    #include <QDebug>
    
    Sprite::Sprite(QWidget *parent):parent(parent)
    {
        QRect rct = parent->rect();
        x = rand() % rct.width();//randomly initialize the x-position for the sprite.
        y=rct.height()*0.05;//start position for the sprite is about 5% after the top of the menu bar.
    
        dx = rand() % 10;//the speed is randomly set in x-direction.
    
    //    dy = rand() % 10;//the speed is randomly set in y-direction.
        dy = 4;
    
        x1=rct.width()/2;
        y1 = rct.height()-80;
    
        start(10);
    
    }
    
    void Sprite::draw(QPainter &painter)
    {
        qDebug() <<"Sprite::draw() called";
        painter.drawEllipse(x, y, 15, 15);//ball
        painter.drawRect( x1, y1, 80, 30);//basket
    }
    
    
    void Sprite::timerEvent(QTimerEvent *)
    {
        qDebug("timerEvent called");
        QRect rct = parent->rect();
        if ( x > rct.width() || x < 0)
            dx *= -1;
        if ( y > rct.height() || y < 0){}
    
        x += dx;
        y += dy;
        parent->update();
    }
    
    
    mainwindow.cpp
    -----------------
    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include <QDebug>
    #include <QKeyEvent>
    
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent)
        , ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        qDebug() <<"mainWindow constructor";
    
         sprite = new Sprite(this);
        connect(this, &MainWindow::draw, sprite, &Sprite::draw);
    }
    
    MainWindow::~MainWindow()
    {
        qDebug() <<"mainWindow destructor";
        delete ui;
    }
    
    void MainWindow::paintEvent(QPaintEvent *)
    {
        qDebug() <<"painEvent() called";
        QPainter painter(this);
    
        painter.fillRect(rect(), QBrush(QColor(Qt::white)));
    
        painter.setPen(Qt::black);
        painter.setBrush(QBrush(QColor(Qt::darkBlue)));
        emit draw(painter);
    }
    
    
    1 Reply Last reply
    0
    • Christian EhrlicherC Offline
      Christian EhrlicherC Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #2

      @Iftekhar said in Ball creation at regular intervals, falling ball game:

      Could anyone help me with how to implement the ball creation at regular intervals?

      As already told you on stackoverflow - create another timer and call update as shown you in the other thread.

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      1 Reply Last reply
      1
      • I Offline
        I Offline
        Iftekhar
        wrote on last edited by
        #3

        @Christian-Ehrlicher
        I cannot understand how to create a new time and where to create it,
        in Mainwindow.cpp constructor , or some where else.
        Please provide some sude code so that I can work with. Thanks

        JonBJ 1 Reply Last reply
        0
        • I Iftekhar

          @Christian-Ehrlicher
          I cannot understand how to create a new time and where to create it,
          in Mainwindow.cpp constructor , or some where else.
          Please provide some sude code so that I can work with. Thanks

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by JonB
          #4

          @Iftekhar
          Before you get that far, I would completely rethink your class Sprite : public QTimer class. Subclassing should be thought of/subject to the "is-a" test: is a sprite a (kind of) timer?

          A sprite is an object you draw, which maybe has a position which changes over time. You have it as an instance/subclass of a QTimer, with a draw() method to draw it. This seems completely unsuitable, and the wrong way round. If anything a sprite should be a QWidget or a QObject, perhaps with a QTimer as a member; or the QTimer might be better external to the sprite.

          void MainWindow::paintEvent(QPaintEvent *)
          {
              QPainter painter(this);
              // ...
              emit draw(painter);
          }
          

          I don't think you should be emitting any signal here, nor pass it a QPainter.

          I think I would just have a list of all the ball-sprites in existence. A single QTimer which, each time it ticks, causes code to go through the list and update the positions of every sprite. (Unless you want accuracy/timing/movement on each ball separately, so they don't all move at the same time: in that case you might put a QTimer into each sprite, but it would not be my inclination.) You can then also use that same timer to cause a new sprite to be created and added to the list, by checking if the current tick is at one of the "regular intervals" for creation. Or, if you prefer, have a second timer ticking just for new ball creation. We end up with either one QTimer or two, no matter how many sprites there are.

          If your whole objective is to have an area showing a number of "balls" moving around, I would be tempted to change over to using a QGraphicsScene + QGraphicsView. Then your Sprites can be subclassed from QGraphicsEllipseItem. You can then create, remove and move them easily.

          I could also mention the possibility of using QAnimation to automate smooth movement of objects; but that may be a step further than you want.

          1 Reply Last reply
          1

          • Login

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved