Ball creation at regular intervals, falling ball game
-
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); }
-
@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.
-
@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 -
@Iftekhar
Before you get that far, I would completely rethink yourclass 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 adraw()
method to draw it. This seems completely unsuitable, and the wrong way round. If anything a sprite should be aQWidget
or aQObject
, perhaps with aQTimer
as a member; or theQTimer
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 aQTimer
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 oneQTimer
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 yourSprite
s can be subclassed fromQGraphicsEllipseItem
. 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.