SFML and Dot

https://www.youtube.com/watch?v=Idms4kairNk&feature=youtu.be

As I become a little more competent in C++, I feel it’s time for me to start working with UIs. I have made a project that displays a Star Wars logo, but for obvious trademark reasons, I can’t post that. However, I can post this project. It’s a bouncing red circle. While this took quite a bit of Googling, it turned out okay. The dot is created to detect edges and bounce off of them in the other direction.

Now, the plan is to add more dots, define gravity, and make it interactive. I’m not sure how long that will take, so maybe it’s something for the distant future. For now, though, I’m happy I’ve gotten this far!

#include <SFML/Graphics.hpp>
#include <cmath>
#include <cstdlib>
#include <functional>
#include <random>

int main()
{
    const int window_width = 1024;
    const int window_height = 768;
    const float dot_radius = 32.f;
    const int bpp = 16;

    sf::RenderWindow window(sf::VideoMode(window_width, window_height, bpp), "Bouncing Dot");
    window.setVerticalSyncEnabled(true);

    std::random_device seed_device;
    std::default_random_engine engine(seed_device());
    std::uniform_int_distribution<int> distribution(-16, 16);
    auto random = std::bind(distribution, std::ref(engine));

    sf::Vector2f direction(random(), random());
    const float velocity = std::sqrt(direction.x * direction.x + direction.y * direction.y);

    sf::CircleShape dot(dot_radius - 4);

    // Removed for personal reasons - Added this but was not a fan of outline.
    //dot.setOutlineThickness(0);
    //dot.setOutlineColor(sf::Color::Black);

    dot.setFillColor(sf::Color::Red);
    dot.setOrigin(dot.getRadius(), dot.getRadius());
    dot.setPosition(window_width / 2, window_height / 2);

    sf::Clock clock;
    sf::Time elapsed = clock.restart();
    const sf::Time update_ms = sf::seconds(1.f / 30.f);
    
    while (window.isOpen()) {
        sf::Event event;
        while (window.pollEvent(event)) {
            if ((event.type == sf::Event::Closed) || ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Escape))) {
                window.close();
                break;
            }
        }

        elapsed += clock.restart();
        while (elapsed >= update_ms) {
            const auto pos = dot.getPosition();
            const auto delta = update_ms.asSeconds() * velocity;
            sf::Vector2f new_pos(pos.x + direction.x * delta, pos.y + direction.y * delta);

            if (new_pos.x - dot_radius < 0) { // Left
                direction.x *= -1;
                new_pos.x = 0 + dot_radius;
            } else if (new_pos.x + dot_radius >= window_width) { // Right
                direction.x *= -1;
                new_pos.x = window_width - dot_radius;
            } else if (new_pos.y - dot_radius < 0) { // Top
                direction.y *= -1;
                new_pos.y = 0 + dot_radius;
            } else if (new_pos.y + dot_radius >= window_height) { // Bottom
                direction.y *= -1;
                new_pos.y = window_height - dot_radius;
            }
            dot.setPosition(new_pos);

            elapsed -= update_ms;
        }

        window.clear(sf::Color(102, 102, 102));
        window.draw(dot);
        window.display();
    }

    return EXIT_SUCCESS;
}