Search code examples
c++sfml

How to make sf::Vector2f transform(float t) speed faster?


#include <iostream>
#include <SFML/Graphics.hpp>


float  period_ms = 5000.f;
using namespace std;

sf::Vector2f transform(float t)
{
    float const ellipse_width = 500.f;
    float const ellipse_height = 500.f;
    float const a = ellipse_width / 2.f;
    float const b = ellipse_height / 2.f;
    float const pi = 3.141592653589f;
    float const tau = 2.f * pi;

    float const x = (std::fmodf(t, period_ms) / period_ms) * tau;
    return sf::Vector2f(a * std::cos(x), b * std::sin(x));
}
int main()
{
    sf::ContextSettings settings;
    settings.antialiasingLevel = 8;
    sf::RenderWindow window(sf::VideoMode(1000, 1000), "SFML shapes", sf::Style::Default, settings);
    window.setFramerateLimit(144);

    //white orbitting circle
    sf::CircleShape shape(28.f);
    shape.setFillColor(sf::Color::Black);
    shape.setOutlineColor(sf::Color::Red);
    shape.setOutlineThickness(5);
    //white orbitting circle

    //center red circle
    sf::CircleShape shapeTwo(208.f);
    shapeTwo.setFillColor(sf::Color::Red);
    shapeTwo.setOutlineThickness(5);
    shapeTwo.setOutlineColor(sf::Color(250, 150, 100));
    shapeTwo.setPosition(325.00, 320.00);
    //base red
    sf::Clock clock;

    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();
        }

        float const t = static_cast<float>(clock.getElapsedTime().asMilliseconds());
        shape.setPosition(sf::Vector2f(500.f, 500.f) + transform(t));

        window.clear();
        window.draw(shape);
        window.draw(shapeTwo);
        window.display();
        cout << "Orbitting X:  " << shape.getPosition().x << ", Y: " << shape.getPosition().y << endl;

    }

    return 0;
}

How do I change the speed at which the circle rotates using sf::Vector2f without it resetting the position of the shape? Like, I have it set on an if condition, that the period_ms lowers, to make the loop faster, but doing that when the condition is fulfilled, makes the shape's position reset.


Solution

  • You can add a time factor variable. This would require you to change some things about time management:

    • Restart the clock each frame and acumulate the time in a separate variable.
    • Have a new variable with the time factor, that multiplies the delta time each frame.
    float timeFactor = 1.0f;
    float accTime = 0.0f;
    

    For example, you could duplicate it while you press space:

    while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();
            else if(event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Space)
                timeFactor = 2.0f;
            else if(event.type == sf::Event::KeyReleased && event.key.code == sf::Keyboard::Space)
                timeFactor = 1.0f;
            
        }
    
    

    Use it to multiply the time you use in your transform and restart the clock.

    float const dt = static_cast<float>(clock.getElapsedTime().asMilliseconds()); // delta time
    accTime += dt * timeFactor;
    shape.setPosition(sf::Vector2f(500.f, 500.f) + transform(accTime));
    clock.restart();
    

    Note that even though this works, there could be a semantic ambiguity with the period variable, as now it only represents the value of the period with time factor 1.