IdentifiantMot de passe
Loading...
Mot de passe oubli� ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les r�ponses en temps r�el, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

conception et programmation ECS


Sujet :

C++

  1. #21
    Membre �clair�
    Homme Profil pro
    �tudiant
    Inscrit en
    Octobre 2014
    Messages
    521
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 37
    Localisation : France, H�rault (Languedoc Roussillon)

    Informations professionnelles :
    Activit� : �tudiant

    Informations forums :
    Inscription : Octobre 2014
    Messages : 521
    Par d�faut
    Ok, merci, je crois que je vois un peu mieu l'id�e.

    Si on reprend l'exemple d'un syst�me pour g�rer les mouvements : il utilise les composants "Position" et "Velocity". "Position" est utilis� par 2 syst�mes ("SystemGraphic" et "SystemMove"), �a doit donc pas �tre contenu par un syst�me.
    mais l� je ne te suis pas...utilis� par 2 syst�mes...mais...pas �tre contenu par un syst�me ?

    Si un composant est utilis� par un syst�me, n'est-il pas aussi contenu par celui ci, associ� � l'Entity ( le num�ro ) ?

  2. #22
    Membre �m�rite

    Profil pro
    Inscrit en
    D�cembre 2013
    Messages
    403
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : D�cembre 2013
    Messages : 403
    Par d�faut
    Citation Envoy� par Bousk Voir le message
    Euh Koala, je confonds p-e, ou alors c'est toi, mais ce dont tu parles c'est juste �tre "Data-driven". Non on ne va pas recompiler pour cr�er une �p�e de feu apr�s avoir cr�� l'�p�e de glace. On a un objet �p�e, une datasheet correspondante et des attributs de part et d'autre.
    L'ECS est effectivement une approche orient�e data driven. Mais je crois que vous �tes d'accord sur ce qu'est l'ECS.

    Une remarque quand m�me sur Unity, l'approche qui est utilis�e est inspir�e de l'ECS, mais cela reste une interface publique que Unity fournit aux utilisateurs. En particulier, il me semble que c'est plus un EC+ (n�ologisme de ma part, ne cherchez pas sur internet ), c'est � dire que l'on n'a pas vraiment acc�s aux syst�mes et que l'on va param�trer des comportements attach�s aux composants via des scripts. (ce qui n'est pas incompatible avec un ECS, vu qu'un script, c'est aussi une data). De plus, je crois que Unity affiche les composants comme des �l�ments des entit�s, sous forme d'arborescence. C'est probablement pas impl�ment� comme �a en interne (un arbre d'objet polymorphique est tr�s joli pour qu'un utilisateur voit les d�pendances, mais c'est pas optimal lorsque le jeu tourne - et c'est finalement ce qui compte).

    (mais bien sur, cela d�pend de comment on con�oit l'ECS et il n'y a pas une fa�on de faire, chaque moteur et jeu qui utilisent un ECS ont probablement une impl�mentation propre)

    Citation Envoy� par mazertys17 Voir le message
    Toujours en partant sur ce concept Entity Composant System, svp dites moi si j'ai bien suivit :

    On a une Entity, dans mon cas, plus haut, le Data ( qui devrait donc s'appeler Entity ), qui repr�sente un objet du jeu ( une biche, un arbre, etc...).

    On a des Components, qui sont des modules utilis�s/ouPas pour une Entity ( ex un Graphics, qui l'affiche, un Physics, qui le positionne ).

    On a des System, qui sont des sortes de containers intelligents de components, qui les font tourner.
    Dans l'impl�mentation que je pr�f�re, on a :
    - entit� = un id unique (comme l'a dit koala et Iradrille)
    - composant = donn�es
    - syst�me = algos

    On ne pas faire plus simple et modulable Chaque syst�me manipule une liste de composants de m�me type (de pr�f�rence). Il faut pouvoir ajouter et supprimer des entit�s facilement, c'est plus facile si on manipule des tableaux contenant des type identique (donc si un syst�me utilise 2 types de composant, c'est plus efficace d'avoir 2 vector plut�t qu'un vector d'objet polymorphique - et plus cache friendly).

    A chaque update, les syst�mes parcourent les composants et les mettent � jour (il n'est pas oblig� d'avoir tous les syst�mes qui mettent � jour en m�me temps, mais si ce n'est pas le cas, il faut faire attention aux conflits).

    La difficult� est les interactions entre les composants, c'est probablement le plus couteux. Dans le meilleur des cas, quand on met � jour un composant, on n'a besoin d'aucune info externe, c'est rapide. Un peu plus lent, c'est un composant qui a besoin d'un info provenant d'un composant du m�me syst�me (ie pas de risque de conflit). On peut optimiser les acc�s (par exemple avec un space partitionning si on veut les composants "position" � proximit� d'un composant "position" donn�). Le cas le pire, c'est un composant qui n�cessite des infos d'autres composants. Donc besoin de faire des recherches inter-syst�mes (par exemple, � partir d'un composant "position" du joueur, on recherche les composants "position" qui sont plus proches, puis on doit retrouver les entit�s correspondantes, puis trouver les composants "ia" correspondants � ces entit�s - si elles ont en un - et passer en mode "j'attaque le joueur").

    Citation Envoy� par mazertys17 Voir le message
    ...au shared_ptr...
    L�, je crois que la question va vite �tre r�gl�e et qu'il n'y aura pas trop d'avis divergeant : un pointeur, c'est un cache miss. Quelque soit le type de pointeur (et c'est encore plus vrai avec shared_ptr, puisqu'il peut avoir un control bloc dans un troisi�me espace m�moire).
    Si tu veux des performances, pas de tableau de pointeurs.
    (d'o� ma remarque pr�c�dente sur le fait de ne pas avoir de tableau d'objets polymorphiques. C'est pas une bonne id�e du tout)

    (Remarque : modulo les performances. Si tu as un jeu avec 10 entit�s en m�me temps - rien du tout donc - la perte de performances du fait des pointeurs sera n�gligeable. Dans ce cas, une approche old-school sans ECS ne sera pas critique. Tant que ton jeu n'�volue pas trop).

    Citation Envoy� par mazertys17 Voir le message
    Chose que je voulais �viter puisqu'on arr�te pas de dire, probablement � raison que c'est un signe de mauvaise conception.
    D�j� dit et r�p�t�, la mauvaise conception, c'est les propri�taires multiples. Pas l'utilisation de shared_ptr en soi. Mais on va pas relancer le d�bat

    Citation Envoy� par mazertys17 Voir le message
    si d�j� je suis dans le juste sur le concept Entity/Component/System
    Pas de d�finition absolue de comment doit �tre impl�ment� un ECS, donc cela d�pend. Mais dans ma vision de la chose, c'est pas du tout pareil que toi. (je pense que je suis proche de la vision de Iradrille)

    @Iradrille: l'id�e de masques est int�ressante, je ne l'avais jamais vue. Par contre, il y aura vite un probl�me si on a beaucoup de composants de types diff�rents. (et donc cela va d�pendre la taille du jeu et de comment on s�pare les composants - j'ai tendance � en cr�er beaucoup, pour avoir des composants "atomiques").

    Pour l'�tape interm�diaire, c'est quelque chose que j'avais vu. Je crois que l'on peut en fait g�n�raliser le concept : que les syst�mes puissent travailler en plusieurs fois (pas simplement parcourir 1 fois les composants lors de l'update), pour faire des tries, des partitionnements des donn�es (un grand classique est r�organiser les infos utilis�es par la partie graphique, pour regrouper ensemble les �l�ments qui utilisent le m�me contexte GL, pour des raisons de performances), update de cache pour faciliter le boulot des syst�mes, etc.

    Citation Envoy� par LittleWhite Voir le message
    Mais j'ose croire qu'il est impossible de faire un jeu complet avec des composants et un syst�me ECS. C'est mon ressenti, mon impression et surement � cause de mon ignorance.
    Il y a des parties de l'ECS que j'aime bien. Mais � part �a...
    A mon sens, la question de savoir si on peut faire un jeu complet bas� sur un ECS est mal pos�e. On peut faire un jeu complet sans ECS. Mais c'est lourd. On peut faire qu'avec ECS, mais c'est forcer l'utilisation d'une technique.
    La question serait plut�t si on utilise un ECS, seul ou avec d'autres techniques, quel sera le co�t (performances, lourdeur � mettre en place, code tr�s complexe pour certaines fonctionnalit�s, etc) et les b�n�fices (faciliter de cr�ation et �volution des �l�ments du jeu, faciliter de travail avec des game designers, etc).
    Je crois aussi que l'ECS ne peut pas tout faire. En particulier, m�me si on a un syst�me "graphique" dans l'ECS, il faut un backend pour le graphisme, qui optimise le rendu (scenegraph, space partition, caches, etc)

    Citation Envoy� par LittleWhite Voir le message
    Je serai vous, pour tester l'ECS, je ne tenterai m�me pas de mettre �a dans mon jeu ni rien. Je tenterai de mettre �a dans un programme � part, un bac � sable, avec un main et quelques classes de base. Cela permet de tester les limitations, les contraintes, les avantages et mieux comprendre les articles que l'on lit sur Internet.
    Oui.
    Et commencer par des projets pour apprendre � g�rer les ressources, la lib graphique, etc (au moins 1 projet de test pour chaque chose, et probablement plusieurs)

    Citation Envoy� par Iradrille Voir le message
    En quoi la position est sp�ciale et doit �tre int�gr�e � l'entit� ? (J'avoue que j'ai du mal � trouver un exemple d'entit� qui n'aurait pas de position, mais �a existe surement).
    Pour moi, toutes les donn�es sont des le composants, donc tout ce qui a une donn�e et interagit avec d'autres composants doit �tre une entit� + composant(s). En partant de l�, il est facile de concevoir des entit�s sans position :
    - un effet de vent, qui agirait sur le d�placement des joueurs et monstres
    - le soleil (qui sera repr�sent� par une direction plut�t qu'une position), qui produit des ombres (et donc interagit avec le syst�me graphique) ou modifiera la d�tection des ennemis s'ils ont le soleil dans les yeux
    - le vent qui produira un effet sonore 3D
    etc.

    Bref, je suis d'accord, pas de donn�es dans Entit�, juste un identifiant.

    Citation Envoy� par mazertys17 Voir le message
    Si un composant est utilis� par un syst�me, n'est-il pas aussi contenu par celui ci, associ� � l'Entity ( le num�ro ) ?
    Comme l'a dit Iradrille, si un composant est utilis� par 2 syst�mes, quel syst�me doit �tre le conteneur ?

  3. #23
    Membre Expert
    Homme Profil pro
    �tudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activit� : �tudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Par d�faut
    Citation Envoy� par mazertys17 Voir le message
    Si un composant est utilis� par un syst�me, n'est-il pas aussi contenu par celui ci, associ� � l'Entity ( le num�ro ) ?
    Non,

    Un syst�me va poss�der une r�f�rence (au sens large, un pointeur ou un r�f�rence, les deux marchent) sur des ensembles de composants. Tout comme il va contenir une r�f�rence sur la liste d'entit�s.

    Il utilise les entit�s, mais ne les poss�de pas, c'est pareil pour les composants.

    @mintho carmo Pour les masques, jusque 64 (vui, spas �norme) composants �a devrait pas poser de probl�mes, au del� faudra surveiller la performance de std::bitset (qui n'est pas r�put� pour �tre rapide).

  4. #24
    Membre �clair�
    Homme Profil pro
    �tudiant
    Inscrit en
    Octobre 2014
    Messages
    521
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 37
    Localisation : France, H�rault (Languedoc Roussillon)

    Informations professionnelles :
    Activit� : �tudiant

    Informations forums :
    Inscription : Octobre 2014
    Messages : 521
    Par d�faut
    Merci pour toutes ces explications, que je vais prendre soin de relire

    Si j'ai bien compris, le grand avantage dans le ECS, et qui est aussi un peut son inconv�nient, c'est qu'il traite les donn�es "en masse", dans la m�moire, donn�s ( ou composants ) plac�es les unes a c�t�s des autres dans des (vector/tableaux), augmentant ainsi consid�rablement les performances.
    Mais cela implique que pour toutes les interactions, il faut faire "bouger" de l'information ( ce qui peut �tre assez co�teux ).

    Donc, les composants ne doivent pas utiliser de r�f�rences ou de pointeurs. Ils se contentent d'�tre des donn�es "concr�tes", associ�s � un id, con�u pour �tre trait�s � la cha�ne, en somme.

    En revanche, les syst�mes, eux, utilisent des r�f�rences/ptr de ces composants pour les faire fonctionner ( ainsi plusieurs syst�mes diff�rents peuvent utiliser des m�mes donn�es )?

    Dans le cas d'un affichage, par ex, on pourrait avoir ceci :

    -un vector de texture, avec un/des id associ�s.
    -un vector de vertex, avec un id associ�.

    -un system Draw, qui prendrait les vertex, puis les utiliserait sur les textures appropri�s et les dessinerait, puis continuerait et ferait ca a l'infini...?

    -un autre System Positioner, par ex, prendrait les positions de l'objet, et irait repositionner les vertex, faisant �a lui aussi a l'infini ?

    Suis-je sur la bonne voie ?

  5. #25
    Membre �clair�
    Homme Profil pro
    �tudiant
    Inscrit en
    Octobre 2014
    Messages
    521
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 37
    Localisation : France, H�rault (Languedoc Roussillon)

    Informations professionnelles :
    Activit� : �tudiant

    Informations forums :
    Inscription : Octobre 2014
    Messages : 521
    Par d�faut
    Si j'ai bien compris le principe, je me pose quelques questions sur les fondations du programme :

    -une class Game, qui va charger les composants demand�s et les systems, le tout directement sur l'Engine. ( cela vous para�t-il correct ) ?
    -une class Engine, qui va contenir tous les "containers" de composants, ce qui pourrait donner ceci :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
     
    class Engine
    {
     
    public :
     
        Engine() ;
        ~Engine() ;
     
        void                                                                           update () ;
     
     
        std::map < size_t, sf::Texture >                                C_Texture ;
        std::map < size_t, sf::Vector2f >                               C_Position ;
        std::map < size_t, sf::Vertex[4] >                              C_Vertex ;
        etc...
     
        std::vector < std::unique_ptr < System > >               S_System
     
     
    };
    Merci si vous pouvez m'aider

  6. #26
    Membre �m�rite

    Profil pro
    Inscrit en
    D�cembre 2013
    Messages
    403
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : D�cembre 2013
    Messages : 403
    Par d�faut
    Citation Envoy� par mazertys17 Voir le message
    Si j'ai bien compris, le grand avantage dans le ECS, et qui est aussi un peut son inconv�nient, c'est qu'il traite les donn�es "en masse", dans la m�moire, donn�s ( ou composants ) plac�es les unes a c�t�s des autres dans des (vector/tableaux), augmentant ainsi consid�rablement les performances.
    L�int�r�t premier de l'ECS est la souplesse d'utilisation (mais pas pour le d�veloppeur...).
    Si tu as une hi�rarchie en profondeur (par exemple, la classe "Monster" h�rite de "Entity", qui h�rite de "Movable", qui h�rite de "Drawable", qui h�rite de "Object"), si tu veut donner une m�me propri�t� a 2 classes qui ne sont pas dans la m�me hi�rarchie, tu devras le mettre dans "Object" (bof) ou dupliquer le code (re-bof).
    Si tu as un composition par hi�rarchie (la classe "Monster" h�rite de "Entity", de "Movable", de "Drawable" et de "Object"), c'est mieux en termes de r�utilisabilit�, mais un game designer ne peut pas modifier le comportement sans modifier le code (bof).
    Avec l'ECS, tu peux cr�er des comportements param�trables en dehors du code.

    Et la, je rejoins LittleWhite : l'ECS ne sert pas dans tous les jeux. Il n'y a aucun int�r�t (sauf p�dagogique) a cr�er un casse brique ou un arcanoide avec un ECS. A partir du moment ou changer le game design n'est pas critique (parce que le code du jeu n'est pas assez complexe, parce que il n'y a pas beaucoup de type d��l�ments, que les types d��l�ments ne changent pas, ou d'autres raisons), un ECS ne va rien apporte en qualit� de code, mais va le complexifier.

    Le traitement des donn�es "en masse" n'est qu'une obligation qui decoule de l'ECS, du fait que la multitude d'objets (entity et component) fait que l'on a beaucoup plus d�acc�s, trie et recherche a faire et donc besoin d'une meilleure optimisation du code.
    Mais les techniques de regroupement m�moire utilis�es dans l'ECS n'est pas obligatoire (si les performances ne sont pas critiques) et peuvent �tre utilis�es aussi sans ECS (cf les pool objects par exemple). Quand tu as une hi�rarchie d'objet, si tu as besoin de mettre a jour la position en utilisant les infos de vitesse, tu peux y acc�der directement, c'est dans le m�me objet. Avec un ECS, ces infos sont dans 2 composants diff�rents, tu as besoin de parcourir les 2 tableaux pour trouver les infos correspondantes a la m�me entity, c'est plus long.

    Citation Envoy� par mazertys17 Voir le message
    Dans le cas d'un affichage, par ex, on pourrait avoir ceci :

    -un vector de texture, avec un/des id associ�s.
    -un vector de vertex, avec un id associ�.

    -un system Draw, qui prendrait les vertex, puis les utiliserait sur les textures appropri�s et les dessinerait, puis continuerait et ferait ca a l'infini...?

    -un autre System Positioner, par ex, prendrait les positions de l'objet, et irait repositionner les vertex, faisant �a lui aussi a l'infini ?

    Suis-je sur la bonne voie ?
    C'est pour cela que j'ai parle du backend OpenGL, justement parce que je me doutais que ca allait poser probleme (l'affichage est toujours un cas particulier )

    Quel composant a besoin d�acc�der aux infos "id de texture" ou "id de vertex" ? Les texture/vertex ont besoin d�acc�der a quels autres composant ?
    A priori, aucun aux 2 questions. Conclusions, ces infos n'ont pas besoin d��tre dans l'ECS.

    De la m�me fa�on, OpenGL n'a pas besoin des infos de l'ECS, tu lui dis "utilises ces vertices et ces textures" et il s'en moque de ce que cela repr�sente.

    Tu as besoin des id de texture peut �tre dans l'ECS (pour afficher la bonne arme dans les mains du perso et la bonne armure sur son dos), mais les textures/meshs en eux m�me sont des infos du backend graphique, qui doit faire son boulot a part (en bossant directement avec le ressource provider)
    Si tu as par exemple 2 perso affiches et que chacun a une arme, tu dois g�rer les 2 persos comme 2 entit�s dans ton ECS, mais ton backend graphique devrait (pour faire les choses au mieux), regrouper les 2 armes ensembles (pour utiliser la m�me texture/shaders sur les 2 armes) puis la peau des perso (idem, m�me texture et shader), les tissus, etc. Bref, la facon dont le backend graphique fait le rendu du "monde" est diff�rent de la fa�on dont l'ECS le g�re.

    Bref, je rejoins encore une fois LittleWhite, l'ECS ne g�re pas tout.

  7. #27
    Membre Expert
    Profil pro
    Inscrit en
    Mars 2007
    Messages
    1 415
    D�tails du profil
    Informations personnelles :
    Localisation : France, Paris (�le de France)

    Informations forums :
    Inscription : Mars 2007
    Messages : 1 415
    Par d�faut
    Salut

    M�me si l'ECS n'est pas la formule magique qui r�sout tous les probl�mes, �a me para�t tout de m�me assez adapt� pour un STR vous ne trouvez pas ? c'est typiquement le genre de jeu dans lequel on va avoir plein d'unit�s qui vont partager des propri�t�s, et les choix de ces propri�t�s reviennent plus aux level designers et aux cr�atifs qu'au d�veloppeur. M�me si ces deux r�les sont remplis par la m�me personne dans un premier temps, c'est une mani�re saine de s'y prendre.

  8. #28
    Membre �clair�
    Homme Profil pro
    �tudiant
    Inscrit en
    Octobre 2014
    Messages
    521
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 37
    Localisation : France, H�rault (Languedoc Roussillon)

    Informations professionnelles :
    Activit� : �tudiant

    Informations forums :
    Inscription : Octobre 2014
    Messages : 521
    Par d�faut
    Bref, je rejoins encore une fois LittleWhite, l'ECS ne g�re pas tout.
    Merci pour ta r�ponse.

    Donc dans ce cas, par ex, il pourrait y avoir une fonction ind�pendante � la class Engine, qui pourrait �tre "print", et g�rerait toute seul l'affichage, ex :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
     
    class Engine 
    {
         ...
         std::map < size_t , Position >      C_position ;
         ...
         std::map < size_t , Graphics >     U_graphic ; //avec U pour Unique peut être ? histoire de le classer dans une catégorie autre
                                                                            //que S pour System et C pour Composant ?
     
    };
     
    class Engine::print()
    {
         for ( auto& it : _graphic  )
        {
              it.seond.draw() ;
        }
    }
    de la m�me fa�on qu'un composant, un Graphics serait associ� � un ID, mais le Graphics ici serait �galement un mini system qui s'affiche tout seul, en ayant acc�s, par ex au composant "Position", qu'il v�rifie pour updater ses vertexs ?

    cette solution vous para�t viable/optimis� ?


    Je serai vous, pour tester l'ECS, je ne tenterai m�me pas de mettre �a dans mon jeu ni rien. Je tenterai de mettre �a dans un programme � part, un bac � sable, avec un main et quelques classes de base. Cela permet de tester les limitations, les contraintes, les avantages et mieux comprendre les articles que l'on lit sur Internet.
    Oui, effectivement, merci pour le conseil, LittleWhite. C'est comme �a que je vais devoir proc�der


    Merci si vous pouvez m'aider

    ps : et que pensez vous d'utiliser un std::vector < unique_ptr < System > > pour les Systems, sachant que celui ci est a h�ritage ?
    pps : et aussi des noms donn�s aux composants avec C_composantX, et system avec S_ia etc...

  9. #29
    Expert �minent

    Femme Profil pro
    Ing�nieur d�veloppement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    D�tails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (�le de France)

    Informations professionnelles :
    Activit� : Ing�nieur d�veloppement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par d�faut
    A tout hasard, il existe anax et EntityX, deux biblioth�ques d'ECS.

    Je ne les connais pas encore, mais votre discussion m'a amen� � chercher ce qu'est pr�cis�ment un ECS, et je suis tomb� dessus.

  10. #30
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ing�nieur d�veloppement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 131
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activit� : Ing�nieur d�veloppement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 131
    Billets dans le blog
    150
    Par d�faut
    Citation Envoy� par jblecanard Voir le message
    Salut

    M�me si l'ECS n'est pas la formule magique qui r�sout tous les probl�mes, �a me para�t tout de m�me assez adapt� pour un STR vous ne trouvez pas ? c'est typiquement le genre de jeu dans lequel on va avoir plein d'unit�s qui vont partager des propri�t�s, et les choix de ces propri�t�s reviennent plus aux level designers et aux cr�atifs qu'au d�veloppeur. M�me si ces deux r�les sont remplis par la m�me personne dans un premier temps, c'est une mani�re saine de s'y prendre.
    Oui, il y a certaines parties qui sont cools et avantages dans l'ECS, pour un STR et l�, je suis d'accord avec votre point de vue. L'ECS est adapt� dans les cas "comportements" :
    - une unit� movable (peux avoir une destination et s'y rendra) ;
    - une unit� peut attaquer
    - une unit� peut construire
    - une unit� peut lancer des sorts
    - une unit� peut ramasser des ressources
    ...
    - un batiment peut produire
    ...
    (et bien sur, chacun de ces comportements peux ne pas exister)

    Mais, l�, on ne parle que du comportement des �l�ments du jeu, comportement correspondant � un type pr�cis de jeu. En y r�fl�chissant bien, on peux aussi appliquer assez facilement ce type de cas � d'autres jeux, juste les comportements changent.
    par contre, comme hier (page 1), je pense que je replonge dans une arborescence classique OO, r�alisable avec le pattern Strategy ...

    Maintenant, il y a une partie, que tous les jeux ont :
    - une boucle de jeu (update des �l�ments)
    - l'affichage � l'�cran des �l�ments
    ...
    - contr�le par le joueur ou l'IA

    Et l�, en r�alit�, on a un second niveau d'ECS, d'apr�s moi. Dans le sens, vous avez la partie "comportementale des �l�ments du jeux" (soit, le gameplay), qui aura son propre ECS, ind�pendant (ou s�par�), de l'ECS "moteur". Et ce second sera applicable (en th�orie) � tous les jeux. Malheureusement, l'affichage est ultra ultra contraignante dans les jeux vid�os (les comportements des �l�ments aussi ).

    @mazertys17 :
    Je trouve que vous avez un souci de s�mantique (utilisation des mots), qui se r�percute dans le nommage des variables. Autant que dans les probabilit� en math�matique, la s�mantique en programmation est ultra importante, pour que le code soit rapide � comprendre.
    Je vous donne un exemple :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    class Engine::print()
    {
         for ( auto& it : _graphic  )
        {
              it.seond.draw() ;
        }
    }
    Pourquoi une fonction qui fait un bouclage pour faire des "draw", va s'appeler "print()" ?
    Cela n'a pas de sens, car l�utilisation d'un mot diff�rent sugg�re une action diff�rente ... alors que ce n'est pas le cas.

    Par contre, pour moi, l�existence de cette fonction "draw()/print()" �tait obligatoire.
    Vous souhaitez participer � la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui conna�t l'erreur, conna�t la solution.

  11. #31
    Membre �clair�
    Homme Profil pro
    �tudiant
    Inscrit en
    Octobre 2014
    Messages
    521
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 37
    Localisation : France, H�rault (Languedoc Roussillon)

    Informations professionnelles :
    Activit� : �tudiant

    Informations forums :
    Inscription : Octobre 2014
    Messages : 521
    Par d�faut
    Par contre, pour moi, l�existence de cette fonction "draw()/print()" �tait obligatoire.
    donc vous voulez dire que c'est en effet une d�marche correcte ( mis � part le nom ) ?

    voici l'exemple de l'affichage, que je viens de mettre en place :

    d�j�, je prend le parti de construire a la base le composant position :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    class Engine 
    {
        ...
        std::map < size_t , sf::Vector2f >                              C_position ;
        ...
        std::map < size_t, Graphics >                                   U_graphics ;
        ...
    };
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
     
    Game::build ( std::string& name, float x , float y )
    {
        ....
        _number ++ ;
        _engine.C_position.insert( std::pair < size_t , sf::Vector2f > ( _number , sf::Vector2f ( x , y ) ) ) ;
        ....
    }
    puis je construit le module Graphics ( s'il est appel� )

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    Game::buildGraphics ( std::ifstream& flux )
    {
                    //lecture des données qui sont transfomés en word1, int0, int1 etc...
                    ...
                    std::map < size_t , sf::Vector2f > :: iterator itPosition ;
                    itPosition = _engine.C_position.find ( _number ) ;
                    _engine.U_graphics.insert ( std::pair < size_t , Graphics >( _number , Graphics ( _data , itPosition -> second ) ) ) ; // je mets ici la ref de position
                    std::map < size_t , Graphics > :: iterator it ;
                    it = _engine.U_graphics.find ( _number ) ;
                    it -> second.add ( "empty" , _resources.getTexture( word1 ) , int0 , int1 , int2 , int3 , int4 , int5 ) ;
                    ...
    }
    ( sachant que ma class graphics a une r�f�rence sf::Vector2f& _position ).

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
     
    void Engine::draw()
    {
        _data._window.clear() ;
        for ( auto& it : U_graphics )
        {
            it.second.draw() ;
        }
        _data._window.display() ;
    }
    ( personne ne m'a tellement dit, sauf erreur, si l'id�e d'un unique "data" qui contient les infos de base du system, comme la fen�tre, le temps etc... est une bonne id�e, alors j'ai pris le parti de le garder pour l'instant. C'est pourquoi l'Engine l'utilise pour afficher la fen�tre ).

    Dans mon cas, il faut anticiper le fait que si un objet est d�truit, l'affichage doit �tre le 1er � pratiquer la destruction du composant. ( pour �viter ainsi les pb ).

    ps: j'ai obtenu l'h�bergement Developpez pour mon projet, ( et j'en profite pour remercier chalereusement l'�quipe au passage ), alors je vais pas tarder � mettre un forum et tt ce qu'il faut en place, pour avancer plus proprement. Tout programmeur qui voudra contribuer � mon projet sera bienvenu .

  12. #32
    Membre Expert
    Homme Profil pro
    �tudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activit� : �tudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Par d�faut
    Citation Envoy� par mintho carmo Voir le message
    Et la, je rejoins LittleWhite : l'ECS ne sert pas dans tous les jeux. Il n'y a aucun int�r�t (sauf p�dagogique) a cr�er un casse brique ou un arcanoide avec un ECS. A partir du moment ou changer le game design n'est pas critique (parce que le code du jeu n'est pas assez complexe, parce que il n'y a pas beaucoup de type d��l�ments, que les types d��l�ments ne changent pas, ou d'autres raisons), un ECS ne va rien apporte en qualit� de code, mais va le complexifier.
    Le choix d'utiliser un ECS ou pas doit �tre plus bas� sur l'�volution du gameplay (avec un ECS on ne "bloque" aucune possibilit�).
    Pour un casse-brique, si les game designers viennent te voir demain en te disant "on vient d'avoir une pu***n d'id�e : des billes apparaissent r�guli�rement (toutes les x secondes), et quand il y a plus de billes que de briques, les billes deviennent des briques, et les briques deviennent des billes".
    Avec un ECS, passer d'un casse brique classique � �a, c'est relativement simple.

    Si on doit ajouter des briques sp�ciales qui, une fois d�truites, deviennent des raquettes suppl�mentaires que le joueur contr�le, c'est simple aussi.

    Mettre en place un ECS c'est pas forc�ment simple et demande pas mal de boulot, si �a ne t�apporte rien (parce que le gameplay est d�fini et changera pas (ou peu)), alors c'est probablement pas une bonne id�e.
    Mais je ne pense pas qu'il existe un type de jeu en particulier qui ne doive pas �tre impl�ment� gr�ce � un ECS (ou, dit autrement, qui ne puisse pas b�n�ficier de la puissance d'un ECS).

    Citation Envoy� par mintho carmo Voir le message
    Mais les techniques de regroupement m�moire utilis�es dans l'ECS n'est pas obligatoire (si les performances ne sont pas critiques) et peuvent �tre utilis�es aussi sans ECS (cf les pool objects par exemple). Quand tu as une hi�rarchie d'objet, si tu as besoin de mettre a jour la position en utilisant les infos de vitesse, tu peux y acc�der directement, c'est dans le m�me objet. Avec un ECS, ces infos sont dans 2 composants diff�rents, tu as besoin de parcourir les 2 tableaux pour trouver les infos correspondantes a la m�me entity, c'est plus long.
    Parcourir un ou deux tableaux ne change (quasiment) rien (si les tableaux sont tri�s dans le m�me ordre) tant qu'on a les donn�es dont on a besoin et rien d'autre.
    Quant on � des donn�es inutiles, �a prend de la place dans le cache pour rien et �a va augmenter le nombres de cache misses.

    Parcourir 2 tableaux "positions" et "velocities" sera tr�s certainement plus rapide que de parcourir un seul tableau d'entit�s qui contiennent tout un tas de donn�es inutile au traitement. Dans le cas d'une hi�rarchie d'objets, tu auras au strict minimum un pointeur vers une vtable qui sera "fournie" avec tes objets mais qui sera inutile au traitement.

    Mais on se rapproche dangereusement de l'optimisation pr�matur�e. =)

    Citation Envoy� par mintho carmo Voir le message
    Bref, je rejoins encore une fois LittleWhite, l'ECS ne g�re pas tout.
    Oui, l'ECS g�re le gameplay (toute la logique du jeu), la partie affichage doit �tre � part.

    Citation Envoy� par leternel Voir le message
    A tout hasard, il existe anax et EntityX, deux biblioth�ques d'ECS.

    Je ne les connais pas encore, mais votre discussion m'a amen� � chercher ce qu'est pr�cis�ment un ECS, et je suis tomb� dessus.
    Jamais entendu parler de anax, mais j'ai par contre entendu parler de EntityX en bien � plusieurs reprises.
    Jamais utilis� ni l'une ni l'autre par contre.

  13. #33
    Expert �minent

    Femme Profil pro
    Ing�nieur d�veloppement logiciels
    Inscrit en
    Juin 2007
    Messages
    5 202
    D�tails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Essonne (�le de France)

    Informations professionnelles :
    Activit� : Ing�nieur d�veloppement logiciels

    Informations forums :
    Inscription : Juin 2007
    Messages : 5 202
    Par d�faut
    J'irai jeter un oeil attentif sur EntityX, dans ce cas.

  14. #34
    Membre �clair�
    Homme Profil pro
    �tudiant
    Inscrit en
    Octobre 2014
    Messages
    521
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 37
    Localisation : France, H�rault (Languedoc Roussillon)

    Informations professionnelles :
    Activit� : �tudiant

    Informations forums :
    Inscription : Octobre 2014
    Messages : 521
    Par d�faut
    A tout hasard, il existe anax et EntityX, deux biblioth�ques d'ECS.
    Oui, j'en ai entendu parler. Apr�s, au point ou j'en suis, je pense que c'est jouable de b�tir mon programme juste avec la SFML.

    Oui, l'ECS g�re le gameplay (toute la logique du jeu), la partie affichage doit �tre � part.
    Oui, donc il faut un peut mixer l'ECS avec la poo, si je comprend bien, pour pouvoir avoir un peut de flexibilit�...En tout cas, je reconnais que ce concept d'ECS a l'air vraiment pratique.

    Encore quelques questions :

    un std::map < size_t , Composant > pour chaque composant est-il une bonne solution ( ou le std::map n'est pas forc�ment le plus optimis�/utile dans ce cas ) ?

  15. #35
    Membre Expert
    Homme Profil pro
    �tudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activit� : �tudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Par d�faut
    Citation Envoy� par mazertys17 Voir le message
    Encore quelques questions :

    un std::map < size_t , Composant > pour chaque composant est-il une bonne solution ( ou le std::map n'est pas forc�ment le plus optimis�/utile dans ce cas ) ?
    Il n'y a pas de r�ponse g�n�rale. C'est au cas par cas.

    Pour un composant que toutes (ou presque) tes entit�s poss�deront, un std::vector<Composant> peut �tre un bon choix, il y aura quelques "cases vides" mais tu aura une bonne localit� pour tes donn�es.

    Pour un composant que tr�s peu d'entit�s poss�deront, une std::map<Entity, Composant> peut �tre un bon choix si tu as besoin d'un ordre pr�cis, sinon un std::unordered_map<Entity, Composant> peut faire l'affaire. Ou peut �tre qu'une boost::container::flat_map<Entity, Composant> sera meilleure.

    Bref, pas de r�elle r�ponse, d�sol�.

    Citation Envoy� par mazertys17 Voir le message
    Si j'ai bien compris, le grand avantage dans le ECS, et qui est aussi un peut son inconv�nient, c'est qu'il traite les donn�es "en masse", dans la m�moire, donn�s ( ou composants ) plac�es les unes a c�t�s des autres dans des (vector/tableaux), augmentant ainsi consid�rablement les performances.
    Mais cela implique que pour toutes les interactions, il faut faire "bouger" de l'information ( ce qui peut �tre assez co�teux ).

    Donc, les composants ne doivent pas utiliser de r�f�rences ou de pointeurs. Ils se contentent d'�tre des donn�es "concr�tes", associ�s � un id, con�u pour �tre trait�s � la cha�ne, en somme.

    En revanche, les syst�mes, eux, utilisent des r�f�rences/ptr de ces composants pour les faire fonctionner ( ainsi plusieurs syst�mes diff�rents peuvent utiliser des m�mes donn�es )?
    J'avais pas vu ce post, �a r�sume bien le principe oui.

    Il est pr�f�rable (quand c'est possible) d'avoir des syst�mes qui soient totalement ind�pendants : syst�me A travaille sur les composants 1 et 2, syst�me B travaille sur les composants 3, 4 et 5.
    �� permet d'avoir des composants tri�s correctement pour les syst�mes, et de multithreader facilement les syst�mes. (Cas le plus simple : 1 thread par syst�me).

    Mais c'est pas toujours possible, dans ce cas il faut faire gaffe aux data races (et � l'ordre d'�x�cution des syst�mes).

  16. #36
    Expert �minent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activit� : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par d�faut
    Citation Envoy� par mazertys17 Voir le message
    Oui, j'en ai entendu parler. Apr�s, au point ou j'en suis, je pense que c'est jouable de b�tir mon programme juste avec la SFML.



    Oui, donc il faut un peut mixer l'ECS avec la poo, si je comprend bien, pour pouvoir avoir un peut de flexibilit�...En tout cas, je reconnais que ce concept d'ECS a l'air vraiment pratique.

    Encore quelques questions :

    un std::map < size_t , Composant > pour chaque composant est-il une bonne solution ( ou le std::map n'est pas forc�ment le plus optimis�/utile dans ce cas ) ?
    De mani�re tout � fait g�n�rale, tu dois te dire qu'une tr�s grosse majorit� du travail d'utilisation de tes composants sera bas� soit sur l'ex�cution par lot (de begin(), � end()), soit sur la recherche (quelle est la valeur du composant (56 998) ou de celui correspondant � l'entit� 12 345 ) avec tr�s peu (pour ainsi dire aucun) ajouts pendant le jeu (du moins, une fois que les donn�es ont �t� charg�es s'entend) et possibilit� de modification (mais sans obligation) de certaines valeurs.

    Les composants trait�s par lots, mais sur lesquels tu n'a que peu de recherches � effectuer seront sans doute plac�s dans un std::vector car cela permet de profiter de la mise en cache des donn�es effectu�e par le processeur.

    Ceux pour lesquels tu as beaucoup de recherches � faire prendront sans doute place dans un std::set/ std::unordered_set s'ils ne sont jamais modifi�s (la description associ�e � une entit� ne change th�oriquement jamais )o u dans une std::map/std::unordered_map s'il doivent �tre modifiables (vie, v�locit� (avec acc�l�ration/ d�c�l�ration possible), ...) voir dans un conteneur "multi index" comme ceux fournis par boost::multi_index si tu te rend compte que tu utilises r�guli�rement plusieurs types de cl� pour tes recherhes

    Evidemment, il s'agit d'une approche "� la grosse louche", qui m�rite amplement d'�tre peaufin�e en cours de route et en fonction des composants utilis�s... En plus, tout ne sera pas forc�ment toujours aussi simple que ces deux choix "principaux"
    A m�diter: La solution la plus simple est toujours la moins compliqu�e
    Ce qui se con�oit bien s'�nonce clairement, et les mots pour le dire vous viennent ais�ment. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 f�vrier 2014
    mon tout nouveau blog

  17. #37
    Membre �clair�
    Homme Profil pro
    �tudiant
    Inscrit en
    Octobre 2014
    Messages
    521
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 37
    Localisation : France, H�rault (Languedoc Roussillon)

    Informations professionnelles :
    Activit� : �tudiant

    Informations forums :
    Inscription : Octobre 2014
    Messages : 521
    Par d�faut
    plac�s dans un std::vector
    Ok, cela supose qu'il faut mettre l'ID dans les attributs du vector j'imagine..?..

    Pour aller pas � pas, je commence a �laborer quelques fonctions ( pour l'instant c'est avec std::map, mais je vais changer ca ). S.V.P, j'aimerais savoir si cela vous parait aller dans le bon sens ( ca marche, mais est-ce bien correct comme facon de faire, selon vous ) :

    Dans cette exemple, le but est simplement de s�lectionner un objet ( ou plusieurs ), en mettant les ID concern�s dans un vector ( qui pourra servir par la suite pour d'autres op�rations, comme donner des ordres de d�placement etc... ).

    ici, un syst�me "S_Control" qui contient des r�f�rences sur les containers de composants suivant : C_Position, C_SelectionZone, I_selected.

    -le C_Position contient des positions ( sf::vector2f )
    -le C_SelectionZone contient un sf::IntRect ( la zone de selection )
    -le I_Selected contient tous les IDs selectionn�s. ( en fait ce n'est pas un composant, d'o� le I devant au lieu de C ).

    Cela donne ceci dans mon Engine :
    (encore une fois, il faudra que je change les std::map en vector )
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    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
     
     
    class Engine
    {
     
    public :
     
        Engine( Data& data ) ;
        ~Engine() ;
     
        void                                                            add () ;
        void                                                            update () ;
        void                                                            draw() ;
     
        Data&                                                           _data ;
     
        std::vector < std::shared_ptr < System > >                      S_system ;
     
        std::map < size_t, Graphics >                                   U_graphics ;
     
        std::map < size_t , sf::Vector2f >                              C_position ;
        std::map < size_t , sf::IntRect >                               C_selectionZone ;
     
        std::vector < size_t >                                          I_selected ;
     
    };
    voici mon system "S_Control", h�rit� de System :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    class S_Control : public System
    {
    public :
     
        S_Control(  std::map < size_t , sf::Vector2f >& position ,
                    std::map < size_t , sf::IntRect >&   controlZone ,
                    std::vector < size_t >& selected ) ;
     
        ~S_Control() ;
     
        void                                                             update() ;
     
     
        std::map < size_t , sf::Vector2f >&                              C_position ;
        std::map < size_t , sf::IntRect >&                               C_selectionZone ;
        std::vector < size_t >&                                          I_selected ;
     
    protected :
     
    };
    et enfin ( et c'est surtout l� que j'ai besoin de votre avis ), son utilisation :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    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
     
     
     
    void S_Control::update()
    {
        if ( sf::Mouse::isButtonPressed ( sf::Mouse::Left ))
        {
            if ( !sf::Keyboard::isKeyPressed ( sf::Keyboard::LControl )) //si Control n'est pas enfoncé, alors on désélectionne tt le monde.
            {
                I_selected.clear() ;
            }
            for ( auto& it : C_position )
            {
                for ( auto& itS : C_selectionZone )
                {
                    if (  itS.first == it.first )
                    {
                        if (  sf::Mouse::getPosition().x > it.second.x + itS.second.left && sf::Mouse::getPosition().x < it.second.x + itS.second.left + itS.second.width
                        &&    sf::Mouse::getPosition().y > it.second.y + itS.second.top  && sf::Mouse::getPosition().y < it.second.y + itS.second.top  + itS.second.height )
                        {
                            I_selected.push_back ( it.first ) ;
                            it.second.x ++ ; // ca c'est pour le test, quand un objet est selectionné, on le voit se déplacer vers la droite.
                        }
                    }
                }
            }
        }
    }
    J'ai donc une double boucle, et pour une chose tr�s basique, ce qui doit pas �tre top. Est-ce pourtant bien cela le ECS ?

    Bref. Tout cela me parait fort lourd au d�part, mais je supose que plus ca avancera, plus ca sera "rentable".

    Merci si vous pouvez m'aider

  18. #38
    Expert �minent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activit� : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par d�faut
    Ne t'int�resse pas trop � la "machinerie" dans un premier temps...

    Dans un premier temps, ce qu'il te faut, c'est quelques composants simples qui te permettront d'en cr�er de plus complexes et un moyen de disposer d'entit�s.

    Les entit�s, c'est tr�s simple : ce ne sont que des identifiants uniques. Cela n'a rien : ni comportement, ni donn�e. Le plus simple et le plus efficace pour identifier quelque chose, c'est d'utiliser une valeur enti�re (sans doute non sign�e) et de s'assurer qu'elle n'est utilis�e que pour une chose. Mais comme "cr�er, c'est nommer", on peut envisager (ce sera plus facile pour le d�buggage) de rajouter une chaine de caract�res qui repr�sente le nom de chaque entit�.
    Tu auras donc une structure Entity qui prendra une forme proche de
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    struct Entity{
        size_t id;
        std::string name;
    };
    // nécessaire pour l'utilisation d'un set
    bool operator<(Entity const & one, Entity const & two){
        return one.id<two.id;
    }
    Puis, il te faut "quelque chose" qui te permette d'avoir "toutes les entit�s sous la mains"... Cela prendra la forme d'une classe "EntityHolder" proche de
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    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
     
    class EntityHolder{
        public:
            using const_iterator = std::set<Entity>::const_iterator;
            /* Crée une nouvelle entité et revoie son identifiant unique */
            size_t create(std::string const & name){
                 auto id=items_.size()+1; // l'identifiant (unique) de chaque
                                          // entité est son ordre d'insertion
                                          //  dans la table ;)
                 items_.insert(Entity{id, name});
                 return id;
            }
            /* tu voudras sans doute, lors du développement, savoir si une 
             * entité existe déjà ;) */
            bool exists(std::string const & name) const{
                 return find(name)!=0;
            }
            /* lors du développement, tu voudras sans doute récupérer
             *  l'identifiant d'une entité que tu connait par son nom
             */
            size_t find(std::string const & name) const{
                auto const & it = find_if(begin(),end(),
                                          [name](Entity const & e)->bool {
                                              return e.name == name;
                                          });
                return it == end()? 0 : it->id;
            }
            const_iterator begin() const{
                return items_.begin();
            }
            const_iterator end() const{
                return items_.end();
            }
    private:
        std::set<Entity> items_;
    };
    L'id�e est que tu voudras sans doute travailler avec tes entit�s (durant le d�veloppement) sous une forme proche de
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    int main(){
        EntityHolder holder;
        holder.create("petite epee rouillee");
        holder.create("petite hache rouillee");
        holder.create("petit gourdin de bois vert");
        holder.create("petite potion de sante");
        holder.create("petite potion de mana");
        holder.create("petite potion de force");
        holder.create("vers sanguinaire");
        holder.create("gobelin des montagnes");
        holder.create("Mercenaire Troll");
        holder.create("Chaman Troll");
        holder.create("Sort de soins");
     
        /*... Beaucoup plus loin, en développpement
         */
        auto found = holder.find("petite epee rouillee");
    }
    (bon, je sais... je me dirige beaucoup plus vers un RPG que vers un STR l�, mais le principe reste valide )

    Ensuite, il faut les composants qui t'int�ressent. On peut dire qu'il y a deux types essentiels de composants:
    • Les composants "g�n�raux" qui repr�sentent des caract�ristiques essentielles comme le type de d�gat, le type d'arme, la race, ...
    • Les composants plus "sp�cifiques" comme "le nombre de point de vie du monstre correspondant � l'entit� 123 896"
    Tout composant a forc�ment un identifiant unique. Les composant "g�n�raux" pourraient d'ailleurs se limiter � cet identifiant unique, mais on peut (comme on l'a fait pour les entit�s) envisager de rajouter une chaine de caract�res qui les nommes.

    Les composants "sp�cifiques" n�cessiteront en plus une "cl� �trang�re" repr�sentant l'entit� � laquelle ils font r�f�rence et disposerons sans doute aussi de valeurs suppl�mentaires. Je m'explique: Nous pourrions avoir une "liste de caract�ristiques proche de
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    id    |   nom
    =================
      1   | vie
      2   | mana
      3   | force
      4   | agilite
      5   | magie de la terre
      6   | magie de l'eau
      7   | magie du feu
      8   | magie de l'air
    ....
    Tout comme tu pourrais avoir une liste de type d'armes proches de
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    id    |   nom
    =================
      1   | arme a une main
      2   | arme a deux main
      3   | arme de jet
      4   | arme contondante
      5   | arme perforante
      6   | arme tranchante
    ...
    ( tu remarquera que "petite epee rouillee" est � la fois 1(arme � une main) et 6 (arme tranchante) )

    Et, si l'on y regarde bien, une arme et une potion agirons (peu ou prou) de la m�me mani�re : en modifiant la valeur d'une caract�ristique bien particuli�re de l'entit� qui en fait les frais.

    Ainsi, nous pourrions avoir un composant "modifieur de caracteristique" qui ferait le lien entre les entit�s et les composants "de base", sous une forme proche de
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    struct Modifier{
        size_t id;               // l'identifiant unique
        size_t related_to;      // l'entité dont on parle
        size_t caracteristique; // que modifie-t-on
        int difference;         // Dans quelle ordre de grandeur
    }
    tu pourras donc d�finir ce qui agit sur quelle caract�ristique sous la forme d'un table qui pourrait ressembler �
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    id    | related | caracteristique | difference
    =================================
      1   |     4   |    1            | 50 // petite potion de vie (4) ajoute 50 à la vie (1)
      2   |     5   |    2            | 50 // petite potion de mana(5) ajoute 50 à la mana (2)
      3   |     1   |    1            | -3  // petite épée rouillée (1) retire 3 à la vie (1)
    ...
    Et bien sur, ce ne sont que des exemples... Des composants de base pourraient aussi �tre du type "ressources" (comprends :or, bois, minerai, ...) ou autre... Seule ton imagination sera ta limite

    Une fois que tu commence � avoir une id�e pr�cise des composants que tu utilises (ceux que j'ai mis en exemple ne sont pas forc�ment adapt�s � tes besoins propres ) tu peux commencer � r�fl�chir � comment les utiliser et, surtout, � "qui en a besoin"
    A m�diter: La solution la plus simple est toujours la moins compliqu�e
    Ce qui se con�oit bien s'�nonce clairement, et les mots pour le dire vous viennent ais�ment. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 f�vrier 2014
    mon tout nouveau blog

  19. #39
    Membre �clair�
    Homme Profil pro
    �tudiant
    Inscrit en
    Octobre 2014
    Messages
    521
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 37
    Localisation : France, H�rault (Languedoc Roussillon)

    Informations professionnelles :
    Activit� : �tudiant

    Informations forums :
    Inscription : Octobre 2014
    Messages : 521
    Par d�faut
    Merci pour ta r�ponse et toutes les explications

    Si je te suis bien, le EntityHolder est une sorte de "livret" qui contient toutes les entitys qui tournent dans le jeu. Ce "livret" pourrait �tre utilisable par des systems pour chercher les entitys correspondantes a leurs attentes. ( ex, le syst�me builder va avoir besoin de "worker", il le demande au EntityHolder de lui envoyer tous les "worker" et celui ci lui renverra les id 451, 54987, 145 et 44 ). Le System fera ensuite son boulot avec sous la main les bons IDs.

    Pour rebondir sur mon exemple pr�c�dent avec la s�lection, on pourrait d�cider de rajouter une fonction "getSelected" dans le "EntityHolder", qui renverrait une s�rie d'ID, tous ceux qui sont s�lectionn�s par le joueur, ( ajout� ici, dans le vector par S_Control ).
    ( si je te suis toujours ). A moins que tout ce que je viens de dire risque d�alourdir une class qui se doit d'�tre minimaliste pour des raisons de perfs ( mais je verrais pas trop pourquoi ) ?

    Tout composant a forc�ment un identifiant unique. Les composant "g�n�raux" pourraient d'ailleurs se limiter � cet identifiant unique, mais on peut (comme on l'a fait pour les entit�s) envisager de rajouter une chaine de caract�res qui les nommes.

    Les composants "sp�cifiques" n�cessiteront en plus une "cl� �trang�re"
    Et ceci reviendrais au finale � traduire un std::string par un nombre ?

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
     
    id    | related | caracteristique | difference
    =================================
      1   |     4   |    1            | 50 // petite potion de vie (4) ajoute 50 à la vie (1)
      2   |     5   |    2            | 50 // petite potion de mana(5) ajoute 50 à la mana (2)
      3   |     1   |    1            | -3  // petite épée rouillée (1) retire 3 à la vie (1)
    ...
    dans cet exemple, la clef caracteristique 1 ne pourrait repr�senter que "petite potion de vie"
    en revanche, il pourrait y avoir une clef armement 1 qui elle, serait un "petit couteau" ?


    @Iradrille
    �� permet d'avoir des composants tri�s correctement pour les syst�mes, et de multithreader facilement les syst�mes. (Cas le plus simple : 1 thread par syst�me).
    J'avais un peu peur de ca...Mais cela veut-il dire que pour pratiquer le ECS, le multi-thread est indispensable ?

    ps: que pensez vous du nomage que j'ai pr�sent� plus haut ( pour les struct et les class ) ?

    S_MySystem // pour les System ( ex S_Control , S_Physics )
    C_MyComponent // pour les composants ( ex C_Position, C_SelectionZone )
    U_MyUnique // pour des SystemComponent ( ex U_Draw, qui est a la fois un Composant et System )

    ( et ici pour des composants individuels )
    I_MyIndividual // pour des vector qui contiennent des Entit�s particuli�res ( ex I_Selected , I_Magic, I_Building ) ( ceux-ci seraient contenu dans le Holder ?

  20. #40
    Membre Expert
    Homme Profil pro
    �tudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activit� : �tudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Par d�faut
    @Koala, J'ai vraiment l'impression que tu pousses l'aspect relationnel trop loin.

    Dans ton dernier post tu m'as un peu surpris en parlant de std::set pour stocker des composants, ou en disant que la description d'une entit� ne changeait jamais.

    Mais je comprend mieux (je crois ), tu pousses le concept � l�extr�me pour au final avoir un jeu fait exclusivement de requ�tes SQL (que ce soit en utilisant un SGBDR existant ou en recr�ant un) ?

    J'ai par exemple du mal � voir pourquoi un id et une clef �trang�re sont pr�sentes ici
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    struct Modifier{
        size_t id;               // l'identifiant unique
        size_t related_to;      // l'entité dont on parle
        size_t caracteristique; // que modifie-t-on
        int difference;         // Dans quelle ordre de grandeur
    }
    Dans une DB, oui �a sera stock� comme �a, mais en �-t-on besoin ici ?
    Un syst�me travaille sur un tuple de composants sans se pr�occuper de l'entit� � laquelle ces composants appartiennent non ?

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    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
    enum Carac {
        CARAC_A,
        CARAC_B,
        CARAC_C
    };
     
    struct Modifier{
        Mask mask = 1<< 0;
        Carac caracteristique; // que modifie-t-on
        int difference;         // Dans quelle ordre de grandeur
    };
     
    struct HasCarac {
        Mask mask = 1<< 0;
        int caracteristiques[3];
    };
     
    std::unordered_map<Entity, Modifiers> modifiers;
    std::unordered_map<Entity, HasCarac> caracteristiques;
     
    struct SystemModifier {
        Mask mask = HasCarac::mask | Modifier::mask;
        void update() {
            for(auto e: entities) {
                if(masks[e] & mask == mask) {
                    Modifier &m = modifiers[e];
                    HasCarac &hc = caracteristiques[e];
     
                    hc.caracteristiques[m.caracteristique] += m.difference;
                }
            }
        }
    };
    Citation Envoy� par mazertys17 Voir le message
    J'avais un peu peur de ca...Mais cela veut-il dire que pour pratiquer le ECS, le multi-thread est indispensable ?
    Indispensable non, bien sur que non. Mais si les syst�mes sont ind�pendants c'est tr�s simple � multi-threader (et dans ce cas, pourquoi se priver ?).

Discussions similaires

  1. Conception et programmation orient�es objet
    Par forum dans le forum Livres
    R�ponses: 2
    Dernier message: 31/08/2018, 16h44
  2. R�ponses: 0
    Dernier message: 15/07/2014, 21h31
  3. R�ponses: 0
    Dernier message: 15/07/2014, 21h31
  4. concepts de programmation en couches
    Par solitude dans le forum Windows Forms
    R�ponses: 3
    Dernier message: 07/11/2008, 14h01

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo