WME offre des capacités de dialogue très puissant et ce chapitre traite de la façon comment vous pouvez mettre en œuvre des arbres de dialogue dans votre jeu. Nous allons utiliser notre dernier exemple où nous avons dans une même scène Molly et Sally.
Notre chapitre débute de la même façon que le précédent, avec la définition de ce qu'on appelle "boite de réponses". C'est l'interface dans lequel seront stocké les choix de dialogue que le joueur a pour bien communiqué avec les autres personnages.
Vous allez voir que c'est très similaire à la définition de la boite d'inventaire. Nous allons parler du fichier qui se trouve dans data\interface\responses.def et comme on l'a déjà vu, c'est affecté dans les gestionnaire de projet en tant que Response Window. (Fenêtre de réponse)
RESPONSE_BOX { FONT = "fonts\outline_white.font" FONT_HOVER = "fonts\outline_red.font"
Chemin vers le fichier Font utilisé pour les options de dialogues et pour les options de dialogues en surbrillance.(souris par dessus)
HORIZONTAL = FALSE
HORIZONTAL spécifie si les options de dialogue sont affichés horizontalement ou verticalement.
SPACING = 5
Combien de pixels devrait séparer les options?
AREA {40, 0, 800, 170}
Pareil que dans la boite d'inventaire, vous définissez la fenêtre dans laquelle vos options vont apparaitre.
WINDOW { X = 0 Y = 420 WIDTH = 800 HEIGHT = 180 BUTTON { TEMPLATE = "ui_elements\template\but.button" IMAGE = "ui_elements\arrow_up.bmp" TEXT = "" NAME = "prev" X = 0 Y = 0 WIDTH = 30 HEIGHT = 30 } BUTTON{ TEMPLATE = "ui_elements\template\but.button" IMAGE = "ui_elements\arrow_down.bmp" TEXT = "" NAME = "next" X = 0 Y = 150 WIDTH = 30 HEIGHT = 30 } } }
Là encore voyez qu'il y a une définition de fenêtre avec deux boutons (prev et next) qui sont les boutons de défilement. Si WME trouve des boutons nommé ainsi, il les utilisent automatiquement. Tous le positionnement (Absolu dans WINDOW et relatif dans BUTTONS, comme la boite d'inventaire).
Pour les autres options possible vous pouvez utiliser :
TEXT_ALIGN - Spécifie l'alignement des texte de ligne de réponse; Ça peut être aussi bien "left", "right" ou "center"; La valeur par défaut est "left"
VERTICAL_ALIGN - spécifie l'alignement vertical des réponses au sein de la zone de réponse (elle n'a aucun effet sur les éléments classés à l'horizontale); Ça peut être une des valeur suivante: "top", "center" ou "bottom"; La valeur par défaut est "bottom"
Bien sûr, vous pouvez, pour la fenêtre, utiliser le paramètre IMAGE qui définira une image de fond pour la boite de réponses. Je vais laisser à votre imagination pour l'instant et passons sur la manière dont le dialogue lui-même est construit.
Les dialogues dans WME sont entièrement scripté(mis dans un script) ce qui leur donnent une grande flexibilité. Vous pouvez faire ce que vous voulez, au milieu du dialogue vous voulez inclure une sequence cinematographique complexe, une vidéos, et j'en passe - Vous l'avez.
Mais retour à nos dialogue - Regardons un exemple d'arbre de dialogue que j'ai créé dans ce but:
C'est la façon typique dont le joueur peut parcourir l'arbre des dialogues. Il peut aussi bien parler du temps ou du livre ou il peut poser des questions sur ses collègues, ce qui lui fraye un chemin pour poser des questions sur certains collègues et par ailleurs Peter se fraye un chemin vers l'intrigue.
En outre nous aimerions définir quelques autres règles à notre dialogue. La météo est le sujet très stupide,donc nous allons laisser notre joueur poser qu'une fois un question a se sujet dans tout le jeu. Marc et Dirac ne sont pas important pour l'histoire, nous laisserons donc notre joueur leur demander qu'une seule chose par dialogue. Enfin le sujet "livre" sera ouvert au joueur seulement si Molly à ramassé le livre.
Allons-y. Nous devons nous familiariser avec quelques nouvelles méthodes:
Game.AddResponse([response number], [response text]); Ajouter une réponse dans la fenêtre des réponses.
Game.AddResponseOnce([response number], [response text]); Ajouter une réponse dans la fenêtre qu'une fois par branche dialogue en cours. Puis le sujet disparaît jusqu'à ce que vous laissiez cette branche de dialogue.
Game.StartDlgBranch(); est une méthode utilisée quand vous voulez commencer une branche de dialogue pour utiliser avec la méthode AddResponseOnce.
Game.EndDlgBranch(); est une méthode utilisée quand vous voulez terminer une branche de dialogue pour utiliser avec la méthode AddResponseOnce.
Game.AddResponseOnceGame([response number], [response text]); Ajoute une reponse dans la fenêtre qu'une fois pour tout le jeu.
Game.GetResponse(); Affiche la boîte de dialogue préparée, attend que le joueur choisisse une réponse et renvoie le numéro de la réponse choisie.
Parce que nous voulons garder notre code propre, nous allons utiliser des fonctions séparées pour tous les niveaux de l'arbre, nous allons appeler ces fonctions “basic”(de base), “Colleagues”(Collègues) et “Peter” pour les distinguer facilement.
Mais assez bavardé, ouvrez sally.script et nous allons continuer d'avancer. Effacer tout dans ce fichier et y laisser quelque chose comme ceci:
#include "scripts\base.inc" on "LeftClick" { basic(); }
Bon début, n'est ce pas? Bon, Nous allons ajouter quelque chose de plus évidemment. Commençons par la fonction basic();
function basic() { var options; options[0] = "Quel temps magnifique, n'est ce pas?"; options[1] = "Pouvez vous me dire quelque chose au sujet de vos collegues?"; options[2] = "A quoi sert ce livre?"; options[3] = "Au revoir!"; var selected; while (selected != 3) { Game.AddResponseOnceGame(0,options[0]); Game.AddResponse(1,options[1]); Game.AddResponse(3,options[3]); Game.Interactive = true; selected = Game.GetResponse(); Game.Interactive = false; actor.Talk(options[selected]); // L'acteur dit la ligne sélectionnée en premier switch (selected) //Nous choisissons quoi faire en se basant sur l'option selectionnée { case 0: sally.Talk("Pas vraiment"); break; case 1: sally.Talk("Qui vous intéresse exactement?"); break; case 3: sally.Talk("A plus tard!"); break; } } Game.Interactive = true; }
D'abord nous avons créé un tableau appelé options. C'est très utile, pas seulement pour garder le texte propre et dans un seul endroit, mais aussi parce que quand la valeur est sélectionnée, notre acteur peut facilement dire les mots que le joueur a sélectionnés.Puis vient la mécanique du dialogue. Le dialogue par lui même est une boucle, qui tourne jusqu’à ce que le joueur choisisse l'option 3 (au revoir). Donc à chaque parcours de la boucle, la boite de dialogue est recréée et le joueur peut choisir son option à nouveau.
Nous pouvons voir qu'à l’intérieur de cette boucle nous avons attribuer 3 réponses (nous n'avons pas résolu le problème du livre encore) et ensuite on met le jeu en mode interactif. Mais il était toujours interactif, alors pourquoi? Parce qu'on ne veut pas que notre joueur tourne en rond tout en discutant, donc nous mettons le jeu en mode interactif seulement pour les dialogues. Nous attendons la saisie du joueur et puis utilisons la logique Switch pour choisir la réponse.
Comme je l'ai déjà indiqué, vous pouvez faire n'importe quoi comme une réponse. Si vous avez décidé qu'après avoir choisit une certaine option le jeu se ferme inopinément directe vers le bureau, mettez simplement Game.QuitGame(); Mais venez pas vous plaindre si les joueur vous torture après.
Okay, voyons le problème du livre. Nous voulons que le joueur parle du livre seulement si il l'a pris. C'est vraiment très intuitif et c'est la combinaison des idées du chapitre précédent aussi. modifiez la fonction basic pour:
Game.AddResponseOnceGame(0,options[0]); Game.AddResponse(1,options[1]); if (actor.HasItem("book")) Game.AddResponse(2,options[2]); Game.AddResponse(3,options[3]);
Donc nous avons dis là, que seulement si l'acteur détient le livre dans son inventaire, cette option peut être ajouté a l'arborescence des dialogues. Sympa. Et bien sûr nous avons besoin de définir la réponse adaptée.
case 1: sally.Talk("Qui vous intéresse exactement?"); break; case 2: sally.Talk("Je sais pas mais ça a l'air vraiment sympa!"); break; case 3: sally.Talk("A plus tard!"); break;
J'espère que vous commencez à avoir sentir toute la chose. Mais que diriez-vous de passer au deuxième niveau? Nous avons décidé d'utiliser une fonction appelée colleagues pour cela, allons donc la faire.
modifiez la section case 1: pour avoir:
case 1: sally.Talk("Qui vous intéresse exactement?"); colleagues(); break;
Maintenant nous devons définir la fonction colleagues().
function colleagues() { var options; options[0] = "Marc?"; options[1] = "Peter?"; options[2] = "Dirac?"; options[3] = "Revenons à mes autres questions"; Game.StartDlgBranch(); // Nous allons démarrer une branche à cause de AddResponseOnce var selected; while (selected != 3) { Game.AddResponseOnce(0,options[0]); Game.AddResponse(1,options[1]); Game.AddResponseOnce(2,options[2]); Game.AddResponse(3,options[3]); Game.Interactive = true; selected = Game.GetResponse(); Game.Interactive = false; actor.Talk(options[selected]); switch (selected) { case 0: sally.Talk("C'était un héros de jeu d'aventure de science-fiction qui n'est jamais sorti."); break; case 1: sally.Talk("Le croiriez-vous? Peter a disparu."); sally.Talk("Nous avons tellement peur!"); break; case 2: sally.Talk("Étrange personnage. Tranchants comme un rasoir."); break; case 3: sally.Talk("Comme vous voulez."); break; } } Game.Interactive = true; Game.EndDlgBranch(); // On termine la branche là }
Donc, comme nous pouvons voir, C'est vraiment similaire à la méthode basic(). La principale différence c'est la combinaison StartDlgBranch / EndDlgBranch, définissant le début et la fin de la branche et nous permet, avec de la bonne fonction, de faire disparaitre le sujet de l'arbre quand on n'en a plus besoin (déjà lu).
Ok. Vous diriez que vous n'avez pas besoin de voir la dernière section en raison de l'analogie parfaite de ce que nous venons de voir là. Mais j'ai décidé d'y mettre un rebondissement!
Au tout début de ce fichier nous allons créer une variable globale appelée murderSuspect.
ainsi notre fichier commence par:
#include "scripts\base.inc" global murderSuspect;
Et maintenant nous pouvons mettre cette fonction appelée Peter:
function Peter() { var options; options[0] = "Quand avez vous vu Peter pour la dernière fois?"; options[1] = "Avait-il des ennemis?"; options[2] = "Revenons à mes autres questions"; var selected; while (selected != 2) { Game.AddResponse(0,options[0]); Game.AddResponse(1,options[1]); Game.AddResponse(2,options[2]); Game.Interactive = true; selected = Game.GetResponse(); Game.Interactive = false; actor.Talk(options[selected]); switch (selected) { case 0: sally.Talk("Il etait avec moi à la fête. Puis il est parti soudainement."); actor.Talk("C'est étrange. Vous trouvez pas?"); sally.Talk("Bien... Non... c’était... habituel."); break; case 1: sally.Talk("Non. Seulement cette fille stupide qui le matais."); actor.Talk("Une fille vous dites? Étiez vous jalouse ou quoi?"); sally.Talk("Jalouse! Moi??? De CETTE fille? Jamais!"); sally.Talk("D'ailleurs, je le tu..."); actor.Talk("QUOI???"); sally.Talk("Rien!"); murderSuspect = true; break; case 2: sally.Talk("Comme vous voulez."); break; } } Game.Interactive = true; }
La seule différence dans celle-ci est que nous avons défini une variable globale qui influencera quelque chose dans le jeu. C'est le fondement de la logique du jeu (parfois appelé «l'effet papillon" du jeu - Quelqu'un vous dis un morceau d'information et un tiroir sans aucun rapport dans une autre ville s'ouvre mystérieusement - Mais nous ne parlons pas des lacunes relatives à la conception du jeu, d'accord? D'accord???).
Le seul changement restant est pour la fonction basic(); Mais je vais mettre le script entier parce que je crois que vous est capable de la repérer facilement.
#include "scripts\base.inc" global murderSuspect; function Peter() { var options; options[0] = "Quand avez vous vu Peter pour la dernière fois?"; options[1] = "Avait-il des ennemis?"; options[2] = "Revenons à mes autres questions"; Game.StartDlgBranch() ; var selected; while (selected != 2) { Game.AddResponse(0,options[0]); Game.AddResponse(1,options[1]); Game.AddResponse(2,options[2]); Game.Interactive = true; selected = Game.GetResponse(); Game.Interactive = false; actor.Talk(options[selected]); switch (selected) { case 0: sally.Talk("Il etait avec moi à la fête. Puis il est parti soudainement."); actor.Talk("C'est étrange. Vous trouvez pas?"); sally.Talk("Bien... Non... c’était... habituel."); break; case 1: sally.Talk("Non. Seulement cette fille stupide qui le matais."); actor.Talk("Une fille vous dites? Étiez vous jalouse ou quoi?"); sally.Talk("Jalouse! Moi??? De CETTE fille? Jamais!"); sally.Talk("D'ailleurs, je le tu..."); actor.Talk("QUOI???"); sally.Talk("Rien!"); murderSuspect = true; break; case 2: sally.Talk("Comme vous voulez."); break; } } } Game.Interactive = true; Game.EndDlgBranch() ; } function colleagues() { var options; options[0] = "Marc?"; options[1] = "Peter?"; options[2] = "Dirac?"; options[3] = "Revenons à mes autres questions"; Game.StartDlgBranch() ; var selected; while (selected != 3) { Game.AddResponseOnce(0,options[0]); Game.AddResponse(1,options[1]); Game.AddResponseOnce(2,options[2]); Game.AddResponse(3,options[3]); Game.Interactive = true; selected = Game.GetResponse(); Game.Interactive = false; actor.Talk(options[selected]); switch (selected) { case 0: sally.Talk("C'était un héros de jeu d'aventure de science-fiction qui n'est jamais sorti."); break; case 1: sally.Talk("Le croiriez-vous? Peter a disparu."); sally.Talk("Nous avons tellement peur!"); break; case 2: sally.Talk("Étrange personnage. Tranchants comme un rasoir."); break; case 3: sally.Talk("Comme vous voulez."); break; } } Game.Interactive = true; Game.EndDlgBranch() ; } function basic() { var options; options[0] = "Quel temps magnifique, n'est ce pas?"; options[1] = "Pouvez vous me dire quelque chose au sujet de vos collègues?"; options[2] = "A quoi sert ce livre?"; options[3] = "Vous avez tué Peter!"; options[100] = "Au revoir!"; var selected; while (selected != 100) { Game.AddResponseOnceGame(0,options[0]); Game.AddResponse(1,options[1]); if (actor.HasItem("book")) Game.AddResponse(2,options[2]); if (murderSuspect) Game.AddResponse(3,options[3]); Game.AddResponse(100,options[100]); Game.Interactive = true; selected = Game.GetResponse(); Game.Interactive = false; actor.Talk(options[selected]); switch (selected) { case 0: sally.Talk("Pas vraiment"); break; case 1: sally.Talk("Qui vous intéresse exactement?"); colleagues(); break; case 2: sally.Talk("Je sais pas mais ça a l'air vraiment sympa!"); break; case 100: sally.Talk("A plus tard!"); break; case 3: sally.Talk("Oui! Et là je vais vous tuer tout pareil! *BLAM*"); Scene.FadeOut(1000,255,0,0,255); Game.QuitGame(); break; } } Game.Interactive = true; } on "LeftClick" { basic(); }
Seulement pour éviter toute confusion, Scene.FadeOut efface la scène en une couleur spécifique. Son utilisation est:
Scene.FadeOut(duration, red, green, blue, alpha);
ici nous laissons s'effacer pendant 1000ms (1 sec.), vers le tout rouge sans transparence.
Game.QuitGame(); Sort tout simplement du jeu vers Windows.
Bien sûr vous pouvez trouver le listing de se script dans le répertoire des ressources pour le chapitre 7.
Vous pouvez trouvez quelques méthodes à ce sujet que nous n'avons pas traité ici, dans la documentation de WME sous
Contents → Scripting in WME → Script Language Reference → Game Object in the section Responses / Inventory
Et ça conclu ce chapitre, mais ne vous en faites pas, Il y a beaucoup de choses passionnantes à venir.