From 87e2a0e9aae8a81103120715009577dc68b06ca6 Mon Sep 17 00:00:00 2001 From: ItsDrike Date: Tue, 11 Mar 2025 13:26:17 +0100 Subject: [PATCH] Basic ball --- CMakeLists.txt | 1 + src/ball.cpp | 68 ++++++++++++++++++++++++++++++++++++++++++++++ src/ball.h | 25 +++++++++++++++++ src/mainwindow.cpp | 22 +++++++++++---- src/mainwindow.h | 18 +++++++----- 5 files changed, 121 insertions(+), 13 deletions(-) create mode 100644 src/ball.cpp create mode 100644 src/ball.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 3a55ea7..1901005 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -35,6 +35,7 @@ else() else() add_executable(${PROJECT_NAME} ${PROJECT_SOURCES} + src/ball.h src/ball.cpp ) endif() endif() diff --git a/src/ball.cpp b/src/ball.cpp new file mode 100644 index 0000000..0030277 --- /dev/null +++ b/src/ball.cpp @@ -0,0 +1,68 @@ +#include "ball.h" +#include +#include +#include + +#define RADIUS 15 +#define TICK_SPEED 10 +#define MAX_SPEED 5.0 +#define GRAVITY 0.981 + +double getRandomDouble(double maxValue); + +Ball::Ball(QWidget* parent) : m_parent{parent}, m_isSpawning{true} { + QRect rct = parent->rect(); + + m_x = rand() % rct.width(); // random x pos + m_y = rct.height() + 5; // start below the screen + + m_kx = getRandomDouble(MAX_SPEED); // random horizontal speed + m_ky = -MAX_SPEED; + + start(TICK_SPEED); +} + +void Ball::draw(QPainter& painter) { + painter.drawEllipse(m_x, m_y, RADIUS * 2.0, RADIUS * 2.0); +} + +void Ball::timerEvent(QTimerEvent*) { + if (m_ky < -MAX_SPEED) + m_ky = std::max(m_ky - GRAVITY, -MAX_SPEED); + + // Horizontal wall collision + QRect rct = m_parent->rect(); + if (m_x < RADIUS || m_x > rct.width() - RADIUS) { + m_kx *= -1; + } + // Ceiling collision + if (m_y < RADIUS) { + m_ky *= -1; + } + // Bottom collision (only if no longer spawning) + if (!m_isSpawning && m_y > rct.height() - RADIUS) { + // TODO: Destroy ball + } + + m_x += m_kx; + m_y += m_ky; + + // Once we get into the window, we're no longer "spawning" + if (m_isSpawning && m_y < rct.width() - RADIUS) + m_isSpawning = false; + + // Update the window + m_parent->update(); +} + +double getRandomDouble(double maxValue) { + // Create a random device and a random engine + std::random_device rd; + std::mt19937 gen(rd()); + + // Define the range from 0 to maxValue + std::uniform_real_distribution<> dis(0.0, maxValue); + + // Return the random value + return dis(gen); +} diff --git a/src/ball.h b/src/ball.h new file mode 100644 index 0000000..e895f91 --- /dev/null +++ b/src/ball.h @@ -0,0 +1,25 @@ +#ifndef BALL_H +#define BALL_H + +#include +#include + +class Ball : public QTimer { + public: + Ball(QWidget* parent); + + void draw(QPainter& painter); + + protected: + virtual void timerEvent(QTimerEvent*) override; + + private: + QWidget* m_parent; + double m_x; + double m_y; + double m_kx; + double m_ky; + bool m_isSpawning; +}; + +#endif // BALL_H diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 6395a77..1f0d95b 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -1,14 +1,24 @@ #include "mainwindow.h" #include "./ui_mainwindow.h" -MainWindow::MainWindow(QWidget *parent) - : QMainWindow(parent) - , ui(new Ui::MainWindow) -{ +MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); + balls.append(std::make_shared(this)); } -MainWindow::~MainWindow() -{ +MainWindow::~MainWindow() { delete ui; } + +void MainWindow::paintEvent(QPaintEvent*) { + QPainter painter(this); + + painter.fillRect(rect(), Qt::darkGray); + + painter.setBrush(QBrush(Qt::white)); + painter.setPen(Qt::black); + + for (auto ball : balls) { + ball->draw(painter); + } +} diff --git a/src/mainwindow.h b/src/mainwindow.h index f7a3da3..41dc4a2 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -1,23 +1,27 @@ #ifndef MAINWINDOW_H #define MAINWINDOW_H +#include "ball.h" #include QT_BEGIN_NAMESPACE namespace Ui { -class MainWindow; + class MainWindow; } QT_END_NAMESPACE -class MainWindow : public QMainWindow -{ +class MainWindow : public QMainWindow { Q_OBJECT -public: - MainWindow(QWidget *parent = nullptr); + public: + MainWindow(QWidget* parent = nullptr); ~MainWindow(); -private: - Ui::MainWindow *ui; + protected: + virtual void paintEvent(QPaintEvent*) override; + + private: + Ui::MainWindow* ui; + QList> balls; }; #endif // MAINWINDOW_H