12-04-2013, 11:12 PM
(L'aveugle peut décrire les sons du feu d'artifices!)
Puisque tu pars d'un arbre, pourquoi ne pas modéliser cela en XML? Chaque noeud serait alors un dialogue (<dialog>) comprenant un sous-noeud avec les prérequis (<requires><require{1,n}></requires>), un autre sous-noeud avec le texte du dialogue (<text>Salutations joueur. J'ai perdu mon unique marteau. Je l'ai laissé en plein milieu du volcan, peux-tu aller le chercher?</text>) et enfin, un dernier noeud avec les évènements débloqués (<unlocks><unlock{0,n}></unlock>).
Ainsi, tu pourras utiliser Xpath pour récupérer tous les noeuds "dialog" dont les prérequis sont remplis. Ensuite, charge à toi de trouver comment ordonner ces noeuds (aléatoire, ou prépondérance de certains prérequis face à d'autres), puis tu choisis un seul de ces noeuds. Tu lis le texte (ou l'affiche à l'écran), et une fois le texte affiché, les "unlock" du "unlocks" sont débloqués, donc de nouveaux prérequis seront activés.
Pour les noeuds require/unlock, tu peux utiliser un modèle du genre <require name="rencontrer-le-joueur"/> et <unlock name="rencontrer-le-joueur"/>. Ainsi, le "dialog" qui contient le "require" ci-dessus ne pourras pas être lu si un "unlock" contenant le même nom n'a pas été rencontré avant (donc, au départ, tu ne pourras lire que les noeuds "dialog" qui n'ont aucun "require").
Vois-tu l'idée? Pour la mise en oeuvre, XSLT (j'suis ch**t avec XML/XSLT hein? :p) devrait t'aider. Il existe, je pense mais je n'en suis pas sûr, des interpréteurs javascript du XSLT. Sinon, tu peux très bien utiliser directement XMLHttpRequest pour récupérer le XML du dialogue, puis récupérer la XMLResponse pour traiter le XML comme un DOM document dans ton javascript (et avoir accès aux habituels children[...], getAttribute et getElementsBy...).
Enfin, pour complexifier, tu peux:
Avec cela, je pense que tu auras un système de dialogues assez robustes, facile à entretenir et à utiliser, qui pourra également se dérouler hors-ligne (une fois le XMl téléchargé, aucun appel au serveur n'est fait, sauf si tu le demandes explicitement). Enfin, tu pourras même traduire le jeu dans d'autres langues en traduisant les <text> de ton XML.
Note importante qui me vient à l'esprit:
Dans ce schéma, utilisant "<require>" et "<unlock>", la structure du XML serait:
Donc, on n'exploite pas le coté "arbre" du XML (à cause du <dialog{1..n}>). En d'autres mots, tu peux avoir des plusiques <dialog> qui seront débloqués (ils sont "enfants") après un autre <dialog>, mais de la même façon, un "<dialog>" possède plusieurs prérequis indépendants (plusieurs "parents"): ce n'est donc pas un arbre, mais un graph.
La structure "arbre pur" serait plutôt:
Ainsi, au début, seule la phrase "Salut joueur" peut être lue. Le jeu va donc la lire. Une fois lue, cela débloque 2 dialogues: "Comment vas-tu" et "Salut PNJ qui a perdu son marteau". L'un de ces deux dialogues est alors lu (au hasard?). Si le 1er est lu, cela débloque le contenue de "...1", si c'est le 2nd, cela débloque le contenu de "...2" etc.
Ce deuxième système est, à mon avis:
Toutefois, il évite d'avoir des risques de "bouclage" (une séquence de dialogue répétée à l'infinie). Dans le cas du graphe, si un dialogue A requière l'évènement B (qui a déjà eu lieu), que le joueur choisit C, et que C ne débloque aucun évènement, alors le dialogue A pourrait être re-lu.
Pour éviter cela, il te faudrait faire une "liste" des dialogues déjà lus, pour interdire leur re-lecture.
A mon avis, tu as matière à travailler maintenant :p Bonne chance.
(Qui osera me répondre tl;dr? O.O)
Puisque tu pars d'un arbre, pourquoi ne pas modéliser cela en XML? Chaque noeud serait alors un dialogue (<dialog>) comprenant un sous-noeud avec les prérequis (<requires><require{1,n}></requires>), un autre sous-noeud avec le texte du dialogue (<text>Salutations joueur. J'ai perdu mon unique marteau. Je l'ai laissé en plein milieu du volcan, peux-tu aller le chercher?</text>) et enfin, un dernier noeud avec les évènements débloqués (<unlocks><unlock{0,n}></unlock>).
Ainsi, tu pourras utiliser Xpath pour récupérer tous les noeuds "dialog" dont les prérequis sont remplis. Ensuite, charge à toi de trouver comment ordonner ces noeuds (aléatoire, ou prépondérance de certains prérequis face à d'autres), puis tu choisis un seul de ces noeuds. Tu lis le texte (ou l'affiche à l'écran), et une fois le texte affiché, les "unlock" du "unlocks" sont débloqués, donc de nouveaux prérequis seront activés.
Pour les noeuds require/unlock, tu peux utiliser un modèle du genre <require name="rencontrer-le-joueur"/> et <unlock name="rencontrer-le-joueur"/>. Ainsi, le "dialog" qui contient le "require" ci-dessus ne pourras pas être lu si un "unlock" contenant le même nom n'a pas été rencontré avant (donc, au départ, tu ne pourras lire que les noeuds "dialog" qui n'ont aucun "require").
Vois-tu l'idée? Pour la mise en oeuvre, XSLT (j'suis ch**t avec XML/XSLT hein? :p) devrait t'aider. Il existe, je pense mais je n'en suis pas sûr, des interpréteurs javascript du XSLT. Sinon, tu peux très bien utiliser directement XMLHttpRequest pour récupérer le XML du dialogue, puis récupérer la XMLResponse pour traiter le XML comme un DOM document dans ton javascript (et avoir accès aux habituels children[...], getAttribute et getElementsBy...).
Enfin, pour complexifier, tu peux:
- Ajouter un noeud "speakers", contenant des sous-noeuds "speaker". Chaque "speaker" possède un attribut (name) qui indique le nom du PNJ qui peut lire ce dialogue (c'est un genre de pré-requis spécial: le prérequis pour lire le dialogue, c'est que la personne qui parle doit être tel ou tel PNJ). Idem pour les dialogues que le joueur peut utiliser: "speaker" peut voir son "name" définit à "player" si le joueur a le droit de lire ce dialogue (note que, pour le joueur, tu vas récupérer une liste de dialogues possibles sur la abse des <requires>, et laisser le joueur faire son choix dans cette liste de dialogues: ce n'est pas à toi de choisir pour le joueur, contrairement au PNJ où tu DOIS choisir; enfin, si le joueur n'a aucun "dialogue", tu peux passer directement son tour, tu n'auras donc pas une alternance forcée entre PNJ et joueur)
- Ajouter un noeud "date", qui te permet de mettre en place un système d'expiration du dialogue: si le dialogue entre les deux joueurs a duré plus de X secondes ou minutes (ou s'il y a eu plus de X échanges c'est à dire plus de X <dialog> lus, alors ce <dialog> possédant un <date> ne pourra plus être lu, ou à l'inverse, il ne pourra être lu qu'après ces X échanges ou X secondes). <date> serait alors une sorte de prérequis basé sur le temps, et non sur les évènements.
Avec cela, je pense que tu auras un système de dialogues assez robustes, facile à entretenir et à utiliser, qui pourra également se dérouler hors-ligne (une fois le XMl téléchargé, aucun appel au serveur n'est fait, sauf si tu le demandes explicitement). Enfin, tu pourras même traduire le jeu dans d'autres langues en traduisant les <text> de ton XML.
Note importante qui me vient à l'esprit:
Dans ce schéma, utilisant "<require>" et "<unlock>", la structure du XML serait:
<root>
<dialog><!-- 1 .. n -->
<requires>
<require name=""/><!-- 0 .. n -->
<text>blabla</text>
<unlocks>
<unlock name=""/><!-- 0 .. n -->
</unlocks>
</requires>
</dialog>
</root>
Donc, on n'exploite pas le coté "arbre" du XML (à cause du <dialog{1..n}>). En d'autres mots, tu peux avoir des plusiques <dialog> qui seront débloqués (ils sont "enfants") après un autre <dialog>, mais de la même façon, un "<dialog>" possède plusieurs prérequis indépendants (plusieurs "parents"): ce n'est donc pas un arbre, mais un graph.
La structure "arbre pur" serait plutôt:
<root>
<dialog author="PNJ">
<text>Salut joueur!</text>
<dialogs>
<dialog author="PNJ">
<text>Comment vas-tu?</text>
<dialogs>...1</dialogs>
</dialog>
<dialog author="J">
<text>Salut PNJ qui a perdu son marteau</text>
<dialogs>...2</dialogs>
</dialog>
</dialogs>
</dialog>
</root>
Dans ce schéma-arbre (qui me semble beaaaaucoup moins prétique et moins souple), seuls les <dialog> directement enfants de <root> sont accessibles au début. Une fois qu'un <dialog> est lu, seuls les dialogues contenus dans le <dialogs> peuvent être lus.Ainsi, au début, seule la phrase "Salut joueur" peut être lue. Le jeu va donc la lire. Une fois lue, cela débloque 2 dialogues: "Comment vas-tu" et "Salut PNJ qui a perdu son marteau". L'un de ces deux dialogues est alors lu (au hasard?). Si le 1er est lu, cela débloque le contenue de "...1", si c'est le 2nd, cela débloque le contenu de "...2" etc.
Ce deuxième système est, à mon avis:
- Plus facile à mettre en place grâce au coté "arbre"
- Moins sympatique à entretenir (pas de possibilité de faire rejoindre deux branches de l'arbre)
- Moins sympatique à utiliser en tant que joueur (si on choisit un dialogue donné, on sait qu'on ne pourra plus tomber sur certaines autres phrases)
Toutefois, il évite d'avoir des risques de "bouclage" (une séquence de dialogue répétée à l'infinie). Dans le cas du graphe, si un dialogue A requière l'évènement B (qui a déjà eu lieu), que le joueur choisit C, et que C ne débloque aucun évènement, alors le dialogue A pourrait être re-lu.
Pour éviter cela, il te faudrait faire une "liste" des dialogues déjà lus, pour interdire leur re-lecture.
A mon avis, tu as matière à travailler maintenant :p Bonne chance.
(Qui osera me répondre tl;dr? O.O)