10 septembre 2008

LSL avancé : la boite dialogue bleue

Comme promis, voici une petit tutoriel sur la petite boite de dialogue bleue qui apparait dans le coin supérieur droit de l'écran.
Cette fenêtre de dialogue est équipée de boutons permettant ainsi une interaction.

Il y a donc dans cette fenêtre 3 parties :
  • le message, le texte de la boite de dialogue, présentant les boutons, donnant une information, ....
  • des boutons (12 au maximum)
  • un bouton "ignorer", permettant de fermer la fenêtre sans rien faire

La fonction qui va permettre la création de cette boite est la fonction llDialog :

llDialog( key avatar, string message, list buttons, integer chat_channel );

  • avatar : le UUID de l'avatar qui verra apparaitre la boite de dialogue, sa clé
  • message : le message de la boite de dialogue
  • buttons : le texte des boutons, présenté sous la forme d'une liste
  • chat_channel : le canal où se fera la trasnmition de l'information

Mais pourquoi donc parler de cette boite de dialogue juste après avoir parlé du listen ??

Ben, justement... La fonction llDialog fait parler notre avatar, c'est là son mode de fonctionnement. Lorsque l'on clique sur un bouton, notre avatar parle sur le canal choisi et dit le texte du bouton. Ainsi, il faut pour traiter l'information qu'il y ait derrière quelqu'un a l'écoute !! Donc un événement listen.

Donc llDialog s'utilise conjointement avec llListen / Listen, et aussi llListenRemove, car il n'est pas nécessaire de garder l'écoute en fonction une fois le message transmis.

Nous avons donc les étapes suivantes :

  1. création de l'écoute : llListen
  2. ouverture de la boite de dialogue : llDialog
  3. réception et traitement du message : evenement listen
  4. suppression de l'écoute


Concernant les boutons....

Le texte des boutons doit être passé à llDialog sous la forme d'une liste. L'ordre des éléments de cette liste a son importance : elle détermine l'ordre des boutons.
Si deux boutons ont le même nom, le message transmis sera le même, donc notre script ne pourra pas savoir quel bouton a transmis ledit message. Donc attention à choisir des textes tous différents pour les boutons.

L'ordre des boutons par rapport aux éléments de la liste est le suivant :

9 - 10 - 11
6 - 7 - 8
3 - 4 - 5
0 - 1 - 2


Premier exemple : un menu simple

Nous allons travailler sur un objet tout simple : un cube. Lorsqu'on clique sur lui, il nous propose de lui changer sa couleur. Nous supposerons que nous avons une fonction qui fera ce changement de couleur.



key avatar; //l'avatar qui clique sur l'objet
integer ecoute;
integer canal = 123456;

list menu = ["rouge", "noir", "blanc"];
string message_menu = "Choisissez ma nouvelle couleur";



changer_couleur(string couleur){
//a ecrire, on change la couleur des faces du cube
}



default
{

touch_start(integer total_number)
{
avatar = llDetectedKey(0);
ecoute = llListen(canal, "", avatar, "");
llDialog(avatar, message_menu, menu, canal);
}


listen(integer channel, string name, key id, string message)
{
if ( message == "rouge" ) changer_couleur("rouge");
else if (message == "noir") changer_couleur("noir");
else if (message == "blanc") changer_couleur("blanc");
llListenRemove(ecoute);
}

}


Lorsqu'on touche l'objet, l'évènement touch_start est déclenché. on récupère la clé de l'avatar, on ouvre une écoute, en précisant cette clé : ainsi, seule celui qui a cliqué sera écouté.
On fait ensuite appel a la la fonction llDialog. On lui passe comme paramètre la clé de l'avatar, de manière a ce que ce soit lui qui voit s'ouvrir la boite de dialogue, le texte de la boite et la liste des boutons, ainsi que le canal.

Puis, quand un bouton a été choisi, le script intercepte le message grace à son ecoute : on traite l'évènement listen. Le message envoyé est le texte du bouton. On fait donc un teste sur les valeurs possibles avec une série de IF.
Si la valeur est correcte : on change la couleur.....

Puis, le travail ayant été fait, on supprime l'écoute.


Second exemple : menu et sous menus



Nous allons complexifier l'exemple précédent : nous avons cette fois beaucoup de couleurs, et nous voulons les trier par famille. Famille des rouges, des bleus, des verts.
Il nous faut donc 4 menus :
  • menu_principal : permet de choisir la couleur
  • menu_rouge : choix de la couleur ou retour au menu principal
  • menu_bleu et menu_vert, sur le meme principe que menu_rouge
Modifions le programme précédent :


key avatar; //l'avatar qui clique sur l'objet
integer ecoute;
integer canal = 123456;

list menu_principal = ["rouge", "bleu", "vert"];
string message_menu = "Choisissez ma nouvelle couleur";

list menu_rouge = ["vif", "magenta", "<<<", "sang"]; string menu_rouge = "Choisissez votre nuance de rouge : "; list menu_bleu = ["marine", "royal", "<<<", "cyan"]; string menu_bleu = "Choisissez votre nuance de bleu : "; list menu_vert = ["clair", "pomme", "<<<", "emeraude"]; string menu_vert = "Choisissez votre nuance de vert : "; changer_couleur(string couleur){ //a ecrire, on change la couleur des faces du cube } default { touch_start(integer total_number)
{
avatar = llDetectedKey(0);
ecoute = llListen(canal, "", avatar, "");
llDialog(avatar, message_menu, menu, canal);
}


listen(integer channel, string name, key id, string message)
{
//on traite le menu principal
if (message == "rouge") llDialog(avatar, message_rouge, menu_rouge, canal);
else if (message == "vert") llDialog(avatar, message_vert, menu_vert, canal);
else if (message == "bleu") llDialog(avatar, message_bleu, menu_bleu, canal);

//on traite pour le sous menu, le bouton <<< else if (message == "<<<") llDialog(avatar, message_menu, menu, canal); // les couleurs....
else if (message == "vif") {
changer_couleur("vif");
llListenRemove(ecoute);
}
else if (message == "magenta") {
changer_couleur("magenta");
llListenRemove(ecoute);
}
// on traite ainsi toutes les autres couleurs
// pour la derniere, on ecrit seulement else
// au lieu de else if
}

}



Ce script fonctionne comme le précédent : on capture la cle de celui qui a cliqué, on ouvre une écoute et on affiche la boite de dialogue, celle du menu principal.

Ensuite, en fonction de ce qui est cliqué, on agit de manières différentes :
  • si on est sur le menu principal, on affiche à nouveau la boite de dialogue, mais avec le menu couleur choisi
  • si on est sur un menu couleur et que le bouton de retour est pressé : on affiche à nouveau la boite de dialogue du menu principal
  • sinon : on est sur une couleur, donc on effectue la tache demandée

Un dernier conseil pour finir : dans certains cas, on a plusieurs copies du meme objet l'une près de l'autre. Et il ne faudrait pas que tous ces objets se parlent sur le meme canal : dans certains cas, cela peut provoquer des interractions. Imaginer : vous commandez l'allumage d'une lampe, et toutes les lampes s'allument !!

Pour cela ajouter ceci au début de l'état default :

state_entry()
{
canal = (integer)llFrand(-100000) - 10000;
}

Cela positionne le canal d'écoute sur une valeur aléatoire grande et négative. La plage de valeurs étant importante, la probabilité que deux objets obtiennent le même canal est quasi nulle.



Voila de quoi agrémenter vos objets de zoulies boites de dialogue, pour encore plus d'interactivité.
Si vous avez des questions, ou envie de voir ici d'autres tutoriels, n'hésitez pas. Je ferais de mon mieux.

Aucun commentaire: