SFML and Dot

As I become a little more competent in C++ I feel its time for me to start working with UI’s. I have made a project which displays a Star Wars logo and for obvious trademark reasons I can’t post that. I can however post this project. It’s a bouncing red circle. Whilst this did take quite a bit of Googling it did turn out ok. The dot is created to detect edges and bounce off of them in the other direction. Now the plan is to add more dots and define gravity and make it interactive. I’m not sure how long that is going to take so maybe something for the distant future. For now though I’m happy I have got 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) { // <---
                direction.x *= -1;
                new_pos.x = 0 + dot_radius;
            } else if (new_pos.x + dot_radius >= window_width) { // --->
                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;
}


Related Post

Leave a Reply

Your email address will not be published.