Comportement étrange de ma clock/fenêtre ?

L'auteur de ce sujet a trouvé une solution à son problème.
Auteur du sujet

Bonjour, j'ai voulu voir comment fonctionne un système de tick pour mettre à jour la logique d'un jeu indépendamment de la boucle de rendu (dans un seul thread), j'ai donc créer un petit projet de test, regardé ce qui se faisait sur internet et j'ai tout mis dans le main, j'ai une fonction qui renvoie le temps passé depuis son dernier appel, et je me base sur ça pour effectuer le bon nombre d'update.

Le soucis, c'est que très peu de tick se "déroule" lors de l’exécution, peut-être un tout les 2-3 secondes ça semble variable, j'ai d'abord penser que ma fonction "chrono" (qui utilise sf::Clock) ne fonctionnait pas comme il faut ou que je m'étais trompé dans la condition qui vérifie si assez de temps s'est écoulé pour mettre à jour le jeu. Je n'ai rien trouvé à ce niveau par contre quand je bouge/interagi avec la fenêtre ou la met en grande dimension (je la redimensionne en haut à droite quoi) les ticks s'écoulent plus "naturellement".

Du coup je sais pas trop de quoi ça vient, à première vu ça devrait plutôt impacter le jeu.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <SFML/Graphics.hpp>
#include <iostream>

int getTimePassed();

int main()
{
    sf::RenderWindow window(sf::VideoMode(200, 200), "SFML works!");

    const unsigned tickPerSecond = 20;
    const unsigned timePerStep = 1000 / tickPerSecond;

    unsigned int deltaTime  = 0;
    unsigned int timePassed = 0;
    unsigned int tick = 0;

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

        while(timePassed >= timePerStep){
            //update
            timePassed -= timePerStep;
            std::cout << "Game logic updated#Tick:" << tick << std::endl;
            tick++;
        }

        deltaTime   = getTimePassed();
        timePassed += deltaTime;
        window.clear();
        window.display();
    }

    return 0;
}

int getTimePassed(){
    static sf::Clock clock;
    sf::Time timePassed = clock.getElapsedTime();
    clock.restart();
    return timePassed.asMilliseconds();
}
+0 -0

Cette réponse a aidé l'auteur du sujet

Salut,

Pourquoi ne pas mettre la sf::Clock dans le main et incrémenter timePassed avant le while(timePassed >= timePerStep) ?

Par ailleurs,

1
2
3
sf::Time timePassed = clock.getElapsedTime();
clock.restart();
return timePassed.asMilliseconds();

peut être remplacé par :

1
return clock.restart().asMilliseconds() //restart retourne le temps actuel avant de relancer la clock. Et en plus, tu ne perds pas le temps qu'il y a entre le getElapsedTime() et restart()

Dans le jeu que je code actuellement, la boucle principale avec un timestep fixe comme toi ressemble à ça :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
void WindowManager::run()
{
    sf::Clock dtClock;
    sf::Time elapsedTime;

    while (m_window.isOpen())
    {
        m_engine.nextFrameInit();
        if(!m_engine.getRunningState())
        {
            m_window.close();
        }

        sf::Event event;
        while (m_window.pollEvent(event))
        {
            //GESTION DES EVENEMENTS
        }

        elapsedTime += dtClock.restart(); //Incrémentation du la nouvelle durée avec CE QU'IL RESTE DE LA FRAME PRECEDENTE !!!
        //Fix the timestep so that the game logic is refreshed every 1/60s (60 fps)
        while(elapsedTime >= sf::seconds(1/60.f))
        {
            //JE FAIS UNE UPDATE (avec dt = 1/60s)

            elapsedTime -= sf::seconds(1/60.f);
        }

        //Render the state
        m_window.clear();
        //ICI, JE FAIS LE RENDU

        m_window.display();
    }
}

Édité par victorlevasseur

+2 -0
Auteur du sujet

Merci beaucoup, le problème semble régler le soucis, ça devait sûrement venir de la fonction ou d'une erreur que j'ai inconsciemment corriger en reprenant ton code.

Voici le code, si j'ai oublié quelque chose prévenez moi. :)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <SFML/Graphics.hpp>
#include <iostream>

int getTimePassed();

int main()
{
    sf::RenderWindow window(sf::VideoMode(200, 200), "SFML works!");

    const unsigned tickPerSecond = 20;
    const sf::Time timePerStep = sf::milliseconds(1000 / tickPerSecond);

    sf::Time timePassed;
    sf::Clock clock;

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

        timePassed += clock.restart();

        while(timePassed >= timePerStep){
            //update
            timePassed -= timePerStep;
        }

        window.clear();
        window.display();
    }

    return 0;
}

Édité par Chokocraft

+0 -0
Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte