mirror of
https://github.com/Floriansylvain/SFMLplayground.git
synced 2026-08-19 11:43:24 +02:00
feat: velocity tracking w/ rendering lines
This commit is contained in:
+25
-2
@@ -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);
|
||||||
|
|||||||
@@ -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; }
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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
@@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user