Partage
  • Partager sur Facebook
  • Partager sur Twitter

Comment structurer un jeu en c++

    8 juillet 2013 à 22:29:23

    >C'est le modèle Entity Component System décrit dans les liens posté x fois par lmghs.

    Je repasse depuis peu et plutôt du côté théorique du C++ ou Qt (Ou GNU/Linux mais c'est hors-propos :p) donc je dois avouer n'être jamais tombé sur un de ses liens. :) Ca viendra par contre ^^ En tout cas je me renseignerai sur ce système. :)

    Je dois avouer pas avoir trop capté pour le système de traits (j'ai pas encore lu le tuto auquel cas il traiterais ça). Enfin, je relirais ce topic demain et ça ira ^^

    • Partager sur Facebook
    • Partager sur Twitter
    Minie a Free(dom), lightweight & simple web browser!
      8 juillet 2013 à 23:22:15

      Bonsoir à tous,

      Voilà une discussion qui tombe à pic pour moi! (je l'ai suivie au boulot ;))

      Justement hier j'ai bien entamé la partie envoie / réception des dégâts sur les autres joueurs, ok ça fonctionne bien, donc je me suis dit: tiens je vais m'amuser à faire quelques essai avec une classe "Classe" qui serait mère de, par exemple: "Mecano", "Scientifique" etc..., lorsque j'appuie sur la touche 1 pour lancer ma compétence 1, ça exécute bien la méthode skill1() (je simplifie hein) de la classe du personnage...mais au fur et à mesure, je pensai justement: oula, ça va commencer à être un beau bordel entre les classes, les types de vaisseau, les sortes de PNJ, pffffiou ça va hériter sévère!!:ninja:

      Et là, je vois justement que vous parlez de "Entity Component System", honnêtement, je ne connaissait pas ça tombe pile poil car c'est justement ce dont j'ai besoin (et je vais apprendre un nouveau truc..ça tombe bien aussi, c'est le but de mon projet!)

      Le truc pas glop, c'est que je vais sans doute devoir refaire une bonne partie de mon programme à mon avis (mais ça fait partit du jeu!)

      Merci pour vos conseils en tout cas

      -
      Edité par Asphodelus 8 juillet 2013 à 23:25:18

      • Partager sur Facebook
      • Partager sur Twitter
      Anonyme
        9 juillet 2013 à 0:23:02

        Je me permet d'intervenir puisque le sujet m'intéresse beaucoup. Dans l'exemple que tu donne int21, une classe d'entité serait quelque chose comme ça non ?

        class Sword
        {
            public:
                Sword();
                ~Sword();
            private:
                std::string m_name;
                long m_price;
                long m_damage:
                bool is_award;
        };
        

        -
        Edité par Anonyme 9 juillet 2013 à 0:24:03

        • Partager sur Facebook
        • Partager sur Twitter
          9 juillet 2013 à 0:26:11

          Asphodelus a écrit:

          Pour le choix pointeur / référence, j'avais regardé pas mal de truc là dessus et au final j'avais même vu que c'était une question de gout, vu que j'ai été habitué à travaillé avec...Mais ici encore tu as raison, vaut mieux prendre la solution la plus simple: les références

          Edité par Asphodelus il y a environ 13 heures

          Ça dépend toujours du design que tu veux avoir dans ton programme. Par exemple, un entityActor qui a comme référence un entity devra initialiser celle-ci dans le constructeur, après quoi il n'est plus possible de pointer vers une autre variable. Si le design de ton programme veut que l'entityActor peut uniquement pointer vers une seule valeur possible, alors il faut un mécanisme d'effacement d'entityActor pour pouvoir agir sur un autre entity.

          Avec un pointeur, tu peut pointer vers une autre valeur en tout temps, mais il est dangereux d'utiliser des pointeurs de base dans le cas d'un delete involontaire. Il est mieux d'utiliser des boost::shared_ptr<T> pour assurer l'intégrité de l'objet en tout temps. Mais les références restent plus simples si cela suffit à tes besoins.

          informaticienzero:

          La classe sword pourrait être une entité si elle a besoin d'être mise à jour via une fonction virtuelle update(const float timedelta), après elle pourrait aussi détenir l'information du sprite à dessiner sous forme d'entier.

          -
          Edité par lucas92 9 juillet 2013 à 0:30:14

          • Partager sur Facebook
          • Partager sur Twitter
            9 juillet 2013 à 0:26:31

            Oula non Informaticienzero, c'est un poil plus compliqué :p...

            Regarde les tuto / exemples de "Entity Component System", je suis en train d'y regarder, c'est pas simple, surtout que j'ai l'impression que personne ne fait exactement pareil en fait

            @lucas92: merci du conseil, je vais regarder à tout ça, de toute façon je vais devoir refaire 80% de mon code client et même punition pour serveur (de toute façon, ça devenait dégueulasse)

            -
            Edité par Asphodelus 9 juillet 2013 à 2:03:38

            • Partager sur Facebook
            • Partager sur Twitter
              9 juillet 2013 à 10:46:59

              Flaco a écrit:

              Ah je vois... les traits comme ici ?


              Non. Ce que j'appelle traits a très peu à voir avec ça. Sur le plan concept, on retrouve des idées communes. Sur le plan technique, il n'y a aucun rapport. Je ne sais plus si l’appellation "traits" (dans notre cas de jdr) vient de moi, ou si je l'avais déjà lue auparavant. Je soupçonne avoir juste repris un terme que j'avais croisé dans les théories du traitement du langage naturel, et qui retrouvait des échos (lointains) sur les classes de traits.

              Le terme idoine serait "Entity Component System". Après, vous pouvez lire les liens derrière mes liens où De Passage et moi-même donnons des morceaux de codes qui illustrent ces principes.

              Ce qui est sûr, c'est que mettre de l'héritage partout, c'est l'échec: ça ne scale pas un seul instant. C'est le genre de truc que je vois vite car je connais bien les limites et les avantages de l'OO (ici l'héritage), et plus d'un système de règles (D&D 2e & 3e, Basic/chaosium, oeil noir, malefice, Dk, vampire & cie, ...) en tant que vieux rôliste.

              -
              Edité par lmghs 9 juillet 2013 à 14:19:03

              • Partager sur Facebook
              • Partager sur Twitter
              C++: Blog|FAQ C++ dvpz|FAQ fclc++|FAQ Comeau|FAQ C++lite|FAQ BS| Bons livres sur le C++| PS: Je ne réponds pas aux questions techniques par MP.
                9 juillet 2013 à 11:59:16

                J'ai vu tes liens lmghs, j'ai regardé aussi sur google "Entity Component System" et je comprend mieux à quoi ça sert

                C'est carrément une autre façon de concevoir un programme, et ça à l'air super pratique!

                Par contre, c'est pas vraiment la solution la plus simple :waw: mais bon, si on chercher toujours à faire au plus simple, faut arrêter la programmation ^^

                Perso, ce n'est pas encore clair dans ma tête (le principe si, mais pas comment l'utiliser), mais ça va venir, j'ai juste regardé vite fait pour le moment. Et puis, y'a quelques exemple sur le net mais je n'ai pas envie de faire du copier coller, je pense qu'il faut d'abord bien cerner le principe, puis concevoir le truc à notre façon

                • Partager sur Facebook
                • Partager sur Twitter
                Anonyme
                  9 juillet 2013 à 12:23:00

                  J'étais en train de lire un article sur l'ECS appliqué à un Bomberman (ici), et je me demandais : on définit donc tout un tas de module, et c'est au main de faire le reste alors ? J'entends par là charger les sprites, etc.

                  • Partager sur Facebook
                  • Partager sur Twitter
                    9 juillet 2013 à 12:49:08

                    Asphodelus a écrit:

                    Par contre, c'est pas vraiment la solution la plus simple :waw: mais bon, si on chercher toujours à faire au plus simple, faut arrêter la programmation ^^

                    cf. ma signature ^^ .

                    -
                    Edité par Ksass`Peuk 9 juillet 2013 à 12:49:29

                    • Partager sur Facebook
                    • Partager sur Twitter

                    Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C

                      9 juillet 2013 à 21:54:25

                      @informaticienzero rien ne t'empêche transférer la reponsabilité du chargement à une classe ou un ensemble de classes par exemple

                      int main()
                      {
                         // retrieve game global setup
                         ConfigurationHandler config(getSetup());   
                         
                         // initialize modules
                         ModuleManager modules(config);
                      
                         // initialize game
                         GameManager game(modules,config);
                      
                         return game.play();
                      }



                      • Partager sur Facebook
                      • Partager sur Twitter
                      Mettre à jour le MinGW Gcc sur Code::Blocks. Du code qui n'existe pas ne contient pas de bug
                        10 juillet 2013 à 0:59:47

                        Merci les mecs; je jettrais un oeil là dessus. J'ai jamais réellement avancé dans le dev d'un jeu donc le dev de ceux-ci m'est bien obscur...

                        >rien ne t'empêche transférer la reponsabilité du chargement à une classe ou un ensemble de classes par exemple

                        Mais c'est pas ce qu'on ma dit de ne pas faire dans ton exemple ? :o (Sans attaque)

                        -
                        Edité par Flaco 10 juillet 2013 à 1:00:33

                        • Partager sur Facebook
                        • Partager sur Twitter
                        Minie a Free(dom), lightweight & simple web browser!
                          10 juillet 2013 à 1:02:39

                          Et c'est aussi le même principe que ma classe fourre tout en fin de compte, non? :lol:
                          • Partager sur Facebook
                          • Partager sur Twitter
                            10 juillet 2013 à 3:29:05

                            Bonsoir à tous,

                            Je travaille sur un projet de jeu, je vais donc partager mon experience là dédans. J'utilise principalement l'Entity Component System, qui est de mon point de vue la meilleur façon pour concevoir un jeu qu'un système basé sur l’héritage.

                            Voici ma vision des choses.

                            Pour ma part, les classes les plus importantes sont :

                            • World
                            • Entity
                            • System
                            • Component

                            Le World contient tous les entités et les systèmes.

                            Les Components contiennent des donnés et des méthodes très basiques.

                            Les Systems s’occupent de mettre à jour les Components.

                            Les Entités contiennent des components.

                            Je vais mettre quelques exemples de components, systeme et d'entity :

                            Une entités peut representer

                            • Un personnage
                            • Un monstre
                            • Un projectile
                            • Un sort
                            • Etc..

                            Plusieurs exemples de components:

                            • RenderComponent : Contient les informations utilisés de l'entité pour le rendu
                            • PhysicsComponent : Contient les donnés lié à la physique 
                            • CollisionComponent : Contient les informations de collision
                            • SoundComponent : Contient les sons
                            • PositionComponent : Contient les positions

                            Plusieurs exemple de Systèmes :

                            • RenderSystem : Fait un rendu de toutes les entités en utilisant leur RenderComponent
                            • PhysicsSystem : Gêre la physique de toutes les entités en utilisant les donnés  d'un PhysicsComponent
                            • CollisionSystem : Gère la colliision de toutes les entités en utilisant les donnés d'un CollisionComponent
                            • SoundSystem : S'occupe de jouer des sons en se servant de son SoundComponent. 

                            Tout ceci ne sont que des exemples, chacun aura sa manière de faire les choses mais le concept sera à peu prés le même.

                            Je suis désolé si je suis pas  assez claire, mais il me faudrait faire des pages pour expliquer tout en détail. Si vous avez des questions, n’hésitez pas.

                            PS: Désolé pour les éventuelles fautes, vu  l'heure où j'ai posté ce message.

                            -
                            Edité par Skamer 10 juillet 2013 à 3:34:13

                            • Partager sur Facebook
                            • Partager sur Twitter
                              10 juillet 2013 à 8:27:23

                              Flaco a écrit:

                              Merci les mecs; je jettrais un oeil là dessus. J'ai jamais réellement avancé dans le dev d'un jeu donc le dev de ceux-ci m'est bien obscur...

                              rien ne t'empêche transférer la reponsabilité du chargement à une classe ou un ensemble de classes par exemple

                              Mais c'est pas ce qu'on ma dit de ne pas faire dans ton exemple ? :o (Sans attaque)

                              Non ;) . Dans cet exemple, il y a un rôle définis pour chacun des objets. De plus ce sont (très probablement) des singletons qui ajoute encore de la précision au sujet des fonctionnalités de ces objets. La question est "que veut dire Base ?" Rien ^^ .

                              • Partager sur Facebook
                              • Partager sur Twitter

                              Posez vos questions ou discutez informatique, sur le Discord NaN | Tuto : Preuve de programmes C

                                10 juillet 2013 à 10:47:21

                                @Ksass : bof, y'a qu'à renommer "Base" en "Load" et pis c'est tout!! (je plaisante bien sur...j'ai compris ce que tu voulais dire :p)

                                @Skamer: merci beaucoup pour ton retour d'expérience!

                                Personnellement, je suis en train d'y regarder à fond, je lis des articles là dessus mais le problème c'est que personne ne fait pareil on dirait (mais bon, le principe de base reste souvent le même). Pour l'instant, j'avoue ne pas avoir saisi tout les mécanismes de la chose (mais ça viendra au fur et à mesure)

                                J'ai bien compris la classe Entity, elle est quasiment "vide" à la base (mise à part des trucs que l'on retrouvera toujours, par exemple: position, ID), ensuite on lui ajoute des composants (points de vie, altération, capacités etc...), ça ok sur le principe mais c'est surtout la partie "system" que je ne comprend pas trop (et c'est là qu’apparemment les avis divergent): dans ma boucle de rendu, faut il que j'itère les entity une par une, voir si elles ont besoin d'être mise à jour ou alors que j'itère les composants par "famille" (ex: un thread s'occupe de mettre à jour les composants lié au rendu, un autre ceux liés à l'IA, la physic etc etc...)...j'y perds un peu mon latin là :euh:

                                • Partager sur Facebook
                                • Partager sur Twitter
                                  10 juillet 2013 à 12:25:59

                                  @Asphodelus: Le seul truc que tu vas avoir sur toutes les entités, c'est l'identifiant unique. L'idée est qu'un systeme va savoir quels composants il utilise, pour savoir s'il doit traiter une entité, il va regarder si celle-ci a le(s) composant(s) dont il a besoin, s'elle les a, le système va la traiter, sinon il va l'ignorer. Si je prend un système d'affichage, il aura besoin d'un composant position pour afficher une entité. Si l'entité a un composant position le système d'affichage va l'afficher, sinon il l'ignore. Dans le cas d'une entité épée par exemple, elle se trouve dans l'inventaire du joueur, elle n'a donc pas besoin d'être affichée sur la map, si le joueur la jete, elle reçoit un composant de position, qui va permettre au système d'affichage de l'afficher sur la map. Si le joueur la remet dans son inventaire, on supprime son composant de postion, le système d'affichage n'a plus de position pour cette entité, il ne l'affichera donc plus. Autre exemple, pour gérer les points de vie, je vais avoir un Systeme de gestion des points de vie, qui ne traitera que les entités qui ont un composant santé et des composants modifcateurs de santé. Les entité qui n'ont pas de composant santé sont inertes, on ne traitera jamais de dommages avec eux. Les entités qui ont un composant santé sans composant(s) modificateur(s), n'ont pas connu d'évolution de leur santé, il est donc inutile de la recalculer. Dans un combat le joueur va prendre des dommages, on va mettre des modificateurs de santé dans sa liste de composant, pour que le système de gestion de la santé s'active pour le personnage. Si c'est un PNJ qui prend des dommages, on fera la même chose, de sorte que quelque soit l'entité qui prendra les dommages, le traitement sera toujours le même.
                                  • Partager sur Facebook
                                  • Partager sur Twitter
                                  Mettre à jour le MinGW Gcc sur Code::Blocks. Du code qui n'existe pas ne contient pas de bug
                                    10 juillet 2013 à 13:31:56

                                    int21H t'as parfaitement bien expliquer ceux que font les système.

                                    Il existe d'autre concept basé sur les components qui ne fait pas appel au système, les systèmes permettent de minimiser les updates inutiles.

                                    Sans les systèmes on aurait dû faire ça :

                                    void updateAllEntities()
                                    {
                                    for(auto it = mEntities.begin(); it != mEntities.end(); it++)
                                          {
                                             it->update();
                                             it->render();
                                           }
                                    }

                                    Il suffit que t'ait un seul entité à update sur 100, c'est déjà 99 appels inutiles.  Aprés comme dit plus haut, int21h t'as tout expliquer.

                                    -
                                    Edité par Skamer 10 juillet 2013 à 13:35:27

                                    • Partager sur Facebook
                                    • Partager sur Twitter
                                      10 juillet 2013 à 23:48:50

                                      Ok merci pour les précisions

                                      Pour le updateAll() je n'y avait même pas songé, je vous rassure! (ça ferait un peu bourrin quand même!)

                                      Dons si j'ai bien compris, ça ferais un truc dans ce genre:

                                      void rendering() // lancé à chaque frame
                                      {
                                      for(i = entities.begin(); i != entities.end(); i++)
                                      {
                                      System_rendering->updateEntity(i); // mais ne sera lancé QUE si l'entity en question contient des composants lié au rendu
                                      System_collisions->updateEntity(i); // même principe
                                      System_sound->updateEntity(i); // même principe
                                      
                                      /// ...
                                      }
                                      
                                      }

                                      Mais il faudra tester à chaque fois le contenu de l'entity pour savoir ce qu'il y a dedant (y'a peut être moyen d'optimiser ça mais bon...je vais déjà tacher de bien comprendre le mecanisme et après on verra :p)

                                      EDIT: en fait, au lieu d'éplucher le contenu de l'entity à chaque fois, on pourrait définir son/ses "rôles" (d'un point de vue "systeme je veux dire) à chaque ajout de composants, exemple: si on ajoute un "CollisionComponent", on lui ajoute un bool is_collidable = true;

                                      Une entity, pourrais donc avoir à la fois: is_collidable, have_physic etc...

                                      Comme ça, lors du rendu, on sait déjà quelles systemes doivent mettre à jour l'entity

                                      -
                                      Edité par Asphodelus 10 juillet 2013 à 23:58:05

                                      • Partager sur Facebook
                                      • Partager sur Twitter
                                        11 juillet 2013 à 9:39:45

                                        Hmm...

                                        Personnellement, je mettrai un système pour observer  l'ajout et le retrait d'un Component au sein du Entity pour les System.

                                        class Entity {
                                            private:
                                                int _id;
                                                std::map<ComponentType, Component> _components;
                                                std::vector<EntityListener> _listeners; // ici, ce sont en fait des systèmes
                                        
                                            public:
                                         
                                                void addComponent(const Component& component) {
                                                    _components.put(std::pair<ComponentType, Component>(component.getType(), component);
                                        
                                                   for (std::vector<EntityListener>::iterator it = _listeners.begin(); it != _listeners.end(); ++it)
                                                   {
                                                       it->onNewComponent(*this, component); // on informe le système
                                                   }
                                                }
                                                // ...
                                                // bool hasComponent(ComponentType)
                                                // Component* getComponent(ComponentType) ...
                                        };



                                        Du côté système, on écoute l'ajout/retrait des composants.

                                        class MySystem : public System // System implémente EntityListener
                                        {
                                            private:
                                        
                                                std::map<int, Entity*> _entities;
                                        
                                            public:
                                           
                                               void onNewComponent(Entity& entity, const Component& component) {
                                                   if (component.getType() == MON_TYPE_DE_COMPONENT)
                                                   {
                                                        _entities.put(std::pair<int, Entity*>(entity.getId(), &entity));
                                                   }
                                               }
                                        };

                                         Tout l'intérêt est que les System savent en permanence qu'elles sont les Entity qui les intéressent ou ne les intéressent plus. Plus trop besoin de se farcir la liste complète à chaque fois à partir de là.

                                        Tu rajoutes un observer du type onEntityDelete et puis voilà.

                                        -
                                        Edité par Xahell 11 juillet 2013 à 10:06:02

                                        • Partager sur Facebook
                                        • Partager sur Twitter
                                          11 juillet 2013 à 9:57:04

                                          Mouarf tu m'a devancé! Tu me crois si tu veux mais j'allais faire un edit pour proposer une truc dans ce style là :p

                                          En gros, je fais un SystemManager (qui contient tout les types de System) et à chaque ajout de composant, selon, leur type, j'ajoute un pointeur de l'Entity dans le System qui va bien

                                          Je me complique vraiment la vie des fois

                                          -
                                          Edité par Asphodelus 11 juillet 2013 à 10:03:29

                                          • Partager sur Facebook
                                          • Partager sur Twitter
                                            11 juillet 2013 à 14:54:42

                                            J'ai découvert le design Entity Component System gràce à vous ! =)

                                            En faisant quelques recherches, j'ai lu ce commentaire à la suite de cet article :

                                            Mick West a écrit:

                                            Really the power of a component system comes from how you integrate it with script and data, and that part can get a bit more complicated. Just implementing a component system in C++ alone is often not particularly useful.

                                             Donc comme le conseillent De passage ici et lmghs ici il faudrait utiliser des scripts.

                                            Vous en êtes vous déjà servi en complément du ECS ?

                                            Avez vous des conseils et des liens à proposer pour approfondir ce sujet ?

                                            Merci.

                                            • Partager sur Facebook
                                            • Partager sur Twitter
                                              12 juillet 2013 à 3:25:22

                                              SmallFitz, en ce qui concerne l'utilisation de script, je travaille toujours dessus. Je peux donc pas te dire si la méthode marche parfaitement, mais je vais te dire comment j'ai procédé.

                                              Imaginons un petit script en xml  du type :

                                              <Character name="Nomdupersonnage" id="1">
                                                 <PhysicsComponent>
                                                      <Mass>50</Mass>
                                                      <Acceleration>12</Mass>
                                                  </PhysicsComponent>
                                              <StatsComponent>
                                                   <Health>500</Health>
                                                   <Defense>32</Health>
                                                   <Speed>15</Speed>
                                              </StatsComponent>
                                              </Character>


                                              J'ai 2 classes qui s'appellent EntityLoader et EntityFactory.

                                              • EntityLoader s'occupe de lire un script  pour créer une entity (les ressources comme les textures et les sons sont chargés   à ce moment là), puis l'enregistre dans l'EntityFactory.
                                              • EntityFactory possède une entité de chaque type, il s’occupe de créer une copie à partir de l'original du type lorsque l'utilisateur lui demande.

                                              Au niveau code, ça rend quelque chose comme ça:

                                              Class EntityLoader

                                              void EntityLoader::loadCharacterFromFile(const std::string& filename)
                                              {
                                                 // Je passe le code où on parse le fichier xml.
                                                 // et on récupère les valeurs.
                                                 Entity* entity = new Entity;
                                                 
                                                 StatsComponent* stats = new StatsComponent
                                                 CharacterComponent* character = new CharacterComponent;
                                                 PhysicsComponent* physics = new PhysicsComponent;
                                              
                                                 stats->setHealth(500);
                                                 stats->setDefense(32);
                                                 stats->setSpeed(15);
                                              
                                                 character->setName("NomduPersonnage);
                                              
                                                 physics->setMass(50);
                                                 physics->setAcceleration(12);
                                              
                                                 // On ajoute les components à notre entity
                                                 entity->addComponent(stats);
                                                 entity->addComponent(character);
                                                 entity->addComponent(physics);
                                              
                                                // Un pointeur vers notre EntityFactory
                                                // On enregistre notre personnage dans notre Factory
                                                // EntityFactory::registerCharacter(const int ID, Entity* entity)
                                                mEntityFactory->registerCharacter(1, entity)
                                              >}

                                              Puis plus loin dans ton code, afin de créer ton personnage t'auras juste à faire ça:

                                              // On crée un personnage grace à EntityFactory
                                              Entity* character = mEntityFactory->createCharacter(1);
                                              
                                              

                                              Le "1" est l'ID du personnage que tu veux créer.

                                              Pour l'instant, j'ai ajouté ça très récemment à mon projet, il me reste pas mal de chose à améliorer et à corriger. Je suis parti sur ce concept et je trouve que ça marche plutôt pas mal.

                                              -
                                              Edité par Skamer 12 juillet 2013 à 3:31:44

                                              • Partager sur Facebook
                                              • Partager sur Twitter
                                                12 juillet 2013 à 7:46:19

                                                Je pense pas que ce soit ce à quoi il fasse référence en parlant de scripting. Là, tu parles plutôt de base de données XML.

                                                Il parle plutôt d'un moteur de script qui écoute les événements du jeu et qui y répond en exécutant du code python/Lua/autre. Ce code interprété a accès à des fonctions métiers du moteur, comme :

                                                • Détruire <unité> (une entité qui a une composante de vie, par exemple)
                                                • Ordonner à <unité> de <ordre> 

                                                Le moteur de scripting doit généralement avoir une bonne tolérance aux instructions impossibles (tentatives d'ordonner à un bâtiment de se déplacer, etc.).

                                                Tout l'intérêt de la chose est que n'importe qui peut rédiger ses propres scripts et les ajouter au moteur (modding, comme dans Skyrim, Baldur's Gate...) ou à une carte de jeu personnalisée (map making, comme pour Warcraft, Starcraft, Neverwinter Night...).

                                                Pour ce qui est de l'implémenter en ECS, je n'ai pas encore étudié la question.

                                                -
                                                Edité par Xahell 13 juillet 2013 à 0:45:26

                                                • Partager sur Facebook
                                                • Partager sur Twitter
                                                  12 juillet 2013 à 12:34:04

                                                  Personnellement je ne rendrais pas les entités observables par les systèmes, je passerai plutôt par un système de notification géré par un dispatcher. Les systèmes s'enregistrent auprès du dispatcher et lui donnent la liste des types de composants qui les intéressent. Lorsque la liste de composants d'une entité est modifiée, celle-ci envoie au dispatcher un message qui contient l'identifiant unique de l'entité, le type du composant concerné et la nature de la modification. Le dispatcher ventile ensuite le message sur les systèmes concernés. En faisant comme ça, je n'ai pas besoin de prévenir qui que ce soit lors de la création d'une entité, je lui passe juste le dispatcher à qui elle devra notifier les changements dans sa liste de composants.
                                                  • Partager sur Facebook
                                                  • Partager sur Twitter
                                                  Mettre à jour le MinGW Gcc sur Code::Blocks. Du code qui n'existe pas ne contient pas de bug
                                                    12 juillet 2013 à 13:42:43

                                                    @Xahell : En effet, je me suis un peu égaré. Dans ce cas là, je n'ai pas encore pris la peine d'y réfléchir.

                                                    @int21h : Je suis d'accord avec toi. C'est ce que je fais avec mes système, j'utilise le concept des signaux et des slots à l'aide de  boost::signal .

                                                    Ce qui me permet par exemple de faire des multitudes de notification comme : EntityDeadSignal, EntityPositionChangedSignal,  EntityMassChangedSignal, EntityTakenDamageSignal, etc... où chaque système décide de s'inscrire aux événements qui leur intéresse.

                                                    -
                                                    Edité par Skamer 12 juillet 2013 à 13:44:56

                                                    • Partager sur Facebook
                                                    • Partager sur Twitter
                                                      13 juillet 2013 à 0:35:35

                                                      Oui, mais votre truc c'est méga complexe. :o


                                                      Bon je le lirais demain soir et j'essayerais de le faire parce que c'est vrai que faire tout en héritage c'est moche.

                                                      Mais je pense que pour simplifier tout ça, je vais faire comme RPG Maker.

                                                      Des comportements généralistes du type Ennemis et d'autre un peu spécialisé. Et des éléments du type sorts. Ou objet d'inventaire.

                                                      Et des evennement qui s'exécute en permanence du script (avec un paramètre pour quand l'exécuté) et ont accès à tout le jeu en pointeur (pour les conditions).

                                                      Et dedans tu peut lister des comportement qui s'exécute en permanence eux aussi.

                                                      Du coup tu fais tes PNJ facilement et tes monstres en Orienté Object grâce au pattern state contenu dans les Entités.

                                                      La sauvegarde c'est juste un paquet de valeur pour savoir quand faire les PNJ et l'inventaire.

                                                      Je trouve ça vachement "facile" comme construction.

                                                      -
                                                      Edité par Yame 13 juillet 2013 à 0:36:17

                                                      • Partager sur Facebook
                                                      • Partager sur Twitter
                                                        13 juillet 2013 à 7:54:28

                                                        @Yame: Ce qui te parait complexe, c'est le changement de paradigme qu'implique l'ECS. L'ECS lui même n'est pas vraiment complexe, ce qui peut l'être ce sont les systèmes, si tu fais de la 3D avec gestion de la physique fine, des IA un peu plus malines qu'une huitre sous anti-dépresseurs... Cette complexité des système n'est pas inhérente à l'ECS, elle vient de la complexité fonctionnelle elle-même (3D, physique, IA digne de ce nom...). Si tu veux t'amuser un peu avec un ECS puissant, tu peux aller voir du coté de Unity3D.
                                                        • Partager sur Facebook
                                                        • Partager sur Twitter
                                                        Mettre à jour le MinGW Gcc sur Code::Blocks. Du code qui n'existe pas ne contient pas de bug
                                                          14 juillet 2013 à 3:07:22

                                                          L'ECS peut être simple c'est sûr, une fois qu'on a compris le principe, en 2h on peut faire un petit programme console, juste pour test l'ajout, getter, retrait de composants mais je pense il ne faut pas s'arrêter là, il faut tout d'abord optimiser tout ça avant de s'occuper des systems etc par exemple, on voit souvent que les composants sont indexés dans une map<string,composant>, ok, c'est assez pratique mais l'accès à un élément de map via un string est pluslong par rapport à un int (normal)

                                                          Perso je suis en train de regarder à ça car il y a surement moyen de mêler fonctionnalité et performances

                                                          Pour ce qui est des systems je n'y ai pas encore regardé du coup, mais là, ça va être la grosse partie (et là, ça va encore bencher dûr! :p)

                                                          -
                                                          Edité par Asphodelus 14 juillet 2013 à 3:13:00

                                                          • Partager sur Facebook
                                                          • Partager sur Twitter
                                                            14 juillet 2013 à 8:19:05

                                                            @Asphodelus: Premature optimization is the root of evil.
                                                            • Partager sur Facebook
                                                            • Partager sur Twitter
                                                            Mettre à jour le MinGW Gcc sur Code::Blocks. Du code qui n'existe pas ne contient pas de bug
                                                              14 juillet 2013 à 9:38:39

                                                              Oui je sais, je sais...une personne a dit ça donc il faut l'appliquer a la lettre :lol: mais bon...perso, quand je sais que ce que je fait n'est pas top niveau performance et qu'en +, il y a un risque de me retaper également tout ce qui suit derrière à cause de ça, ben je préfère essayer d'optimiser tout de suite (et même avant tiens...la preuve je n'ai pas encore tapé une ligne de code d'ECS dans mon jeu, je le fais d'abord sur un programme test)

                                                              Enfin, ne me tapez pas, c'était mon avis perso, je sais que pour vous j'ai entièrement tord mais c'est tant pis:-°

                                                              • Partager sur Facebook
                                                              • Partager sur Twitter

                                                              Comment structurer un jeu en c++

                                                              × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                                                              × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                                                              • Editeur
                                                              • Markdown