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

Développement 2D, 3D et Jeux Discussion :

Conception d'une bibliotheque de règles JdR


Sujet :

Développement 2D, 3D et Jeux

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    100
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 100
    Points : 150
    Points
    150
    Par défaut Conception d'une bibliotheque de règles JdR
    Bonjour à tous,

    Un ami et moi essayons de créer une bibliothèques permettant d'utiliser des règles de jeu de role de manière objet en C++.

    Nous nous sommes penché sur un aspect un peu special et nous avons 2 idées pour concevoir cela, sachant que chacune a des avantages et inconvénient. On essaye de voir si une autre solution moins "facile à trouver" existe pour gérer cela.

    Cela concerne ce qu'a le personnage, ce qu'il est : classe de personnage, caractéristique (force, constitution, intelligence, ...) . Ce qu'il peut faire : dons (des capacités choisies au fil des niveaux ou recu grace a la classe de personnage), des competences qui peuvent evoluer au fil des niveaux suivant le choix du joueur, les sorts, etc.

    En gros, pour la 2 eme catégorie, ce qu'il peut faire, on a pensé que chaque sous catégorie permettait de faire des actions qui avaient des effets. Au final, ca devient assez générique, sauf que des compétences peuvent évoluer, alors que des dons, non; les sorts dépendent de sa classe etc.
    On a rajouté dans les effets, que meme des caracteristiques pouvaient être le résultat d'un effet (une sorte de don invisible qui donne +4 en constitution par exemple). Or dans le cas des caractéristiques, de l'armure ou des points de vie, plusieurs type d'effets peuvent se cumuler : des bonus grace a des sorts, des bonus grace a une armure, des bonus grace a un don (ce bonus est donc l'"effet" du don).

    Ainsi pour récupérer la valeur des points de vie, on ferait (attention, exemple bateau basique, mais bon, c pour expliquer)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    int getPV()
    {
    vector<Effet> listeEffetPV = getModificateursPV();
    vector<Effet>::iterator ite;
    int totalPV = 0;
     
    for(ite.begin(); ite.end(); ++ite)
    {
              totalPV += fonctionRetournantLePVdeChaqueEffetPV;
    }
     
    return totalPV
    }
    Or dans une approche plutot héritage, on aurait des effets specialisés implémentant chaque fonction les intéressant : getPVBonus pour un PVBonusEffet, getCaracBonusEffet pour un CaracBonusEffet. Etc, etc
    Or cela impliquerait que la classe abstraite Effet aurait toute les fonctions mais ne les implémenterait pas de base...
    C'est pas terrible niveau souplesse si on doit rajouter des nouveaux types d'effets

    L'autre approche serait de faire que chaque effet soit un Effet, mais que suivant le instanceEffet.type, le traitement diffère.
    Ce qui revient a faire des if pas beau a chaque traitement. (et limite on pourrait passer par les RTTI et donc faire des classe spécialisé d'Effet + ou - vide permettant juste d'etre identifié par leur nom de classe...)
    exemple :
    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 Effet
    {
    public:
         int getEffetValue()
    };
     
    int getPV()
    {
    vector<Effet> listeEffetPV = getModificateursPV();
    vector<Effet>::iterator ite;
    int totalPV = 0;
     
    for(ite.begin(); ite.end(); ++ite)
    {
    if(ite.type == "PV")
    {
              totalPV += ite.getEffetValue();
    }
    }
     
    return totalPV
    De notre coté, on voudrait plutot une sorte de bibliotheques d'effets stockées en XML, donc avec un code générique s'adaptant aux données au niveau du runtime et non pas quelque chose ecrit dans le marbre avec une arborescence fixe d'heritage.

    Je pense qu'il existe une solution plus propre, et plus orientée objet, seulement, elle ne nous est pas venu naturellement. Donc je ressors mon bouquin de design pattern/conception objet, mais je ne suis pas sur de faire un lien direct entre la solution montrée en exemple et mon cas pratique actuel...
    Si on ne trouve pas d'ici 2 semaine, on risque de garder une des 2/3 solutions expliquée dessus ... Si je peux eviter si il existe une solution plus propre, ca m'interesserait ...

    Merci de m'avoir lu !

  2. #2
    Invité
    Invité(e)
    Par défaut
    Je vais prendre l'exemple des modificateurs de caractéristiques...

    Un personnage, si je ne me trompe pas trop, n'as pas ses bonus/effets qui sont modifiés sans arrêt. On peut donc re-calculer tous les résultats des effets à chaque changements d'équipement/effets. Et ensuite simplement l' ajouter aux caracs du personnage de base.

    je vais faire un exemple, ça ser asans doute plus simple :

    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
     
    /* Caractéritsiques de base d'un personnage */
    struct Caracs
    {
        int str, dex, cons;
    };
     
    class Effect
    {
        virtual Caracs getModifiers() = 0;
    };
     
    class EffectList
    {
        std::vector<Effect> m_effectList;
     
        Caracs getModifiers()
        {
            Caracs result;   
            for (int i = 0; i < m_effectList.Count(); ++i)
            {
                result += m_effectList[i].getModifiers();
            }
            return result;
        }
    };
     
    class Personnage
    {
       Caracs baseCaracs, effectsCaracs;
     
       Caracs getCaracs()
       {
           return baseCaracs + effectCaracs;
       }
    };
    Voilà, j'espère que c'est assez clair, mais c'est a peu près ce a quoi j'ai pensé en lisant ton truc.

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    100
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 100
    Points : 150
    Points
    150
    Par défaut
    Citation Envoyé par bibi.skuk Voir le message
    Je vais prendre l'exemple des modificateurs de caractéristiques...

    Un personnage, si je ne me trompe pas trop, n'as pas ses bonus/effets qui sont modifiés sans arrêt. On peut donc re-calculer tous les résultats des effets à chaque changements d'équipement/effets. Et ensuite simplement l' ajouter aux caracs du personnage de base.

    je vais faire un exemple, ça ser asans doute plus simple :

    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
     
    /* Caractéritsiques de base d'un personnage */
    struct Caracs
    {
        int str, dex, cons;
    };
     
    class Effect
    {
        virtual Caracs getModifiers() = 0;
    };
     
    class EffectList
    {
        std::vector<Effect> m_effectList;
     
        Caracs getModifiers()
        {
            Caracs result;   
            for (int i = 0; i < m_effectList.Count(); ++i)
            {
                result += m_effectList[i].getModifiers();
            }
            return result;
        }
    };
     
    class Personnage
    {
       Caracs baseCaracs, effectsCaracs;
     
       Caracs getCaracs()
       {
           return baseCaracs + effectCaracs;
       }
    };
    Voilà, j'espère que c'est assez clair, mais c'est a peu près ce a quoi j'ai pensé en lisant ton truc.
    Ok, si j'ai bien compris, c'est une sorte de valeur cache pour éviter de tout recalculer a chaque appel. Je suis d'accord sur le principe, c'est ce vers quoi on allait se tourner pour l'optimisation. Mais pour le moment, on reste bloqué dans notre systeme d'effet, et on ne sait pas comment le designer. En tout cas, merci pour ta réponse

  4. #4
    Invité
    Invité(e)
    Par défaut
    Comme ton effet donen un bonus de caracéristiques, je ferai une simple fonction qui te donne les bonus de ton effet, comme ça après, tu somme le tout, c'est simple, et tu n'as pas de problemes, une sule fonction à deriver a chaque fois, qui fait juste ce qu'il faut, pas besoin d'avoir 25 fonctions qui ne font rien, ou alors une série de if partout, etc...

  5. #5
    Membre habitué
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    100
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 100
    Points : 150
    Points
    150
    Par défaut
    Citation Envoyé par bibi.skuk Voir le message
    Comme ton effet donen un bonus de caracéristiques, je ferai une simple fonction qui te donne les bonus de ton effet, comme ça après, tu somme le tout, c'est simple, et tu n'as pas de problemes, une sule fonction à deriver a chaque fois, qui fait juste ce qu'il faut, pas besoin d'avoir 25 fonctions qui ne font rien, ou alors une série de if partout, etc...
    Il faut bien trier un effet bonus PV d'un effet bonus de caracteristique, non ?

    Si je fais

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    class Effet
    {
        public:
           getModifier();
    };
    Si j'appelle getModifier() sur tous les effets que j'ai en actif sur mon perso, il va additionner aussi bien des bonus de caracs que des bonus de PV, etc, etc. Ou alors j'ai compris de travers ^^

  6. #6
    Futur Membre du Club
    Profil pro
    Inscrit en
    Juin 2007
    Messages
    7
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2007
    Messages : 7
    Points : 6
    Points
    6
    Par défaut
    Tu fait une map avec en clef une string qui est unique aux composantes du personnage.

    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 CComponents
    {
       map<String, int> mValues;
     
       operator +();
       operator -();
       operator ==();
       operator [];
     // etc...
    }
     
    class CCharacter
    {
      map<String, CComponents> mComponents
     
      CCharacter()
      {
         mComponents["States"] = /* la vie la mana, etc... */;
         mComponents["Skills"] = /* les compétences */;
         mComponents["Characteristics"] = /* somme des caractéristiques de tout les levels */
         mComponents["CharacteristicsLevel0"] = /* les caractéristiques du depart */;
    // etc...
      }
      updateComponents() //  mais a jour les Characteristics, les Skills, ou tout se qu'il faut.
     
      CComponents& getComponents(String);
      CComponents& getComponentsSum(); // Tu ajouts toutes les cases des  CComponents qui on les même clefs.
     
      delComponents(String name);
      addComponents(String name, CComponents c);
    }
     
    bob.getComponents("States")["PV"] // pour avoir la vie d'origine.
    bob.getComponentsSum()["States"]["PV"] // pour avoir la vie d'origine + les modificateurs.
    Voila un petit system flexible, et tu peux même revenir en arrière sur les levels vue que tu garde la progression. Pour ajouté un effet tu fait addComponents, pour le retiré tu fais delComponents. Avec tes effets tu peux joué sur le personnage. Tu peux aussi géré les bonus des objets etc...

    C'est pas très optimisé, ni très propres, mais il y a moyen très facilement de le faire quelque chose de correcte. De plus tu peux facilement faire un loader/saver XML, aussi bien pour les Personnage que pour les items, que pour la magies etc... Apres tu peux aussi gérer la duré des effets, mais bon, après ca c'est une autre histoire.

    Voilou.

  7. #7
    Membre éclairé
    Avatar de N_I_C_S
    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    450
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 450
    Points : 681
    Points
    681
    Par défaut
    Salut,
    Si j'ai bien compris (c'est pas sûr), je pense que tu peux utiliser le pattern Decorator pour avoir une démarche purement objet. L'idée est de rajouter ou modifier dynamiquement des comportements ( par ex. getPV() ) de toute une arborescence de classes (par ex. tous les types de persos) de manière très modulaire. Une classe Decorator representerait un effet, tu peux donc en ajouter autant que tu veux sans toucher au reste, les fabriquer selon les données d'un fichier, et même les cumuler. J'ai pas de liens mais ya plein de descriptions du pattern sur le net.

  8. #8
    Membre habitué
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    100
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 100
    Points : 150
    Points
    150
    Par défaut
    Citation Envoyé par Yellow.fr Voir le message
    Tu fait une map avec en clef une string qui est unique aux composantes du personnage.

    ...

    Voila un petit system flexible, et tu peux même revenir en arrière sur les levels vue que tu garde la progression. Pour ajouté un effet tu fait addComponents, pour le retiré tu fais delComponents. Avec tes effets tu peux joué sur le personnage. Tu peux aussi géré les bonus des objets etc...

    C'est pas très optimisé, ni très propres, mais il y a moyen très facilement de le faire quelque chose de correcte. De plus tu peux facilement faire un loader/saver XML, aussi bien pour les Personnage que pour les items, que pour la magies etc... Apres tu peux aussi gérer la duré des effets, mais bon, après ca c'est une autre histoire.

    Voilou.
    Vu ce que j'en lis, ca a l'air de correspondre à nos besoins. Je vais refaire ca avec mes besoins chez moi, mais il semblerait que ca pourrait coller Merci

Discussions similaires

  1. Réponses: 8
    Dernier message: 18/07/2005, 18h38
  2. [Débutant][Conception] Contrôler une application distante
    Par muad'dib dans le forum Général Java
    Réponses: 10
    Dernier message: 05/07/2005, 14h58
  3. Conception d'une base de donnees
    Par sara1983 dans le forum Décisions SGBD
    Réponses: 1
    Dernier message: 29/04/2005, 14h38
  4. [Conception] Passer une fonction en paramètre
    Par pejay dans le forum Langage
    Réponses: 9
    Dernier message: 09/12/2004, 13h58
  5. Conception d'une classe parente
    Par VincentB dans le forum Langage
    Réponses: 9
    Dernier message: 24/06/2003, 17h28

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