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

Auteur Sujet: Demande d' "expertise" sur système de particules  (Lu 2037 fois)

0 Membres et 2 Invités sur ce sujet

Dpondi

  • Newbie
  • *
  • Messages: 2
    • Voir le profil
    • E-mail
Demande d' "expertise" sur système de particules
« le: Novembre 04, 2014, 10:49:54 pm »
Bonsoir,

Je me suis récemment mis à programmer en C++ en utilisant la librairie SFML (qui m'a l'air tout bonnement géniale) et étant un fasciné de générateurs de particules, j'ai essayé d'en créer un de manière très basique et très simple.

Ma demande est simple : J'aimerai savoir si je pourrai améliorer ma façon de coder, si je pouvais optimiser certaines choses dans ce code, et pourquoi pas apprendre de nouvelles choses qui réduiraient le nombre de lignes à écrire.

Voici mon code :
#include <SFML/Graphics.hpp>
#include <time.h>
#include <vector>
#include <iostream>

int main()
{
    srand(time(NULL));

    sf::RenderWindow app(sf::VideoMode(800, 600), "SFML window");
    app.setVerticalSyncEnabled(true);
    app.setMouseCursorVisible(false);

    struct Particule
    {
        float vx,vy,g;
        int vie ;
        sf::CircleShape shape;
        Particule(int x, int y) {
                                     shape.setFillColor(sf::Color::White);
                                     shape.setRadius(7.0);
                                     shape.setPosition(x,y);
                                     g = 0.1; vy = -1.0; vx = (float)rand() / RAND_MAX; vie = 127;
                                    }
        void update() { vy += g; --vie; shape.setFillColor(sf::Color(255,255,255,vie)); shape.move(vx,vy);  }
        bool isAlive() { return vie >= 0; }
    };

  typedef struct Particule Particule;

  std::vector<Particule> Tableau;

  sf::Vector2i MousePos;

    while (app.isOpen())
    {
        sf::Event event;
        while (app.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                app.close();
            if(event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape)
                app.close();
        }

        app.clear(sf::Color::Black);
       
        MousePos = sf::Mouse::getPosition(app);
        Particule p(MousePos.x,MousePos.y);
        Tableau.push_back(p);

        for(int i = Tableau.size()-1 ; i > 0; i--)
        {
            if(Tableau[i].isAlive()) {Tableau[i].update(); app.draw(Tableau[i].shape); }
            else if(Tableau[i].isAlive() == false) Tableau.erase(Tableau.begin()+i);
        }
        app.display();

    }

    return EXIT_SUCCESS;
}
 

Voilà c'est tout simple :)

Merci par avance à ceux qui pourront me conseiller, me donner des idées, et surtout m'aider à m'améliorer.

Cordialement.
« Modifié: Novembre 04, 2014, 10:54:09 pm par Laurent »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Demande d' "expertise" sur système de particules
« Réponse #1 le: Novembre 04, 2014, 11:04:35 pm »
Pour un système très simple (rien n'est paramétrable, et les updates ne sont pas basés sur le temps écoulé) c'est pas si mal. Je te laisse voir comment le faire évoluer, je te donne juste les choses que je trouve mauvaises dans ce code :

1. Ne mets pas tout dans la fonction main(), sépare bien les classes / fonctions.

2. Ne cherche pas à réduire le nombre de lignes de code, mais plutôt à l'augmenter : utilise des noms de variables plus explicites, ne mets pas plusieurs instructions par ligne, aère ton code ; le but c'est qu'il soit lisible, tu ne fais pas un concours de lignes de code.

3. "if (a) ... else if (a == false) ...", c'est juste "if (a) ... else ..." ;)

4. Probablement le plus important : ta gestion de la mémoire est très inefficace. Les particules nouvelles sont ajoutées en fin de tableau, ce qui fait que celles à supprimer sont toujours celles du début. Or un std::vector est très mauvais pour effacer en début de séquence (il doit redéplacer tout le reste pour boucher le trou). Trois solutions :
- utiliser un conteneur plus efficace pour les effacements en début de séquence, tel que std::deque ou std::list
- utiliser l'idiome erase-remove (cf. Google)
- recycler les particules mortes au lieu d'en supprimer / créer constamment
Laurent Gomila - SFML developer

Dpondi

  • Newbie
  • *
  • Messages: 2
    • Voir le profil
    • E-mail
Re : Demande d' "expertise" sur système de particules
« Réponse #2 le: Novembre 04, 2014, 11:10:01 pm »
Bonsoir,

Merci beaucoup pour votre réponse rapide, et milles mercis pour vos conseils !

J'essaierai de les suivre à la lettre et d'améliorer mon code autant que faire se peut.

Merci encore.

Cordialement.

NB: Autant pour moi, merci d'avoir modifié le nom de mon topic.

G.

  • Hero Member
  • *****
  • Messages: 1593
    • Voir le profil
Re : Demande d' "expertise" sur système de particules
« Réponse #3 le: Novembre 05, 2014, 08:26:39 am »
Pour le recyclage des particules mortes dont parle Laurent tu peux te renseigner sur le design pattern object pool.

Et sinon ton typedef est totalement inutile. :p
Les struct du C++ s'utilisent à 99% comme les class.

Glân de Brylan

  • Invité
Re : Demande d' "expertise" sur système de particules
« Réponse #4 le: Novembre 05, 2014, 11:06:09 am »
Ce qui est marrant c'est qu'il a fait un typedef comme s'il était en C mais il a quand même mis des fonctions dedans ^^
Bon, si je souviens bien, les différences entre structure et classe en C++ sont les suivantes :
La portée par défaut des membres et de l'héritage est public dans une structure, privée dans une classe.
On ne peut pas faire de structures templates.
Heu, je crois que c'est tout...perso quand j'utilise une structure je la fais "à la C", sinon autant utiliser une classe...

Laurent

  • Administrator
  • Hero Member
  • *****
  • Messages: 32498
    • Voir le profil
    • SFML's website
    • E-mail
Re : Demande d' "expertise" sur système de particules
« Réponse #5 le: Novembre 05, 2014, 03:45:00 pm »
Citer
La portée par défaut des membres et de l'héritage est public dans une structure, privée dans une classe.
C'est la seule et unique différence.

Mais on s'éloigne un peu du sujet là ;)
Laurent Gomila - SFML developer