feat: velocity tracking w/ rendering lines

This commit is contained in:
Florian Sylvain
2025-05-11 00:18:01 +02:00
parent 92ca5cd5fb
commit 874b54cf36
5 changed files with 78 additions and 3 deletions
+25 -2
View File
@@ -5,7 +5,10 @@
#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)
: m_radius(radius), m_velocity(vel) { : m_radius(radius),
m_velocity(vel),
m_lastPosition(pos),
m_pixelVelocity(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);
@@ -13,17 +16,30 @@ Ball::Ball(float radius, const sf::Vector2f& pos, const sf::Vector2f& vel)
} }
void Ball::update(float dt) { void Ball::update(float dt) {
if (m_atRest) return;
m_velocity.y += Constants::GRAVITY * dt; m_velocity.y += Constants::GRAVITY * dt;
m_shape.move(m_velocity * dt); m_shape.move(m_velocity * dt);
sf::Vector2f currentPosition = m_shape.getPosition();
m_pixelVelocity = (currentPosition - m_lastPosition) / dt;
m_lastPosition = currentPosition;
handleWallCollision(); handleWallCollision();
} }
void Ball::draw(sf::RenderWindow& window) { window.draw(m_shape); } void Ball::draw(sf::RenderWindow& window) { window.draw(m_shape); }
void Ball::applyImpulse(const sf::Vector2f& impulse) { m_velocity += impulse; } void Ball::applyImpulse(const sf::Vector2f& impulse) {
m_velocity += impulse;
m_atRest = false;
}
sf::Vector2f Ball::getPosition() const { return m_shape.getPosition(); } sf::Vector2f Ball::getPosition() const { return m_shape.getPosition(); }
sf::Vector2f Ball::getVelocity() const { return m_velocity; }
bool Ball::isAtRest() const { return m_atRest; }
void Ball::handleWallCollision() { void Ball::handleWallCollision() {
sf::Vector2f pos = m_shape.getPosition(); sf::Vector2f pos = m_shape.getPosition();
@@ -51,6 +67,13 @@ void Ball::handleWallCollision() {
if (pos.y + m_radius >= Constants::HEIGHT - 1.0f) { if (pos.y + m_radius >= Constants::HEIGHT - 1.0f) {
m_velocity.x *= Constants::FRICTION; m_velocity.x *= Constants::FRICTION;
if (std::abs(m_velocity.x) < 5.f) m_velocity.x = 0.f; if (std::abs(m_velocity.x) < 5.f) m_velocity.x = 0.f;
if (std::abs(m_pixelVelocity.x) < Constants::REST_PIXEL_VELOCITY &&
std::abs(m_pixelVelocity.y) < Constants::REST_PIXEL_VELOCITY) {
m_velocity = {0.f, 0.f};
m_atRest = true;
}
} else {
m_atRest = false;
} }
m_shape.setPosition(pos); m_shape.setPosition(pos);
+6
View File
@@ -8,6 +8,9 @@ class Ball : public PhysicalObject {
sf::CircleShape m_shape; sf::CircleShape m_shape;
sf::Vector2f m_velocity; sf::Vector2f m_velocity;
float m_radius; float m_radius;
bool m_atRest = false;
sf::Vector2f m_lastPosition;
sf::Vector2f m_pixelVelocity;
void handleWallCollision(); void handleWallCollision();
@@ -19,4 +22,7 @@ class Ball : public PhysicalObject {
void applyImpulse(const sf::Vector2f& impulse) override; void applyImpulse(const sf::Vector2f& impulse) override;
sf::Vector2f getPosition() const; sf::Vector2f getPosition() const;
sf::Vector2f getVelocity() const;
bool isAtRest() const;
sf::Vector2f getPixelVelocity() const { return m_pixelVelocity; }
}; };
+1
View File
@@ -8,4 +8,5 @@ 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 = 3000.f;
constexpr float REST_PIXEL_VELOCITY = 2.0f;
} // namespace Constants } // namespace Constants
+39 -1
View File
@@ -1,8 +1,8 @@
#include "Game.hpp" #include "Game.hpp"
#include <SFML/Window/Event.hpp> #include <SFML/Window/Event.hpp>
#include <cmath>
#include "Ball.hpp"
#include "Constants.hpp" #include "Constants.hpp"
#include "VectorMath.hpp" #include "VectorMath.hpp"
@@ -61,9 +61,47 @@ void Game::update() {
for (auto& object : m_objects) object->update(dt); for (auto& object : m_objects) object->update(dt);
} }
void Game::drawLine(const sf::Vector2f& start, const sf::Vector2f& direction,
float length, const sf::Color& color) {
float dirLength =
std::sqrt(direction.x * direction.x + direction.y * direction.y);
sf::Vector2f dirNorm =
(dirLength != 0.f) ? direction / dirLength : sf::Vector2f(1.f, 0.f);
sf::Vector2f endPoint = start + dirNorm * length;
sf::Vertex line[] = {{start, color}, {endPoint, color}};
m_window.draw(line, 2, sf::PrimitiveType::Lines);
}
void Game::drawDirectionLine(const Ball* ball) {
sf::Vector2f ballCenter = ball->getPosition();
sf::Vector2i mousePixel = sf::Mouse::getPosition(m_window);
sf::Vector2f mouseWorld(static_cast<float>(mousePixel.x),
static_cast<float>(mousePixel.y));
sf::Vector2f dir = mouseWorld - ballCenter;
drawLine(ballCenter, dir, 100.f, sf::Color::Green);
}
void Game::drawVelocityLine(const Ball* ball) {
if (ball->isAtRest()) return;
sf::Vector2f ballCenter = ball->getPosition();
sf::Vector2f velocity = ball->getVelocity();
float velLength =
std::sqrt(velocity.x * velocity.x + velocity.y * velocity.y);
float clampedLength = std::min(100.f, std::max(0.f, velLength));
drawLine(ballCenter, velocity, clampedLength, sf::Color::Blue);
}
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); for (auto& object : m_objects) object->draw(m_window);
auto* ball = dynamic_cast<Ball*>(m_objects[0].get());
if (ball) {
drawDirectionLine(ball);
drawVelocityLine(ball);
}
m_window.display(); m_window.display();
} }
+7
View File
@@ -6,8 +6,10 @@
#include <memory> #include <memory>
#include <vector> #include <vector>
#include "Ball.hpp"
#include "PhysicalObject.hpp" #include "PhysicalObject.hpp"
class Ball;
class PhysicalObject; class PhysicalObject;
class Game { class Game {
@@ -24,6 +26,11 @@ class Game {
void update(); void update();
void render(); void render();
void drawLine(const sf::Vector2f& start, const sf::Vector2f& direction,
float length, const sf::Color& color);
void drawDirectionLine(const Ball* ball);
void drawVelocityLine(const Ball* ball);
public: public:
Game(); Game();
void run(); void run();