-3

My pong implementation is very choppy, and I think it may be because of how I calculate how much the program sleeps. The maximum frame rate is set to 60 and my computer should be able to run this at 60 frames.

I followed this guide but I am not sure I did it correctly.

This is my main.cpp file:

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

#include "Paddle.hpp"

int framerateLimit = 60; 
unsigned int width = 800;
unsigned int height = 600;

int main()
{
    sf::RenderWindow window(sf::VideoMode({width, height}), "My window");
    window.setFramerateLimit(framerateLimit);
    
    sf::RectangleShape leftPaddle;
    leftPaddle.setSize(sf::Vector2f(10,50));
    leftPaddle.setPosition(sf::Vector2f(20, height / 2.0 - leftPaddle.getSize().y/2));    
    std::cout << leftPaddle.getPosition().x << "," << leftPaddle.getPosition().y << std::endl;

    sf::RectangleShape rightPaddle;
    rightPaddle.setSize(sf::Vector2f(10, 50));
    rightPaddle.setPosition(sf::Vector2f(width - 20 - leftPaddle.getSize().x, height / 2.0 - leftPaddle.getSize().y / 2));

    sf::Clock clock;
    
    const float deltaTime = 0.01f;
    float accumulator = 0.0f;
    float currentTime = clock.getElapsedTime().asSeconds();
    

    while (window.isOpen())
    {
        
        int64_t startTicks = clock.getElapsedTime().asMilliseconds();

        float newTime = clock.getElapsedTime().asSeconds();
        float frameTime = newTime - currentTime;
        
        currentTime = newTime;

        accumulator += frameTime;
        

        while (accumulator >= deltaTime) {
            while (const std::optional event = window.pollEvent())
            {
                // "close requested" event: we close the window
                if (event->is<sf::Event::Closed>()) {
                    window.close();
                }
                if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::W)) {
                    Paddle::moveUp(leftPaddle);
                }
                if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::S)) {
                    Paddle::moveDown(leftPaddle);
                }
                if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Up)) {
                    Paddle::moveUp(rightPaddle);
                }
                if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Down)) {
                    Paddle::moveDown(rightPaddle);
                }

            }
            accumulator -= deltaTime;
        }

        const float alpha = accumulator / deltaTime;

        
        window.clear(sf::Color::Black);

        window.draw(leftPaddle);
        window.draw(rightPaddle);

        window.display();

        
        int frameTicks = clock.getElapsedTime().asMilliseconds() - startTicks;

        if (frameTicks < 1000 / framerateLimit) {
            int duration = 1000 / framerateLimit - frameTicks;
            sf::sleep(sf::milliseconds(duration));
        }
        
    }
}

And this is my movement implementation:

#include "Paddle.hpp"

void Paddle::moveUp(sf::RectangleShape& paddle) {
    paddle.getPosition().y <= 10.f ? paddle.setPosition(sf::Vector2f(paddle.getPosition().x,0)) : paddle.move(sf::Vector2f(0, -10));
}

void Paddle::moveDown(sf::RectangleShape& paddle) {
    paddle.getPosition().y >= height - paddle.getSize().y - 10 ? paddle.setPosition(sf::Vector2f(paddle.getPosition().x,height - paddle.getSize().y)) : paddle.move(sf::Vector2f(0, 10));

}
4
  • 3
    Don't make your game "sleep" at all! Measure how much time has elapsed in your loop, and advance the game by exactly that amount. Commented Jan 15 at 19:40
  • I am sorry but if you don't mind me asking, how can I set a maximum value on the updates per second? When I didn't sleep, the program used 100% of the CPU even though I set the maximum frames per second to 60. Commented Jan 15 at 19:51
  • 1
    The sleeping is exactly what makes it choppy. Because during the sleep your thread has to freeze completely. Commented Jan 15 at 20:10
  • 1
    Please clarify your specific problem or provide additional details to highlight exactly what you need. As it's currently written, it's hard to tell exactly what you're asking. Commented Jan 15 at 23:25

1 Answer 1

0

instead of having window.clear(), window.draw() and window.display() and then sleeping. put these calls in an if() statement that checks if 1/60th of a second has passed since the last time the window gets re drawn.

you could also put some game calculation logic happen before the frame gets drawn rather than as much as your CPU can handle

something like:

total += deltaTime;

if(total>=(1/framerate))
{
    total=0;
    additionalGameCalculationLogic();
    window.clear();
    window.draw();
    window.display();
}
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.