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:

——————– EN COURS DE TRADUCTION ——————
This is the typical way how can player traverse the dialogue tree. He can either ask about Weather or Book or he can ask about his colleagues which opens him a path to ask about specific colleagues and moreover Peter opens up way to some plot like elements.

Also we’d like to define some other rules to our dialogue. Weather is very stupid topic so we’d let our player as about it only once per the whole game. Marc and Dirac are not important for the story, so we’ll let the player ask about them only once per dialogue. Lastly “Book” topic will be opened to player only when Molly picks up the book.

So let’s get moving. We have to be familiar with a few new methods:

Game.AddResponse([response number], [response text]); adds a response to the response window.
Game.AddResponseOnce([response number], [response text]); adds a response to the window once per the current dialogue branch. Then the topic disappears until you leave the dialogue branch.
Game.StartDlgBranch(); is a method used when you want to start a dialogue branch for use with AddResponseOnce method.
Game.EndDlgBranch(); is a method used when you want to end a dialogue branch for use with AddResponseOnce method.
Game.AddResponseOnceGame([response number], [response text]); adds a response to the window one per the whole game.
Game.GetResponse(); Displays the prepared dialogue box, waits until player selects a response and returns the selected response number.

Because we want to keep our code clean, we’re going to use separate functions for all tree levels, we’ll call this functions “basic”, “Colleagues” and “Peter” to easily distinguish them.

But enough chit-chat, open up the sally.script and let’s keep moving. Erase everything in this file and leave there something like this:

#include "scripts\base.inc" 
 
on "LeftClick" 
{ 
  basic(); 
}

Good start, isn’t it? Well, we’re going to add something more obviously. Let’s start with the function basic();

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] = "Bye!"; 
 
	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]); // actor says the selected line first 
 
		switch (selected)  //we choose what to do based on the selected option 
		{ 
			case 0: 
				sally.Talk("Not really");	 
				break;	 
			case 1:  
				sally.Talk("Who exactly is of interest to you?");	 
				break; 
			case 3: 
				sally.Talk("See ya!");	 
				break;		 
		} 
	} 
	Game.Interactive = true; 
}

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.1319118177.txt.gz · Last modified: 2011/10/20 15:42 by Anto0085
Recent changes RSS feed Creative Commons License Driven by DokuWiki