feat: BallFactory for random ball generation

This commit is contained in:
Florian Sylvain
2025-05-11 01:28:07 +02:00
parent 885ed1ec4b
commit f276d243ec
6 changed files with 73 additions and 16 deletions
+3 -2
View File
@@ -4,7 +4,8 @@
#include "Constants.hpp" #include "Constants.hpp"
Ball::Ball(float radius, const sf::Vector2f& pos, const sf::Vector2f& vel) Ball::Ball(float radius, const sf::Vector2f& pos, const sf::Vector2f& vel,
const sf::Color& color)
: m_radius(radius), : m_radius(radius),
m_velocity(vel), m_velocity(vel),
m_lastPosition(pos), m_lastPosition(pos),
@@ -12,7 +13,7 @@ Ball::Ball(float radius, const sf::Vector2f& pos, const sf::Vector2f& vel)
m_shape.setRadius(radius); m_shape.setRadius(radius);
m_shape.setOrigin(sf::Vector2f(radius, radius)); m_shape.setOrigin(sf::Vector2f(radius, radius));
m_shape.setPosition(pos); m_shape.setPosition(pos);
m_shape.setFillColor(sf::Color::Red); m_shape.setFillColor(color);
} }
void Ball::update(float dt) { void Ball::update(float dt) {
+2 -1
View File
@@ -15,7 +15,8 @@ class Ball : public PhysicalObject {
void handleWallCollision(); void handleWallCollision();
public: public:
Ball(float radius, const sf::Vector2f& pos, const sf::Vector2f& vel); Ball(float radius, const sf::Vector2f& pos, const sf::Vector2f& vel,
const sf::Color& color);
void update(float dt) override; void update(float dt) override;
void draw(sf::RenderWindow& window) override; void draw(sf::RenderWindow& window) override;
+38
View File
@@ -0,0 +1,38 @@
#include "BallFactory.hpp"
#include <cstdlib>
#include <ctime>
#include "Constants.hpp"
namespace BallFactory {
std::unique_ptr<Ball> generateRandBall() {
float radius = Constants::BALL_RADIUS;
int diameter = static_cast<int>(2 * radius);
int maxX = Constants::WIDTH - diameter;
int maxY = Constants::HEIGHT - diameter;
float x = static_cast<float>((std::rand() % maxX) + radius);
float y = static_cast<float>((std::rand() % maxY) + radius);
float vel = static_cast<float>((std::rand() % 401) - 200);
auto randColorComp = []() {
return static_cast<std::uint8_t>(64 + (std::rand() % (256 - 64)));
};
sf::Color color(randColorComp(), randColorComp(), randColorComp());
auto position = sf::Vector2f(x, y);
auto velocity = sf::Vector2f(vel, vel);
return std::make_unique<Ball>(radius, position, velocity, color);
}
std::vector<std::unique_ptr<Ball>> generateBalls() {
std::vector<std::unique_ptr<Ball>> balls;
std::srand(static_cast<unsigned>(std::time(nullptr)));
for (int i = 0; i < Constants::BALL_QUANTITY; ++i) {
auto ball = generateRandBall();
balls.push_back(std::move(ball));
}
return balls;
}
} // namespace BallFactory
+10
View File
@@ -0,0 +1,10 @@
#pragma once
#include <memory>
#include <vector>
#include "Ball.hpp"
namespace BallFactory {
std::unique_ptr<Ball> generateRandBall();
std::vector<std::unique_ptr<Ball>> generateBalls();
} // namespace BallFactory
+2 -1
View File
@@ -7,6 +7,7 @@ constexpr float GRAVITY = 8000.f;
constexpr float RESTITUTION = 0.8f; constexpr float RESTITUTION = 0.8f;
constexpr float FRICTION = 0.9f; constexpr float FRICTION = 0.9f;
constexpr float BALL_RADIUS = 20.f; constexpr float BALL_RADIUS = 20.f;
constexpr float IMPULSE = 3000.f; constexpr float IMPULSE = 2500.f;
constexpr float REST_PIXEL_VELOCITY = 2.0f; constexpr float REST_PIXEL_VELOCITY = 2.0f;
constexpr unsigned BALL_QUANTITY = 10;
} // namespace Constants } // namespace Constants
+17 -11
View File
@@ -3,6 +3,7 @@
#include <SFML/Window/Event.hpp> #include <SFML/Window/Event.hpp>
#include <cmath> #include <cmath>
#include "BallFactory.hpp"
#include "Constants.hpp" #include "Constants.hpp"
#include "DebugDraw.hpp" #include "DebugDraw.hpp"
#include "VectorMath.hpp" #include "VectorMath.hpp"
@@ -16,10 +17,11 @@ Game::Game()
m_window.setVerticalSyncEnabled(true); m_window.setVerticalSyncEnabled(true);
m_timeScale = 1.0f; m_timeScale = 1.0f;
m_objects.clear(); m_objects.clear();
m_objects.push_back(std::make_unique<Ball>(
Constants::BALL_RADIUS, auto balls = BallFactory::generateBalls();
sf::Vector2f(Constants::WIDTH / 2.f, Constants::HEIGHT / 4.f), for (auto &ball : balls) {
sf::Vector2f(400.f, 0.f))); m_objects.push_back(std::move(ball));
}
} }
void Game::processKeyPressed(const sf::Event::KeyPressed &kP) { void Game::processKeyPressed(const sf::Event::KeyPressed &kP) {
@@ -37,14 +39,15 @@ void Game::processMousePressed(const sf::Event::MouseButtonPressed &mP) {
} }
void Game::handleMouseClick(const sf::Vector2i &mousePos) { void Game::handleMouseClick(const sf::Vector2i &mousePos) {
auto *ball = dynamic_cast<Ball *>(m_objects[0].get());
if (!ball) return;
sf::Vector2f mouseWorld(static_cast<float>(mousePos.x), sf::Vector2f mouseWorld(static_cast<float>(mousePos.x),
static_cast<float>(mousePos.y)); static_cast<float>(mousePos.y));
sf::Vector2f dir = mouseWorld - ball->getPosition(); for (auto &object : m_objects) {
auto *ball = dynamic_cast<Ball *>(object.get());
if (!ball) continue;
sf::Vector2f dir = mouseWorld - ball->getPosition();
ball->applyImpulse(Constants::IMPULSE * VectorMath::normalize(dir)); ball->applyImpulse(Constants::IMPULSE * VectorMath::normalize(dir));
}
} }
void Game::update() { void Game::update() {
@@ -54,10 +57,13 @@ void Game::update() {
void Game::render() { void Game::render() {
m_window.clear(sf::Color::Black); m_window.clear(sf::Color::Black);
for (auto &object : m_objects) object->draw(m_window);
auto *ball = dynamic_cast<Ball *>(m_objects[0].get()); for (const auto &object : m_objects) {
if (ball) { object->draw(m_window);
auto *ball = dynamic_cast<Ball *>(object.get());
if (!ball) continue;
DebugDraw::drawDirectionLine(m_window, ball); DebugDraw::drawDirectionLine(m_window, ball);
DebugDraw::drawVelocityLine(m_window, ball); DebugDraw::drawVelocityLine(m_window, ball);
} }