Bienvenue, Invité. Merci de vous connecter ou de vous inscrire.
Avez-vous perdu votre e-mail d'activation ?

Auteur Sujet: problème d'optimisation, de fonction clock et de coordonnées.  (Lu 5395 fois)

0 Membres et 1 Invité sur ce sujet

cybolavie

  • Newbie
  • *
  • Messages: 9
    • Voir le profil
problème d'optimisation, de fonction clock et de coordonnées.
« le: Décembre 14, 2012, 07:54:28 pm »
Bonsoir,

je me permet de passer sur ce forum, vis à vis d'un code pour un jeux en 2D, j'obtiens des coordonnées délirantes, j'ai des pertes, la fonction clock.restart() fait baisser considérablement les performances, bref le code me semble pourtant correct.

J'ai du louper un épisode, j'ai installé la SFML 2.0, d'ou vient ces bugs??

#include <SFML/Graphics.hpp>

#include <iostream>

 

#define WND_WIDTH 1024

#define WND_HEIGHT 768

#define GRID_TILES 12

 

const sf::Texture BuildBackgroundGrid(const float size, const sf::Color& color1, const sf::Color& color2);

 

 

int main(int argc, char** argv)

 

{              

               

                sf::Clock clock;

 

                sf::RenderWindow wnd(sf::VideoMode(WND_WIDTH, WND_HEIGHT), "Chicken Run!");

               

        // Initialise des variables qui seront utilisées dans la boucle

 

        sf::Vector2u wndSize(0, 0); // Au départ on met 0,0 afin de provoquer la création de la texture

                sf::Texture texBackgroundGrid;

                sf::CircleShape circle;

                sf::Rect<int> scoreArea;

                sf::Rect<int> gameArea;

                sf::Rect<int> gridArea;

                sf::Sprite grid;

               

                float gridSide;

                float mx = 0;

                float my = 0;

                float eq = 0;

               

                int pixel = 90;

 

                while(wnd.isOpen())

 

        {              

                               

                                sf::Time time = clock.getElapsedTime();

 

                                sf::Event evt;

 

                while(wnd.pollEvent(evt))

 

                {

 

                        if(evt.type == sf::Event::Closed)

 

                                wnd.close();

 

                }

 

 

                                wnd.clear(); // Efface la fenêtre

 

 

                                // Si les dimensions de la fenêtre ont changés, alors on recalcule tout

 

                sf::Vector2u wndCurrentSize = wnd.getSize();

 

                if(wndCurrentSize != wndSize)

 

                {

 

                        wndSize = wndCurrentSize;

 

                        scoreArea = sf::Rect<int>(0, 0, wndSize.x * 0.3, wndSize.y); // Rectangle du panneau des scores

 

                        gameArea = sf::Rect<int>(scoreArea.width, 0, wndSize.x - scoreArea.width, wndSize.y); // Rectangle de la fenêtre moins le panneau des scores

 

                        gridSide = std::min(gameArea.width, gameArea.height) * 0.8; // Côté de la grille = 80% du minimum entre la hauteur et la largeur dispo.

 

                        gridArea = sf::Rect<int>(gameArea.left + ((gameArea.width - gridSide) / 2), gameArea.top + ((gameArea.height - gridSide) / 2), gridSide, gridSide);

 

                        texBackgroundGrid = BuildBackgroundGrid(gridSide, sf::Color::Blue, sf::Color::White);

 

                        grid = sf::Sprite(texBackgroundGrid);

 

                        grid.setPosition(gridArea.left, gridArea.top);

 

                                }

 

                                float tile = gridSide / GRID_TILES;

                               

                                // Affiche la grille a la bonne position

 

                                wnd.draw(grid);

 

                                // Dessine le cercle

                               

                                sf::CircleShape circle;

                                circle.setRadius(tile/2);

                                circle.setFillColor(sf::Color::Red);

                               

                                // déplacement du pion

                               

                                //////////////////////////////////

                                //////////////////////////////////

 

                                // il se déplace une seule fois, avec un décallage depuis la coordonnée d'origine. plus pixel est grand et plus cet écart est conséquent

 

                                /*my += (clock.getElapsedTime().asMicroseconds() * pixel) / 1000000;

                                clock.restart();*/


 

                               

 

                                ////////////////////////////////////

 

                                // Dans ce deuxième cas, il se déplace constamment, en attendant de faire le clock.restart()

 

                                my = (clock.getElapsedTime().asMilliseconds() * pixel) / 1000;

                                //clock.restart();*/

 

                                if ( my > (gridArea.height - tile) ) { my = 0; clock.restart(); }

 

                                circle.setPosition(gridArea.left + mx, gridArea.top + my);

                               

                                wnd.draw(circle); // Affiche le déplacement du Pion

 

                                wnd.display(); // Dessine la fenêtre

 

 

                               

        }

 

        return 0;

               

}

 

 

       

const sf::Texture BuildBackgroundGrid(const float size, const sf::Color& color1, const sf::Color& color2)

 

{              

           

                // Création d'une texture aux dimensions souhaités

 

        sf::Texture text;

                sf::RenderTexture t;

       

                t.create(size, size);

        t.clear(color1);

        t.resetGLStates();

 

        // Création d'un rectangle pour dessiner les tuiles

 

        float tileSide = size / GRID_TILES;

        sf::RectangleShape tile(sf::Vector2f(tileSide, tileSide));

       

                tile.setFillColor(color2);

        tile.setOutlineColor(sf::Color::Black);

        tile.setOutlineThickness(1);

 

                               

                int count = 0;

 

        for(int i = 0; i < GRID_TILES; i++)

 

        {

 

                for(int j = 0; j < GRID_TILES; j++)

 

                {

 

                        if(count & 1)

 

                        {

 

                                tile.setPosition(i * tileSide, j * tileSide);

                                                               

                                                                t.draw(tile);

                                                               

                        }

 

                                               

                                                count++;

 

                }

 

                count++;

 

        }

 

               

                t.display();

 

        text = sf::Texture(t.getTexture());

 

        return text;

 

}

Merci bien.  :)
« Modifié: Décembre 14, 2012, 09:39:49 pm par cybolavie »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : problème d'optimisation, de fonction clock et de coordonnées.
« Réponse #1 le: Décembre 14, 2012, 09:43:34 pm »
C'est possible d'avoir un formattage un peu moins farfelu ? :P
Laurent Gomila - SFML developer

cybolavie

  • Newbie
  • *
  • Messages: 9
    • Voir le profil

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : problème d'optimisation, de fonction clock et de coordonnées.
« Réponse #3 le: Décembre 14, 2012, 10:56:18 pm »
Euh... c'est la même chose.
Laurent Gomila - SFML developer

G.

  • Hero Member
  • *****
  • Messages: 1593
    • Voir le profil
Re : problème d'optimisation, de fonction clock et de coordonnées.
« Réponse #4 le: Décembre 14, 2012, 11:09:40 pm »
Tu sautes trop de lignes :D on se retrouve avec 3 lignes par écran parfois là. :/ Du coup trop relou à lire.
En plus l'indentation est chaotique.
« Modifié: Décembre 14, 2012, 11:14:59 pm par G. »

ctxnop

  • Newbie
  • *
  • Messages: 28
    • Voir le profil
Re : problème d'optimisation, de fonction clock et de coordonnées.
« Réponse #5 le: Décembre 14, 2012, 11:26:30 pm »
Je n'arrêtes pas de tenter de lui expliquer comment formatter son source pour qu'il soit lisible, mais bon...
Voila la version reformattée : http://pastebin.com/7rwf3LiN

EDIT:
J'ai tenté tout à l'heure de voir ce qui n'allait pas. Mais j'étais au boulot et je ne suis pas familier de la SFML, du coup je n'ai rien vu qui m'ai sauté aux yeux.
Cependant les problèmes que j'ai vu sont les suivants :
- Lors de l'ouverture de la fenêtre, un damier est dessiné, si la fenêtre change de dimensions, les dimensions du damier son recalculées. Ces dimensions sont bonne à l'ouverture de la fenêtre, mais si on maximise celle-ci le résultat est ... étrange...
- Faire un clock.restart à chaque itération de la boucle principale tue litérallement les perfs, on se retrouve avec 10-15 FPS.
Si, au lieu de faire un restart, on calcul un diff entre deux itérations (donc on laisse la clock courrir), les perfs reviennent à la normale.
- La fenêtre ne semble pas être rafraichit à chaque itération de la boucle. Genre le pion rouge ne semble pas bouger, déplacez la fenêtre et paf il change de position. Pourtant si je met un breakpoint dans son while, je m'y arrête bien. Chose étrange d'ailleurs, si je réduit et réouvre la fenêtre, elle se met a tourner "normalement".

Tout ces tests ont étés faits avec visual studio 2010, une SFML 2.0 que j'ai compilée via les sources, j'ai linké en static (avec SFML_STATIC de définit pour le preprocesseur). Le tout tournant sur un Vista sur un portable tout moisie (mais pas au point d'avoir 10 fps sur le dessin d'un damier...)
« Modifié: Décembre 14, 2012, 11:35:06 pm par ctxnop »

cybolavie

  • Newbie
  • *
  • Messages: 9
    • Voir le profil
Re : problème d'optimisation, de fonction clock et de coordonnées.
« Réponse #6 le: Décembre 14, 2012, 11:44:10 pm »
J'avais fais un petit effort pour vous, j'étais descendu à 130 lignes, tout en supprimant le côté brouillon.  8)

Bon ok, j'exagère beaucoup sur mon "aération" de code.  :D

G.

  • Hero Member
  • *****
  • Messages: 1593
    • Voir le profil
Re : problème d'optimisation, de fonction clock et de coordonnées.
« Réponse #7 le: Décembre 15, 2012, 12:04:55 am »
Au lieu de mater à la main si la taille de la fenêtre a changé, vous pouvez surveiller l'évènement Resized. Et encore, le contenu d'une fenêtre se redimensionne tout seul quand la fenêtre change de taille non ? (Si c'est pas le cas, ça le fait en utilisant une sf::View en tout cas)

Pourquoi récupérer le temps en millisecondes si c'est pour le diviser par 1000 de toutes façons ? Autant la récupérer tout de suite en secondes.

Pourquoi vous faites un  t.resetGLStates(); ? Je crois que c'est pas utile si vous faites pas directement de l'openGL. Qui sait ce que ça fait. :D

A part ça je vois rien de spécial, mais je suis pas assez skillé. :(

ctxnop

  • Newbie
  • *
  • Messages: 28
    • Voir le profil
Re : problème d'optimisation, de fonction clock et de coordonnées.
« Réponse #8 le: Décembre 15, 2012, 12:31:51 am »
Hé bien comme je disais, je ne suis pas familier de la SFML, je n'ai pas fais le tour des docs, tutos, etc...

Du coup, si le redimensionnement de la fenêtre met à tout à l'échelle tout seul, ca expliquerai le résultat étrange obtenu...
Personnellement je trouve ça étrange que ce soit fait en automatique, c'est perturbant, j'ai l'impression de ne pas avoir la main sur l'affichage du coup.

Pour le coups de la division par 1000, je dois avouer que je n'ai pas fait attention au type de retour de asSeconds(), étant donné que asMilliseconds() retourne un int32, j'ai bêtement pensé que ce serait pareil pour asSeconds, et du coup la valeur retournée serait arrondie et d'une précision insuffisante pour effectuer un calcul de position.

Le t.resetGLStates(), c'est de ma faute ^^' Je l'avais mis pour faire un test d'un truc, et quand j'ai viré mon test j'ai zapé cette ligne ...
Ceci dit lors de mes tests cette après midi, je l'avais bien viré, sans résultat apparent (sauf peut être un rafraichissement plus fréquent de la fenêtre, mais toujours aussi chaotique)

G.

  • Hero Member
  • *****
  • Messages: 1593
    • Voir le profil
Re : problème d'optimisation, de fonction clock et de coordonnées.
« Réponse #9 le: Décembre 15, 2012, 12:56:23 am »
Au fait, debug ou release ?

ctxnop

  • Newbie
  • *
  • Messages: 28
    • Voir le profil
Re : problème d'optimisation, de fonction clock et de coordonnées.
« Réponse #10 le: Décembre 15, 2012, 12:59:55 am »
Testé les deux, même perfs (ou plutôt absence de perfs) dans les deux, a peu de chose près (un léger avantage pour le release évidemment, mais rien de violent)

cybolavie

  • Newbie
  • *
  • Messages: 9
    • Voir le profil
Re : problème d'optimisation, de fonction clock et de coordonnées.
« Réponse #11 le: Décembre 15, 2012, 02:04:00 pm »
De mon côté j'utilise Visual C++ 2010 express et SFML 2.0, en debug.

Ok pour le redimenssionnement automatique, C'est bon à savoir. Cela peut expliquer les bizarreries que j'obtenais à l'écran.

Auparavant, j'effectuais mes déplacements en fonction du temps et comme je voulais qu'il se déplace toutes les 50 ms... (le 1er test était 1s - 1000ms) j'ai donc travaillé avec des chiffres en millisecondes. Depuis, on travaille avec les pixels, la règle de 3 aurait pu être revue en conséquence.

Le gros problème se situe dans le déplacement. au lancement du jeux, tout dépend de la valeur de pixel:

si sa valeur est assez faible (10 pxl) il va démarrer lentement et avec un décallage faible par rapport aux coordonnées d'origine. Dans le cas de l'exemple (90 pxl), il va commencer à afficher le cercle en plein milieu du damier, alors qu'il devrait commencer en toute logique en haut. Il se crée des pertes, il ne dessine pas tout. Une fois le cercle entré en collision avec le bas du damier, je le remet en haut et il effectue bien son déplacement comme il faut, de haut en bas, ainsi de suite.

Par contre, si on effectue la petite équation sur my et que le clock reset est exécuté juste après, il n'affiche plus les déplacements. La solution bricolage et temporaire était donc de laisser tourner le chrono et d'effectuer le clock.restart() au moment de la collision. Et ne parlons pas de cette fluidité complètement inexistante.

Bref un peu galère.  :-[




cybolavie

  • Newbie
  • *
  • Messages: 9
    • Voir le profil
Re : problème d'optimisation, de fonction clock et de coordonnées.
« Réponse #12 le: Décembre 17, 2012, 04:24:54 pm »
Laurent, tu aurais une piste eventuellement? Que cela nous permette d'effectuer des changements rapidement.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : problème d'optimisation, de fonction clock et de coordonnées.
« Réponse #13 le: Décembre 17, 2012, 04:32:07 pm »
Désolé, lorsque les messages commencent à faire plus de 10 lignes j'ai tendance à décrocher.

Tu ne voudrais pas résumer ? ;D
Laurent Gomila - SFML developer

cybolavie

  • Newbie
  • *
  • Messages: 9
    • Voir le profil
Re : problème d'optimisation, de fonction clock et de coordonnées.
« Réponse #14 le: Décembre 17, 2012, 04:50:21 pm »
Pour plus de détail, regarde l'édit de ctxnop au dessus.

Le redimensionnement a été résolu. Mais notre problème se situe sur la fonction clock et les coordonnées délirantes! Comment expliques-tu ce phénomène, as tu testé l'implémentation de ton côté?

 

anything