Translations of this page:

This is an old revision of the document!
—-

7. Les Dialogues

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; 
}

——————– EN COURS DE TRADUCTION ——————
First we’ve created an array called options. This is very useful not only for the keeping texts tidy and in one place, but also because when the value is selected our actor can easily say the words player selected. Then comes the logic of the dialogue. The dialogue itself is a loop, which loops until player selects the option 3 (Bye). So every time the loop iterates, the dialogue box is recreated and player can choose again his options.

We can see that inside of this loop we first assign 3 responses (we didn’t solve the book issue yet) and then set the game to interactive mode. But it was already interactive, so why? Because we don’t want our player to roam around while chatting, so we set the game to interactive mode only for the dialogue selecting. We wait for the player’s input and then use the switch logic to choose the response. As I already outlined, you can do anything as a response. If you decided that after certain option game unexpectedly quits to the desktop, simply put there Game.QuitGame(); but don’t blame me if players torture you afterwards.

Okay, let’s deal with the book issue. We want player to speak about the book only when she takes it. It’s actually very intuitive and it’s combining the ideas of the previous chapter too. Modify the basic function to:

Game.AddResponseOnceGame(0,options[0]);	 
Game.AddResponse(1,options[1]);	 
if (actor.HasItem("book")) Game.AddResponse(2,options[2]);	 
Game.AddResponse(3,options[3]);

So we’re saying here, that only if actor holds a book in his inventory, this option should be added to the dialogue tree. Neat. And of course we need to define appropriate answer.

case 1:  
	sally.Talk("Who exactly is of interest to you?");	 
	break; 
case 2:  
	sally.Talk("I don't know but it really looks neat!");	 
	break; 
case 3: 
	sally.Talk("See ya!");	 
	break;

I hope you’re starting to get the feeling of the whole thing. But how about moving to the second level? We’ve decided to use a function called colleagues for it, so let’s do it.

modify the case 1: section to read:

case 1:  
	sally.Talk("Who exactly is of interest to you?");	 
	colleagues(); 
	break;

Now we have to define the colleagues() function.

function colleagues() 
{ 
	var options; 
	options[0] = "Marc?"; 
	options[1] = "Peter?"; 
	options[2] = "Dirac?"; 
	options[3] = "Back to my other questions."; 
 
	Game.StartDlgBranch(); //We’re starting a branch because of 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("He was a hero of a Sci-Fi adventure game which was never released.");	 
				break;	 
			case 1:  
				sally.Talk("Would you believe it? Peter went missing.");	 
				sally.Talk("We're so scared!");	 
				break; 
			case 2:  
				sally.Talk("Strange fellow. Sharp as a razor.");	 
				break; 
			case 3: 
				sally.Talk("As you wish.");	 
				break;		 
		} 
	} 
	Game.Interactive = true; 
	Game.EndDlgBranch(); //We end a branch here 
}

So as you can see, it’s really almost identical to the basic() method. The only main difference is the StartDlgBranch / EndDlgBranch combo, which defines the start and the end of the tree branch and provides us with the nice function of having topic disappeared from the tree when we don’t need it (already read it).

Okay. You’d say that you don’t need to see the last section because of the perfect analogy to what we’ve just seen here. But I’ve decided to put a plot twist in it!

At the very beginning of this file we’ll create a new global variable called murderSuspect.

So our file starts with:

#include "scripts\base.inc" 
 
global murderSuspect;

And now we can make this function called Peter:

function Peter() 
{ 
	var options; 
	options[0] = "Where was Peter last seen?"; 
	options[1] = "Did he have any enemies?"; 
	options[2] = "Back to my other 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("He was with me on the party. Then he suddenly left.");	 
				actor.Talk("That's strange. Don't you think?"); 
				sally.Talk("Well... No... It was ... usual.");	 
				break;	 
			case 1:  
				sally.Talk("No. Only that stupid girl who was hitting on him.");	 
				actor.Talk("A girl you say? Did you get envious or what?"); 
				sally.Talk("Envious! Me??? On THAT girl? Never!");	 
				sally.Talk("Besides I would kill hi...");	 
				actor.Talk("WHAT???"); 
				sally.Talk("Nothing!");	 
				murderSuspect = true; 
				break; 
			case 2:  
				sally.Talk("As you wish.");	 
				break;		 
		} 
	} 
	Game.Interactive = true; 
}

The only difference in this one is that we set a global variable which will influence something in the game. This is the key stone on the game logic (sometimes referred as a gaming "butterfly effect" – someone tells you a piece of information and completely unrelated drawer in another town suddenly mysteriously opens – but we’re not discussing game design related flaws, right? Right???).

The only remaining change is to the function basic(); but I’m going to post the whole script now because I believe you will be able to spot that easily.

#include "scripts\base.inc" 
 
global murderSuspect; 
 
function Peter() 
{ 
	var options; 
	options[0] = "Where was Peter last seen?"; 
	options[1] = "Did he have any enemies?"; 
	options[2] = "Back to my other 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("He was with me on the party. Then he suddenly left.");	 
				actor.Talk("That's strange. Don't you think?"); 
				sally.Talk("Well... No... It was ... usual.");	 
				break;	 
			case 1:  
				sally.Talk("No. Only that stupid girl who was hitting on him.");	 
				actor.Talk("A girl you say? Did you get envious or what?"); 
				sally.Talk("Envious! Me??? On THAT girl? Never!");	 
				sally.Talk("Besides I would kill hi...");	 
				actor.Talk("WHAT???"); 
				sally.Talk("Nothing!");	 
				murderSuspect = true; 
				break; 
			case 2:  
				sally.Talk("As you wish.");	 
				break;		 
		} 
	} 
	Game.Interactive = true; 
	Game.EndDlgBranch() ; 
 
} 
 
 
function colleagues() 
{ 
	var options; 
	options[0] = "Marc?"; 
	options[1] = "Peter?"; 
	options[2] = "Dirac?"; 
	options[3] = "Back to my other 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("He was a hero of a Sci-Fi adventure game which was never released.");	 
				break;	 
			case 1:  
				sally.Talk("Would you believe it? Peter went missing.");	 
				sally.Talk("We're so scared!");	 
				Peter(); 
				break; 
			case 2:  
				sally.Talk("Strange fellow. Sharp as a razor.");	 
				break; 
			case 3: 
				sally.Talk("As you wish.");	 
				break;		 
		} 
	} 
	Game.Interactive = true; 
	Game.EndDlgBranch() ; 
 
} 
 
 
function basic() 
{ 
	var options; 
	options[0] = "Nice weather, isn't it?"; 
	options[1] = "Can you tell me anything about your colleagues?"; 
	options[2] = "What's this book for?"; 
	options[3] = "You've murdered Peter!"; 
	options[100] = "Bye!"; 
 
	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("Not really");	 
				break;	 
			case 1:  
				sally.Talk("Who exactly is of interest to you?");	 
				colleagues(); 
				break; 
			case 2:  
				sally.Talk("I don't know but it really looks neat!");	 
				break; 
			case 100: 
				sally.Talk("See ya!");	 
				break;		 
			case 3: 
				sally.Talk("Yes! And now I'll kill you as well! *BLAM*");	 
				Scene.FadeOut(1000,255,0,0,255); 
				Game.QuitGame(); 
				break;						 
		} 
	} 
	Game.Interactive = true; 
} 
 
on "LeftClick" 
{ 
	basic(); 
}

Just to avoid confusion, Scene.FadeOut fades out the scene to specified color. It’s prototype is:

Scene.FadeOut(duration, red, green, blue, alpha);

and we let it fade for 1000 ms (1 sec.), to full red and no transparency.

Game.QuitGame(); simply exits the game to Windows.

Of course you can find the listing of this script in the resources folder for the chapter 7.

You can find a couple of related methods which we didn’t cover here in documentation under

Contents → Scripting in WME → Script Language Reference → Game Object in the section Responses / Inventory

And that concludes this chapter but don’t worry. There is a lor of exciting stuff to come.

 
fr/wmebook/ch7.1319120671.txt.gz · Last modified: 2011/10/20 16:24 by Anto0085
Recent changes RSS feed Creative Commons License Driven by DokuWiki