Improve physics

This commit is contained in:
ItsDrike 2025-03-24 18:58:08 +01:00
parent 24eeaa411b
commit 7546e00325
Signed by: ItsDrike
GPG key ID: FA2745890B7048C0
3 changed files with 35 additions and 22 deletions

View file

@ -6,20 +6,34 @@
#include <random> #include <random>
#define RADIUS 15 #define RADIUS 15
#define TICK_SPEED 10 #define TOP_MARGIN 35 // This is the menu bar height (no easy way to get programatically)
#define MAX_SPEED 5.0
#define GRAVITY 0.981
double getRandomDouble(double maxValue); #define TICK_SPEED 10
#define MAX_X_SPEED 5.0
#define MIN_X_SPEED 2.0
#define MAX_Y_SPEED 8.0
#define MIN_Y_SPEED 4.0
#define GRAVITY 0.022
double getRandomDouble(double minValue, double maxValue);
Ball::Ball(QWidget* parent, std::shared_ptr<Platform> platform) : m_parent{parent}, m_platform{platform}, m_isSpawning{true} { Ball::Ball(QWidget* parent, std::shared_ptr<Platform> platform) : m_parent{parent}, m_platform{platform}, m_isSpawning{true} {
QRect rct = parent->rect(); QRect rct = parent->rect();
m_x = rand() % rct.width(); // random x pos m_x = rand() % (rct.width() - RADIUS * 2); // random x pos
m_y = rct.height() + 5; // start below the screen m_y = rct.height() + 5; // start below the screen
m_kx = getRandomDouble(MAX_SPEED); // random horizontal speed // Random X speed, including rand direction
m_ky = -MAX_SPEED; // (this isn't simply done with a negative minimum, as we
// don't want to allow speeds close to 0)
m_kx = getRandomDouble(MIN_X_SPEED, MAX_X_SPEED);
if (rand() % 2 == 0)
m_kx = -m_kx;
// Random Y speed (always starts going up / negative)
m_ky = -getRandomDouble(MIN_Y_SPEED, MAX_Y_SPEED);
start(TICK_SPEED); start(TICK_SPEED);
} }
@ -29,20 +43,20 @@ void Ball::draw(QPainter& painter) {
} }
void Ball::timerEvent(QTimerEvent*) { void Ball::timerEvent(QTimerEvent*) {
if (m_ky < -MAX_SPEED) m_ky = std::min(m_ky + GRAVITY, MAX_Y_SPEED);
m_ky = std::max(m_ky - GRAVITY, -MAX_SPEED);
QRect rct = m_parent->rect();
// Horizontal wall collision // Horizontal wall collision
QRect rct = m_parent->rect(); if (m_x < 0 || m_x > rct.width() - RADIUS * 2.0)
if (m_x < RADIUS || m_x > rct.width() - RADIUS) {
m_kx *= -1; m_kx *= -1;
}
// Ceiling collision // Ceiling collision
if (m_y < RADIUS) { if (m_y < TOP_MARGIN)
m_ky *= -1; m_ky *= -1;
}
// Bottom collision (only if no longer spawning) // Bottom collision (only if no longer spawning)
if (!m_isSpawning && m_y > rct.height() - RADIUS) { if (!m_isSpawning && m_y > rct.height() - RADIUS * 2.0) {
emit fellThrough(this); emit fellThrough(this);
stop(); stop();
m_parent->update(); m_parent->update();
@ -69,13 +83,13 @@ void Ball::timerEvent(QTimerEvent*) {
m_parent->update(); m_parent->update();
} }
double getRandomDouble(double maxValue) { double getRandomDouble(double minValue, double maxValue) {
// Create a random device and a random engine // Create a random device and a random engine
std::random_device rd; std::random_device rd;
std::mt19937 gen(rd()); std::mt19937 gen(rd());
// Define the range from 0 to maxValue // Define the range from 0 to maxValue
std::uniform_real_distribution<> dis(0.0, maxValue); std::uniform_real_distribution<> dis(minValue, maxValue);
// Return the random value // Return the random value
return dis(gen); return dis(gen);

View file

@ -4,9 +4,9 @@
#include <memory> #include <memory>
#include <qnamespace.h> #include <qnamespace.h>
#define INIT_SPAWN_SPEED 1500.0 #define INIT_SPAWN_SPEED 2000.0
#define SPAWN_SPEED_INCREASE 100.0 #define SPAWN_SPEED_INCREASE 50.0
#define MIN_SPAWN_SPEED 100.0 #define MIN_SPAWN_SPEED 800.0
MainWindow::MainWindow(QWidget* parent) : MainWindow::MainWindow(QWidget* parent) :
QMainWindow(parent), ui(new Ui::MainWindow), leftArrowPressed{false}, rightArrowPressed{false}, m_spawnInterval{INIT_SPAWN_SPEED}, m_score{0} { QMainWindow(parent), ui(new Ui::MainWindow), leftArrowPressed{false}, rightArrowPressed{false}, m_spawnInterval{INIT_SPAWN_SPEED}, m_score{0} {
@ -44,7 +44,6 @@ void MainWindow::deleteBall(Ball* ball) {
// This will also free it (smart ptrs). // This will also free it (smart ptrs).
for (auto it = balls.begin(); it != balls.end(); ++it) { for (auto it = balls.begin(); it != balls.end(); ++it) {
if (it->get() == ball) { if (it->get() == ball) {
qDebug() << "Deleting ball";
balls.erase(it); balls.erase(it);
break; break;
} }

View file

@ -7,7 +7,7 @@
#define PLATFORM_WIDTH 100 #define PLATFORM_WIDTH 100
#define PLATFORM_HEIGHT 20 #define PLATFORM_HEIGHT 20
#define PLATFORM_MARGIN_BOTTOM 80 #define PLATFORM_MARGIN_BOTTOM 80
#define SPEED 7.0 #define SPEED 10.0
Platform::Platform(MainWindow* parent) : m_parent{parent} { Platform::Platform(MainWindow* parent) : m_parent{parent} {
QRect rct = parent->rect(); QRect rct = parent->rect();