30 septembre 2008

Mon petit dojo (3)

Après avoir eu une vision extérieure, passons à une vision plus intérieure... Sans vouloir faire de jeu de mots
Il se compose de deux étages :

  • une coursive fait le tour de la zone de pratique du sabre qui se trouve en bas... Elle donne accès à trois pièces : 


    • le balcon, qui permet d'accéder au toit

    • une salle de méditation aux parois de verre semi transparent

    • une salle (à aménager selon ses gouts)


  • la pièce du bas  très haute, permettant ainsi des jumps sans se cogner la tete. Un petit tp permet de remonter.







Quelques vues de la salle de méditation... qui a été aménagée






Pour finir deux vues générales, avant de refermer le dossier "Dojo".... Et de pouvoir y méditer ou s'y entrainer à la pratique du Sabre suivant les règles du respects et de l'honneur...







Bonne semaine à tous....

26 septembre 2008

Mon petit dojo (2)

Continuons la présentation des quelques photos de mon "petit dojo"....
Pour faire suite au post d'hier.
Donc après avoir vu quelques vues générales du dojo flottant.. voici des vues de près.




Promenons-nous sur le toit...
Certaines branches de l'arbre dépassent, permettant ainsi aux bulbes luminescents d'éclairer le petit jardin...
On peut aussi y voir mes colonnes d'entrainement... Sur SL, il y a par dessus les valeurs de "hit" et de "colision". Mais quand je prends une photo, je supprime tous ces trucs la... alors ben forcément, on ne voit rien.. ^_^



Tournons légèrement la tête... et voila, le petit abri surmonter du très beau dragon de chez Grendels ! Le soleil se couche, on irait bien s'alonger sur les coussins, pour profiter du beau temps ( c'est vrai que sur SL, il fait toujours beau !!)




Retournons nous...un petit coin dans le fond, avec une arche végétale....



Et voila le toit dans sa totalité. Il manque juste le petit bout avec l'escalier pour descendre.


Il y a pas a dire, mais SL est formidable pour créer et bâtir des univers oniriques... On crée, on anime, et ensuite, on peut se promener et utiliser ses créations....




25 septembre 2008

Mon petit dojo

Pour changer une peu des cours de scripts, et revenir un peu au Zen, je vous presente ici mon dernier travail de build.
Il s'agit d'un "petit" dojo, avec tout le confort et les installations nécessaire à ce qu'il soit opérationnel.

Dojo... lieu d'éveil.... tu te dois d'être beau et adapté pour cela.


Et quand je dis petit...
  • base : 60m x 60m
  • hauteur : 30m
  • 110 prims...


Il est composé de deux parties :
  • le dojo en tant que tel
  • l'arbre-fondation

Je tiens ici à remercier une des plus exceptionnelles buidleuses de SL : Oumani. Je lui dois les sculpties qui ont servi a réaliser l'arbre, mais surtout, une grande partie de ce que je sais en build.
Elle m'a donné les bases, et quelles bases !!! Elle m'a aussi transmis un peu de sa touche "onirique", qui rend ses créations si belles...
La première fois que Ouma m'a montré ce qu'elle faisait, je suis devenue muette devant tant de beauté, et ceux qui me connaissent savent que, me faire taire, est un grand exploit !!
Ce jour la, j'ai émis l'idée, l'envie, d'etre capable un jour d'en faire autant. Le chemin est encore long pour cela, mais j'ai commencé à y faire mes premiers pas.
Et Ouma m'y encourage....


Je remercie aussi Nounours, qui a poursuivi ma formation et qui m'a appris à économiser les prims ^_^ .
De plus, elle m'a permis de m'exprimer en créativité sur une sim merveilleuse mais destinée à mourir dans peu de temps.... Savoir que tant de beauté va mourir, cela me blesse profondément, mais ce qui a été réalisé là, fait partie de ce que j'ai vu de plus beau sur SL, et fait aussi.
Merci a toi de m'avoir permis de faire mes premiers builds... quand toute timide encore, sachant rezzer avec fierté un beau cube en bois, tu m'as encouragé à en faire une jolie table de pierre. Ta confiance m'honore.
Merci aussi de m'avoir inculqué a coup de masse dans ma tete dure de bonnes praqtiques de scripting. Et de m'avoir guidé lors de mes premiers pas en ce domaine.

Et j'attends avec une impatience non dissimulée, le jour où, avec toi et Ouma, toutes les trois, il nous sera donné à nouveau la chance de builder dans sa totalité une sim... Pour que naisse à nouveau la beauté et le rêve.


Je tiens à remercier aussi ma Yoyo.... qui sait voir tous les petits détails, qui font d'un objet tout simple, une chose belle, car complète.
Toi qui passe après moi, et qui me montre tout ce qui n'est pas ajusté au mm, les textures décalées de presque rien, qui me dit que ca, c'est pas assez détaillé, donc ca fait pas vrai....
Sans toi, je ferais encore du build approximatif.... Avec des murs aux textures où on se dit que.... on voit le motif qui se répète là, là et là encore... et que ca fait pinpin en somme....
Quand tu me dis que maintenant ca va... je sais que ca doit etre vachement bien ^_^.
Que ma cabane de planches pourries est si réaliste que, ca donne envie d'y vivre. hihi !!



Mais revenons a nos moutons....
Le dojo se compose de plusieurs partie :
  • un balcon pour y regarder le jour se lever, prendre l'air, et monter sur le "toit"
  • une salle de méditation, avec vue sur le ciel
  • une salle à aménager à sa convenance
  • un zone de pratique du sabre assez grande et surtout haute, permettant les jumps sans se cogner au plafond, ou perdre de vue son adversaire, par ce que la caméra en mouselock est collée au plafond
  • le toit : avec un lieu de détente habité pourvue de coussins moelleux, etune grande surface libre ou on pourra poser divers instruments d'entrainement.

A noter que ce dojo n'est pas poser sur le sol mais flotte dans les airs.. En effet, il est bâtît dans les branches d'un arbre étrange et merveilleux, dont les bulbes luminescents diffusent une douce lumière la nuit.

Si vous êtes intéressé par ce dojo, contactez moi, il est à vendre !! pour la somme de 2000 L$. Il est livré avec un appareil d'entrainement : 5 colonnes alignées entre lesquels on peut apprendre à se déplacer et bien plus encore, les colonnes indiquant les nombres de frappes et de collisions. Les coussins pour se relaxer ou méditer sont offerts sur simple demande :)).....


Les grands discours sont ennuyeux, passons un peu a quelques images...



Vue générale du dojo, avec "l'arbre"



La base de l'arbre... et ses bulbes lumineux



Vue du haut... on peut y voir le jardin, les piliers pour s'entrainer et une beau dragon sur le toit....
Le dragon n'est pas de moi, j'attends le jour où je saurai faire avec la aussi une grande impatience.
Le dragon est de chez Grendels, sur la sim Avaria.... Un conseil : courrez la-bas visiter la sim et dépenser vos L$ à la boutique. Votre porte monnaie ne fondra pas et vous rentrerez chez vous avec de si belles choses !!

D'autres photos encore demain....

18 septembre 2008

Cours d'initiation au langage LSL (III suite)

après la structure de contrôle IF la dernière fois, continuons ce cours d'initiation au LSL.
Aujourd'hui : les structures de contrôle (suite et fin) et les fonctions.



I. Les structures de controle


1) La boucle WHILE


Cette structure permet de répéter une série d'instructions tant qu'une condition n'est remplie.

while(condition){
instruction1;
instruction2;
....
}


Exemple : Parcourons les entiers de 1 à 10, et indiquons s'ils sont pairs ou impairs.


integer n = 1;
// on commence à 1.
// on définit la variable à parcourir
// et on l'initialise de suite

while ( n <= 10 ){ if (n%2 == 0){
llSay(0, "le nombre "+ n + " est pair");
}else {
llSay(0, "le nombre " + n + " est impair");
}
n++;
}

Voyons dans le détail ce que fait ce bout de code. On définit tout d'abord une variable n = 1, que l'on va parcourir.
Entrée dans la boucle : on teste n. Est-il plus petit que 10 ? Oui. On traite les instructions.
On calcule n%2 qui vaut 1..... donc on exécute le code du ELSE : on écrit : le nombre 1 est impair.
Ensuite, on incrémente n de 1....Fin de la boucle.

On recommence : test ( n <= 10 ?) ...oui => n%2 = 0 donc on ecrit : le nombre 2 est pair. Incrément de n... n vaut 3.
Et on recommence.... jusque n = 11.
Lors du test, la condition n <= 10 est fausse. On n'exécute donc pas le code qui suit, et on sort de la boucle. L'instruction n++ est extrêmement importante. Imaginons qu'on l'oublie. Le nombre n ne varie pas. Le test de la condition est toujours vrai, donc le code s'exécute sans fin, puisque a chaque nouvelle boucle, on teste le meme nombre. Nous sommes dans le cas d'une boucle infinie. Le programme boucle sans fin. Notons aussi que avant de démarrer une boucle, le programme effectue un test. Donc que si on parcourt les entiers de 1 à 100, 100 tests sont effectués. Dans le cas où on ne souhaite faire que une boucle un certain nombre de fois bien défini, il existe une autre structure de controle plus adéquate. Ici, aucun risque de boucle infinie, puis qu'il n'est pas nécessaire d'incrémenter une variable. Passons tout de suite à cette structure :

2) La boucle FOR

Sa structure est la suivante :

for(nom de la variable et affectation; condition de fin; incrément){
instruction1;
instruction2;
....
}

  • Nom de la variable et incrément : on précise la variable et sa valeur initiale

  • Condition : la contrainte qui est excercée sur cette variable. Dans le même genre que celle du WHILE.

  • Incrément : le pas d'incrémentation de la variable.

Reprenons l'exemple précédent avec une boucle FOR :

integer n;// l'initialisation n'est pas nécessaire

for( n = 1 ; n <= 10 ; n++){ if (n%2 == 0){
llSay(0, "le nombre "+ n + " est pair");
}else {
llSay(0, "le nombre " + n + " est impair");
}
}


Notons aussi que l'incrément n'est pas obligatoirement 1... Par exemple, comptons de 2 en 2 jusque 10 :

integer n;
for( n = 0 ; n <= 10; n+=2){ llSay(0; n);
}

on peut aussi bien sur compter à l'envers.... de 10 à 0 par saut de 2....

integer n;
for( n = 10 ; n >= 0 ; n-=2){
llSay(0; n);
}



3) Encore ??


Il existe encore deux autres structures.... le DO...WHILE et le JUMP. Mais je n'en parlerai pas. Pourquoi ?

Le DO ... WHILE fonctionne de la même manière que le WHILE, sauf que le test s'effectue à la fin et non pas au début. Ainsi, quel que soit le résultat du test, la série d'instructions de la boucle est effectuée au moins une fois. Cette structure, présente dans beaucoup de langage, est finalement très peur utilisée.

Le JUMP permet de "sauter", de faire un saut directement à une autre partie du programme. Même si cela peut parfois s'avérer pratique, cette instruction n'est utilisée que par ceux qui n'y connaissent rien à l'algorithmique, et programment comme des gougnafiers !!
Le code est alors illisible, et, même si il parait plus facile de faire des jumps plutot que de coder proprement, dans le maintient et la correction d'un code, l'utilisation du jump rend le code ingérable. Donc à fuir absolument !!



II. Les fonctions


Elles sont de deux sortes : celles qui font partie de l'API du LSL, et que l'on peut utiliser directement, et celles que l'on écrit soi même avec ses petites mains.


1) Les fonctions LSL

Elles se reconnaissent car elles commencent toujours par ll. Par exemple la fonction llSay deja rencontrée. Je détaillerai dans le prochain cours les fonctions LSL indispensables à connaitre.


2) Les fonctions que je code avec mes mimines à moi

Pour pouvoir utiliser ces fonctions, il faut tout d'abord les définir. Une fonction est une portion de code, qui effectue une serie d'instructions. Elle peut prendre des paramètres en entrée ou non. Elle peut retourner un résultat ou non.
Certains langages (mais pas le LSL) distinguent les deux, et appellent fonction quand il y a retour d'un résultat, et procédure quand il n'y en a pas.
Une fonction contenant une suite d'instructions, celles-ci peuvent etre d'autres fonctions, ou des fonctions LSL.

Notons tout de suite que la déclaration des fonctions se fait au début du script, généralement apres la declaration des variables globales.
D'où le squelette d'un script LSL (squelette définitif) :


//définition des variables globales


// Définition des fonctions personnelles


// un état du script : etat1

state etat1 {

evenement1(){
fonction1();
fonction2();
}

evenement2(){
fonction3();
fonction4();
}

}


Voyons tout d'abord une fonction sans paramètre; son squelette est le suivant :


ma_fonction(){
instruction1;
instruction2;
....
}


Par exemple, une fonction qui ecrit : "bonjour à tous !!" dans le chat....

dire_bonjour(){
llSay(0, "Bonjour à tous !!");
}


Lorsqu'on souhaite appeler cette fonction, il suffit d'écrire :

dire_bonjour();

Et c'est tout !!


Ensuite, une fonction avec paramètre. Son squelette est le suivant :


ma_fonction( type1 variable1, type2 variable2, ...){
instruction1;
instruction2;
....
}


Par exemple :

dire_bonjour2(string nom){
llSay(0, "Bonjour " + nom + " !! Comment vas tu ?");
}


Lorsqu'on souhaite appeler cette fonction, il suffit d'écrire :

dire_bonjour2("Nounours");

Ce qui affiche : Bonjour Nounours !! Comment vas tu ?
(C'est vrai ça... Bonjour Nounours !! Tu vas bien ?? Oui j'espère !! )


Ou encore :

parite(integer i){
if (i%2 == 0){
llSay(0, "le nombre "+ i + " est pair");
}else {
llSay(0, "le nombre " + i + " est impair");
}
}

que l'on appellera de cette manière :

parite(25);


Une petite dernière avec plusieurs paramètres :

compare(integer i, integer j){
if ( i <=j ){ llSay(0, i + " est plus petit ou égal que "+ j);
} else {
llSay(0, i + " est plus grand que "+ j);
}
}


Et pour finir une fonction qui retourne une valeur, quelle est ou non des paramètres. Son squelette :


type ma_fonction(type1 variable1, type2 variable2, ...){
instruction1;
instruction2;
....
return valeur;
}


Prenons un exemple : une fonction qui fait la somme de deux entiers. Bon je sais, on peut le faire avec un simple +, mais enfin !! C'est qui le prof ici ?? Grrrrrr......

integer ajoute(integer i, integer j){
return i+j;
}


On utilise cette fonction de la manière suivante :

integer h;
h= ajoute(10, 25);



III. Un peu de pratique


Dans son cours sur l'importance d'un bon algorithme, Nounours nous donne deux fonctions, écrites en langage algorithmique. Essayons de les ecrire en LSL. Je rappelle que l'une de ses fonctions est optimisée alors que l'autre non


1) La fonction non optimisée :

Je rappelle l'algorithme :

somme_entier_naturels_version1 ( n )
{
// Cette fonction va sommer tous les entiers de 1 à n (n étant un paramètre)
// On crée une variable résultat qui aura pour nom "somme"
somme = 0
POUR compteur DE 1 A n FAIRE
// On crée une variable compteur qu iprendra successivement
// les valeur entieres de 1 à n

// On fait la somme des entiers de 1 à n et on le stocke dans "somme"
somme = somme + compteur;

// Fin de la boucle "POUR", donc le programme restera dans cette boucle
// tant que compteur sera compris entre 1 et n.
// L'incrémentation de compteur se fait automatiqueemnt
// à la ligne "POUR compteur..."
FIN_POUR

// On retourne le résultat "somme" qui contient, grace à la boucle "POUR",
// la sommation des entiers de 1 à n
RETOURNER somme
}


Cela nous donnera en LSL :

integer somme_entier_version1(integer n){
integer somme = 0;
integer compteur;

for (compteur = 1; compteur <= n; compteur++){ somme = somme + n ;
// ou encore : somme += n;
}

return somme;
}



2) La fonction optimisée

Je rappelle l'algorithme :


somme_entier_naturels_version2 ( n )
{
// Cette fonction va sommer tous les entiers de 1 à n (n étant un paramètre)
// On sait que la somme des entiers naturels de 1 à n est une formule mathématique!
// http://fr.wikipedia.org/wiki/Somme_(arithm%C3%A9tique)
// somme = n * (n + 1) / 2
// Pourquoi ne pas réutiliser ce résultat?
// On crée une variable somme, et on lui met la formule!

somme = n * (n + 1) / 2

// Et maintenant, on retourne le résultat!
RETOURNER somme
}


Cela nous donnera en LSL :

integer somme_entier_version2(integer n){
integer somme;
somme = n * ( n + 1) / 2;
return somme;
}

On pourrait aller encore plus vite en écrivant directement :

return n * ( n + 1) / 2;




IV. Conclusion

Voilà, c'est tout pour aujourd'hui. Vous pouvez éteindre votre cerveau. La prochaine fois, je parlerai de certaines fonctions LSL, dont celles en rapport avec le type string, qui je le rappelle, ne concerne en rien le vêtement coupe-crotte très à la mode.
Ce prochain cours sera l'avant dernier dernier......

Non, pas d'inquiétude, je ne vais pas arrêter !! Mais puisqu'il s'agit d'un cour d'initiation au LSL, nous en avons fini. Nous passerons à des cours tout courts !!
Avec de vrais bouts de code utiles dedans.

11 septembre 2008

Cours d'initiation au langage LSL (III)

Plusieurs petites choses avant de commencer....

Lorsque je scripte, je ne le fais pas sur sl... j'utilise un logiciel, y écris mon code, puis hop, copier/coller dans sl.

Pourquoi ? Car le petit logiciel que j'utilise est très pratique, il y a autocomplétion du code, possibilité d'avoir accès à la page de wiki LSL de la fonction utilisée, et surtout, il y a un mode débug où je peux voir mon code tourner... une sorte de simulateur qui exécute mon code. Ultra pratique !!

Le logiciel : LSLEditor : http://www.lsleditor.org/

Dommage qu'il ne tourne que sous Zindowz (heurkkkk !! Linux power !!) et nécessite .NET Framework.
(note : je m'excuse auprès de mes lecteurs d'avoir écrit autant de gros mots en seulement une ligne)

Sinon, j'avais oublié de vous donner la page du wiki officiel de LSL : plein de docs sur toutes les fonctions, des exemples de codes, plein de bonnes choses : http://wiki.secondlife.com/wiki/LSL_Portal

Sur la page, en haut, la possibilité de choisir Français comme langage....

Bien passons aux choses sérieuses : le programme du jour.
Alors aujourd'hui : Les opérateurs, les structures de contrôles, affectations des variables



I. Les opérateurs mathématiques et l'affectation de variables numériques


Les 4 opérations mathématiques standards : + - * /
Il faut leur ajouter l'opération modulo %, qui donne le reste de la division entière.
En cas de calcul long, les priorités opératoires mathématiques sont appliquées. Si on veut les changer, l'emploie de parenthèses est indispensables.

Ainsi, on peut trouver :

integer i;
integer j;
i = 45;
j = 5;
i = i + j ;// maintenant i vaut 50 (= 45 + 5)
integer k = i/j;// k vaut 45/5 = 9
integer h = i % 10;// h est le reste de la division
// de 45 par 10.... donc h = 5
intger g = i - k*j;


Attention toutefois..... Les différents types de variables ne sont pas forcément compatibles..... Il faut dans ce cas les convertir (cast) l'un vers l'autre. Certains cast sont implicites, d'autres ne le sont pas du tout.

Exemple :

integer i = 50;
float j = i;// j vaut 50.0, 50 en valeur flottante, la conversion est implicite
// car il n'y a pas de perte de données
j = 50.36;
i = (integer)j;//conversion explicite car i vaut 50, partie entière de j.
// Ici, on perd de l'information. Donc il faut
// expliciter le cast.


Un dernier exemple piège dans lequel on tombe souvent :

float i = 2/3;


Si on demande la valeur de i... Qu'obtient-on ? On s'attend à 0.6666. Mais en fait i vaut 0 !!
Explication, je sens le mal de tête monter en vous....
2 et 3 sont des entiers.... on fait le calcul 2/3, avec des entiers, ce qui implique la division entiere qui vaut l'entier 0. Cet entier est ensuite casté en float implicitement et affecté a i. Donc i = 0.0 !!

Comment faire alors ?? Simplement écrire :

float i = 2.0/3.0;


2.0 et 3.0 sont des floats. La division est une division de floats, son résultat est donc le float 0.66666.
On affecte alors ce résultat à la variable i. CQFD !!


Oui M'dame !! C'est bien beau, mais si j'ai pas 2 et 3, mais deux variables entières k et l valant 2 et 3, et que je veux les diviser et avoir un résultat décimal ?? Je fais comment moi ? j'écris quand même pas k.0 et l.0 ??

Bien sur que non !!! M'enfin !!!
Dans ce cas, on cast explicitement : on caste chaque variables AVANT de faire la division !! Ainsi :

integer k = 2;
integer l = 3;
float i = (float)k / (float)l;


Donnons encore l'opérateur d'incrémentation et de décrémentation :

integer i = 5;
i++;// i++ équivaut à i = i+1; i vaut 6;
i--;// equivaut à i=i-1; i vaut 5


De même, pour éviter certaines formules trop longues :

integer i = 20;
i += 5;// équivalent à i = i+5;
i -= 5;// équivalent à i = i-5;
i *= 5;// équivalent à i = i*5;
i /= 5;// équivalent à i = i/5;
i %= 5;// équivalent à i = i%5;


Juste un dernier mot sur l'emploi du modulo %. A quoi peut-il servir ??

Par exemple pour convertir des secondes, en minutes et secondes :

integer t = 78;
integer min = 78/60;// 1 min
integer sec = 78%60;// et 18 sec

Ou encore pour connaitre la parité d'un nombre. Si un nombre i est pair, i%2 vaut 0, s'il est impair, i%2 vaut 1.
Car, tout nombre pair peut s'écrire sous la forme i = 2*n, et tout nombre impair sous la forme i = 2*n + 1. (pour n entier cela va de soi)




II. Les structures de controle


Note : j'utilise ici la fonction llSay. Elle permet à l'objet de parler sur un canal. Le canal 0 correspond au chat.



1) les conditions : IF.... [ELSE]

Cette structure permet de tester une condition, et d'exécuter des instructions si elle est vraie. Voir aussi d'en exécuter d'autres si elle est fausse.

if(la_condition){
instruction1;
instruction2;
} else {
instruction3;
instruction4;
}

La partie ELSE est facultative....

Je veux bien M'dame.... mais c'est quoi cette condition ?
Vous le faites exprès ou quoi ? La condition est ce que l'on teste.... Deux opérandes que l'on compare avec une opération de comparaison.

Par exemple :


i == 4 vrai si i vaut 4. Noter bien les deux ==
i > 4
i <>

Une opération de comparaison, ou plusieurs, avec des opérateurs logiques :
&& => ET, || => OU, ! => NOT


par exemple, je veux tester si i est compris entre 5 et 10....
Cela signifie que i est plus petit ou égal à 10 ET plus grand ou egal à 5. On écrira donc :

(i >= 5) && (i <= 10)


Par exemple :

if ((i >= 5) && (i <= 10)){ llSay(0, " Le nombre est compris entre 5 et 10");
}

ou encore

if ( i%2 ){
llSay(0, "Le nombre est pair");
}else {
llSay(0, "Le nombre est impair");
}


C'est tout pour aujourd'hui, vous pouvez aller prendre l'air, il fait si beau dehors ! Respirez à plein poumon.

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.

Initiation au langage LSL (II)

Bien après avoir vu les bases du LSL, allons un peu plus loin dans notre connaissance du langage.
Parlons un peu des différentes variables utilisables dans SL.


Notons tout d'abord que pour utiliser une variable, il faut l'avoir définie auparavant. Donc, on déclare une variable, on lui donne une valeur, et ensuite on l'utilise. Une variable se définit par deux paramètres : son type, qui définit quel type de données elle contiendra, et sa portée, qui définit à quel endroit du script elle pourra être utilisée.


I. Portée et définition d'une variable


Variables globales : elles sont accessibles à tout moment à l'intérieur du script. Leur portée est donc le script lui même.

Variables locales : elles sont définies à l'intérieur d'un bloc de code (délimité par des accolades). Elles ne peuvent donc être utilisées que dans ce bloc. Elles n'ont aucune existence en dehors de ce bloc. Si une variable locale a le même nom qu'une variable globale (c'est possible même si c'est un très mauvaise idée !! A éviter absolument), c'est la variable locale qui sera utilisée.

Variables paramètres : ces variables servent à définir les paramètres d'une fonction. Nous verrons cela en détail lorsque nous parlerons des fonction.

Les variables globales doivent être définies en début de script, avant même l'état default. Les variables locales sont définies dans le bloc de code où elles nous sont utiles, lorsque l'on en a besoin.

Pour définir une variable, il faut écrire son type suivit de son nom, et enfin un point virgule pour terminer l'instruction.
Par exemple :

integer un_entier;
string message;


Il est possible de donner une valeur à une variable au moment où on la définit. Ainsi, elle est initialisée dès sa création. Si on ne donne pas de valeur lors de la définition de la variable, le LSL lui donne une valeur par défaut : 0, pour les entiers, "" la chaine vide pour les chaines de caractères.

integer un_entier = 5;
string message = "Kikou !!!!";

En ce qui concerne le choix du nom de la variable, plusieurs points :
  • donner un nom qui a du sens, éviter les noms comme : truc, machin, bidule, toto, foo, bar, deirdre, ....

  • pas de caractères spéciaux dans le nom, ni d'espace : utiliser des lettres, des chiffres, ainsi que le underscore : _


II. Les différents Types du LSL


Le LSL est un langage fortement typé. C'est à dire que toute variable, pour pouvoir être utilisée, doit avoir été définie. Cette définition précise son type, c'est à dire le contenu qu'elle pourra recevoir.
On sera parfois obligé de convertir un type en un autre. Le transtipage, ou cast, est l'opération permettant de faire cela. Tout cela sera vu par la suite.

Voici les différents types de données pour le LSL :
  • integer: nombre entier, signé, codé sur 32 bits. Ex : 0, 6, -56
  • float: nombre flottant signé, un décimal en gros. Il doit s'écrire obligatoirement avec le point décimal et supporte la notation exponentielle. Ex : 0.0, 1.698, -6.25, 6.0E6, -6.3E-4
Notons au passage que si le float vaut 0, on doit écrire celui-ci 0.0, ou encore .0
  • string : chaine de caractères. Elle doit être délimitée par des guillemets. Ex : "Kikou !!"
Si la chaine doit contenir des guillemets, on les précède de \. Ex : "J'adore ce genre de \"bidule\". "
  • key : la key représente une chaine de caractères de format spécifique qui correspond à l'UUID, identifiant unique de tout objet sur SL.
  • vector : 3 floats réunis pour définir un vecteur. On encadre par <>. Ex : <0.0,0.0,0.0> pour le vecteur nul.
  • rotation : 4 floats réunis pour interpréter une rotation. Fonctionne comme le vector. Ex : <1.0,0.3,2.3,.2>
  • list : liste d'éléments hétéroclites. On encadre par [ et ]. Ex : [ 0, -52.6, "kikouu !!"]


III. Conclusion


Pour conclure, je vous conseille ardemment de commenter votre code, c'est à dire de laisser quelques petites explications renseignant sur ce qu'un bout de code fait, à quoi sert cette fonction, pour quoi il pleut encore aujourd'hui, Henri IV savait-il seulement faire du cheval...

Le texte écrit en commentaire ne sera pas interprété par le script. Pour commenter une ligne de texte, il suffit d'écrire // avant le texte à mettre en commentaire. Tout ce qui suit // sur la même ligne est ignoré par le script.
Exemple :

// Ouiiii !!! Ceci est votre premier commentaire !! bravo !!


Pour résumer, voici le squelette général d'un script, modifié par ce que nous venons de voir :

//Début du script - Définition des variables globales
string ma_chaine_globale; // commentaire sur ce que va contenir cette variable
integer un_entier_global; // commentaire sur ce que va contenir cette variable


// Définition des fonctions
// on verra ca plus tard....



// un état du script : etat1

state etat1 {

evenement1(){
fonction1();
fonction2();
}

evenement2(){
fonction3();
fonction4();
}

}


9 septembre 2008

LSL avancé : l'évènement listen

Avant de poursuivre les tutoriels pour les débutants en LSL, voici à la demande d'une amie un petit tutoriel sur l'évènement listen.


Comme tous les évènements, le listen se découpe en deux parties :

  1. On met en place une écoute, c'est a dire que l'on demande à notre script d'écouter.
  2. La gestion de l'écoute : dès que le script a entendu quelque chose, il fait appelle a l'évènement listen qui contient les instructions à effectuer.


Lancer une écoute


Cela se fait à partir de la fonction llListen :

integer llListen( integer canal, string nom, key id, string msg );


canal(integer) : le canal à écouter. Si on veut écouter le chat, on utilisera la constante PUBLIC_CHANNEL. En général, pour permettre le dialogue entre plusieurs objets, on utilisera un autre canal que ce dernier, pour éviter la saturation du script.

nom(string) : le nom de l'avatar, ou de l'objet, que l'on souhaite écouter. A condition bien sur qu'il parle sur le bon canal. Si on veut que notre script écoute tout sur un canal précis, on mettra comme valeur : "", soit la chaine vide.

id(key) : l'UUID de l'avatar, ou de l'objet. Même principe que pour le nom, sauf que là, on travaille avec l'UUID. Pour écouter tout le monde : on utilisera la clé vide : NULL_KEY.

msg(string) : un message particulier. Cela permet à notre script de déclencher l'évènement que si un message précis a été entendu.

A noter que l'appel à la fonction llListen renvoie un nombre entier qui référence l'écoute. Nous verrons plus loin à quoi cela peut servir.

Pourquoi mettre autant de filtres ?
Plus les filtres sont précis, et moins le script aura de travail à faire, donc moins de ressources consommées, ce qui allège la charge sur la sim.


Traiter l'écoute

Cela se fait avec l'évènement listen :

listen( integer channel, string name, key id, string message ){
//les instructions à effectuer...
}


parmi les paramètres que reçoit l'évènement listen, on trouve :

  • channel : le canal sur lequel se fait l'écoute
  • name, id : le nom et la clé qui ont été envoyé par llListen
  • message : le texte qui a été écouté




Premier exemple d'application

Le projet est de faire un objet perroquet, qui va répéter tout ce que je dis. On va donc se construire un perroquet (un bête cube pour aller plus vite).
Cahier des charges :
  • quand on clique sur lui, il écoute ce que dit son propriétaire.
  • Il répète ce qui est dit
  • si on lui dit : zut, il s'arrête



integer ecoute;
integer canal = PUBLIC_CHANNEL;
key avatar;


default
{

touch_start(integer total_number)
{
avatar = llGetOwner();
ecoute = llListen(canal, "", avatar, "");
}

listen(integer channel, string name, key id, string message)
{
if (message != "zut") llSay(canal, message);
else {
llSay(canal, "Je me tais à present...");
llListenRemove(ecoute);
}
}

}


Détaillons un peu ce code...

Lorsque l'on touche notre perroquet, on le met en route.... Il commence par récupérer l'UUID de son propriétaire, puis ouvre un canal d'écoute. L'UUID de l'avatar sert de filtre : il ne va pas écouter tout ce qui se passe sur le chat, mais seulement ce que son propriétaire dira. La fonction llListen renvoie un entier que l'on affecte a la variable ecoute, et qui correspond au numéro de l'écoute. Cela permettra ensuite de pouvoir supprimer cette écoute en question lorsqu'elle ne sera plus utile.

A chaque fois que le propriétaire parle dans le chat, le script déclenche un évènement listen. Si ce qui est dit est "zut", le perroquet annonce qu'il se tait (à la bonne heure). Puis il annule l'écoute (llListenRemove) : cela met le script en sommeil. Il faudra a nouveau cliquer sur le perroquet, pour lancer un nouvel évènement touch_star, qui initiera une nouvelle écoute.



Autre exemple


Imaginons cette fois-ci que nous avons chez nous plusieurs lampes. Nous avons des objets lampes, et un autre objet qui permet d'allumer ou d'éteindre toutes les lampes en même temps.

Comment cela va-t-il fonctionner ?

Nos lampes vont toutes avoir le même script : ce dernier sera à l'écoute d'un canal précis. Si on parle sur ce canal, la lampe s'allume ou s'éteint.
Nous avons aussi un autre objet "interrupteur". Lorsque l'on clique dessus, il donne l'ordre au lampe de s'allumer ou de s'éteindre.
Il va parler sur le canal choisi, et donner son ordre. Les lampes seront à l'écoute.

Donc deux scripts : un pour chacune des lampes, et un pour l'objet.


Script de l'interrupteur :


integer canal = -1234567;

default
{

touch_start(integer total_number)
{
llSay(canal, "clic");
}

}


A chaque fois que l'on clique sur lui, l'interrupteur dit "clic" sur le canal choisi (ici négatif : un avatar ne peut parler sur un canal négatif, on utilisera donc les canaux négatifs pour les dialogues d'objets par exemple)



Script pour les lampes :




integer canal = -1234567;
integer ampoule;


//fonction qui commandera allumage/extinction de la lampe
commande_ampoule(integer amp) {
//si amp == 0 : on éteint
//si amp ==1 : on allume
// à écrire donc..... je vais pas tout faire non plus :)
}


default
{

state_entry()
{
ampoule = 0;
llListen(canal, "", NULL_KEY, "clic");
}


listen(integer channel, string name, key id, string message)
{
ampoule = (ampoule + 1)%2;
commande_ampoule(ampoule);
}

}



A l'initialisation du script (state_entry), on donne à ampoule la valeur 0 ( 0 pour éteint, et 1 pour allumer). La variable ampoule représente l'état de l'ampoule. Puis on ouvre une écoute. On ne récupère une référence surcette écoute, car puisque la lampe sera toujours en attente d'un ordre, l'écoute ne sera jamais supprimée.
Par contre, l'écoute ne réagira que au mot "clic". Et sera sourd a tout autre.

Quand le clic retentit, l'évènement listen est lâché !! Tout d'abord, on change l'état de l'ampoule (on ajoute 1, et si le résultat est 2, on le passe a 0 ; tout cela est écrit avec modulo 2, qui permet de gérer plus proprement un état double).
Le nouvel état de l'ampoule est ensuite passé à la fonction commande_ampoule.... qui agit en conséquence.


Nous verrons dans un prochain tutoriel, l'utilisation de la tite boite de dialogue bleue, qui utilise l'évènement listen, raison pour laquelle j'ai tout d'abord commencé par lui.

8 septembre 2008

Lecon de Zen

Un petit texte du Maitre Zen Taisen Deshimaru.....
Que je laisse a votre méditation.

Si nous ouvrons les mains, nous pouvons recevoir toutes choses. Si nous sommes vides, nous pouvons contenir l'univers entier. Vide est la condition de l'esprit qui ne s'attache à aucune chose...


Meme si le lieu de méditation est exigu,
il renferme l'univers.
Meme si notre esprit est petit,
il contient l'illimité....


L'enseignement moderne donne la première place au discours, mais souvent les mots n'expriment pas la véritable pensée, ou l'attitude profonde. La parole est presque toujours incomplète. Lorsqu'elle trouve sa justesse, nous transmettons notre expérience "de mon coeur à ton coeur.


7 septembre 2008

Mystères insondables

Un petit texte de Carlos Castaneda, au sujet de la voie du guerrier. Le guerrier n'est pas un combattant brutal, mais juste quelqu'un qui cherche sa place parmis les mystères insondables du monde...


Le premier précepte de la règle,
c'est que tout ce qui nous entoure
est une mystère insondable.

Les deuxième précepte de la règle,
c'est que nous devons essayer
de découvrir ces mystères
même sans espérer y parvenir.

Le troisème, c'est qu'un guerrier
conscient du mystère qui nous entoure
et conscient de son devoir de tenter
de le découvrir, prends la place
qui lui revient parmis les mystères
et se considère comme l'un d'eux.

Par conséquent, pour ce guerrier,
le mystère d'être est infini
que cet être soit galet,
fourmi, ou sois même...

6 septembre 2008

Cours d'initiation au langage LSL (I)

Ce cours se veut une introduction au langage de programation de SL : le LSL (Linden Script Langage).
Lorsque j'ai commencé à apprendre le LSL, il m'a été difficile de trouver des tutoriaux de base, où on vous prend par la main pour faire vos premiers pas. Les tutoriaux qui vont suivre répondent à ce besoin.

"Je veux m'y mettre, mais tout ce que je trouve suppose que je sache déjà comment faire, pffffff, c'est galère !!" Si vous êtes dans ce cas, ne bougez pas, ce qui va suivre est pour vous !!
Si vous avez les bases, ben, ça va pas vous aidez beaucoup !!!


I. Premier pas
_______________

Un script LSL est un texte écrit avec un langage spécifique et compréhensible par SL pour provoquer des actions en réaction à des évènements; Par exemple :

  • ouvrir une porte quand on clique dessus
  • dire bonjour quand on clique sur un objet
  • animer l'avatar quand il s'assoit sur une pose ball
  • déclencher un effet pyrotechnique (les zoulis effets particules que j'aime tant) lorsque j'ecris dans le chat : Hello Nounours, et qu'un flot de bulles de lumière se rue sur Nounours pour l'entourer)

Ici les evènements sont :
  • le clic sur un objet, l
  • e clic droit > sit,
  • écrire dans le chat une phrase convenue.
Les actions sont :
  • un objet se déplace (la porte),
  • un texte est écrit dans le chat,
  • une animation agit sur notre avatar,
  • des particules fusent à tout va !!

Il faut donc un objet, et dans cet objet, un script. Quand l'objet est "soumis" à un évènement particulier, il provoque l'exécution du script qu'il contient.

Si un objet est constitué de plusieurs éléments (prims, ou primitives, c'est à dire des éléments 3D de base dont l'assemblage formera un objet complet), chaque élément peut contenir un ou plusieurs scripts.

Pour débuter, nous allons donc créer un simple objet, et lui associer un script.



II. Création d'un cube
_____________________


Pour réaliser cette étape, il faut avoir le droit de créer là où on se trouve. Si ce n'est pas le cas, des sandbox (bac à sable) existent pour cela.

1) faire un clic droit sur le sol, choisir Créer. Un cube apparait sur le sol. Notre premier objet est là !! Bravo !!

2) clic droit > Edition : une fenêtre apparait qui nous permet de modifier et d'agir sur notre objet. Comme notre but n'est pas le build (la construction d'objet SL), dirigeons nous tout de suite vers l'onglet qui intéresse le scripteur fou : Content, le contenu.

3) cliquer sur new script : la fenêtre de l'editeur apparait, avec le contenu du script créé. Notons qu'il n'est pas vide. Sur cette fenêtre de l'editeur, notons la case Running qui est à cocher. Si elle ne l'est pas, le script est désactivé.

4) chercher la ligne

llSay(0, "Hello, avatar");

5) remplacer par :

llSay(0, "Bonjour O inestimable splendeur !!");


6) chercher la ligne :

llSay(0, "Touched: " (string)total_number);

7) remplacer par :

llSay(0, "Vous venez de me toucher, O inestimable splendeur !!");

6) cliquer sur enregistrer. Si tout se passe bien, un petit message vous dit que la "compilation" s'est déroulée sans problème et que votre script ne contient donc pas d'erreur de langage.

7) fermer la fenêtre de l'éditeur de script, et celle de la boite d'edition de l'objet.


Nous avons là un cube contenant un script. Faisons un clic sur le cube. il nous parle dans le chat et nous dit : Vous venez de me toucher, O inestimable splendeur !!

Vous venez de réaliser votre premier script LSL !! Bravo !! Toutes mes félicitations !!

Rééditons l'objet et réouvrons le script pour l'étudier un peu et comprendre son fonctionnement.



III. Composition d'un script
____________________

Observons le contenu de notre script :


default
{
  state_entry()
   {
     llSay(0, "Bonjour O inestimable splendeur !!");
   }

   touch_start(integer total_number)
   {
     llSay(0, "Vous venez de me toucher, O inestimable splendeur !!");
   }
}


Ce script est composé d'un état nommé default, et il contient 2 évènements : state_entry et touch_start.


1) Qu'est-ce donc qu'un état M'dame ??

Je vous remercie de me poser la question. Un état est la situation dans lequel se trouve le script. Par exemple, une porte peut avoir deux états : ouverte ou fermée, un feu de circulation trois états : rouge, vert, orange.

Un script peut contenir plusieurs états, mais un seul état est actif à la fois. De même, il doit contenir un état default, qui est l'état dans lequel se trouve le script lorsqu'on le lance (la petite case running).

Si un script contient d'autres états, chacun devra avoir un nom distinct et devra commencer par le mot clé state, suivi du nom de l'état.


2) Et les évènements ?? Dites, hein M'dame ??

Un évènement est quelque chose qui va déclencher une action. Ici nous avons deux évènements.

state_entry est l'évènement qui est appelé lorsque l'on entre dans l'etat. A chaque fois que l'on entrera dans l'état, cet évènement sera appelé. Son action est : llSay(0, "Bonjour O inestimable splendeur !!"); ce qui provoque l'affichage du message : "Bonjour O inestimable splendeur !!" dans le chat.

L'évènement touch_start est appelé lorsque quelqu'un touche le cube, et cela à chaque fois qu'on le fera. Son action fera apparaitre dans le chat la petite phrase : "Vous venez de me toucher, O inestimable splendeur !!".

Un état doit toujours contenir au moins un évènement, sinon il ne sert à rien. De même qu'un script doit toujours contenir au moins un état.


3) llSay ???? C'est quoi ce truc ??

Un évènement doit toujours contenir l'appel à une fonction, sinon, one more time, il ne sert à rien, ne fait rien.
Bien sur, il peut contenir des appels à plusieurs fonctions, nous verrons ca plus tard.

Une fonction possède un nom, et des paramètres, c'est à dire des informations qu'on lui donne pour qu'elle travaille dessus.
Il existe deux types de fonctions : celles que l'on écrit soi même avec ses tites mains, et celles du langage LSL. On reconnait ces dernières car elles commencent toujours par ll.

Ici, la fonction appelée est llSay. On doit lui donner deux paramètres.

  • 0 : correspond au canal sur lequel doit être diffusé le message. Le canal 0 est celui du chat.
  • "Bonjour O inestimable splendeur !!" : le texte qui doit être écrit sur le canal 0. On remarque qu'il est ecrit entre "...". On appelle cela une chaine de caractères, ou encore une string (sans aucun rapport avec la ficelle coupe-crotte très à la mode).
L'appel à la fonction se termine par ; pour indiquer qu'on a terminé notre instruction.
Les paramètres sont écrit entre parenthèses.

Remarquons aussi que notre fonction est mise entre accolades : elles servent a définir le bloc d'instructions de l'évènement.
De manière général, les accolades serviront à délimiter un bloc.

Pour résumer, voici le squelette général d'un script :



state etat1 {

   evenement1(){
     fonction1();
     fonction2();
   }

   evenement2(){
     fonction3();
     fonction4();
   }

}


Et il peut y avoir, bien sur, plusieurs états........
Faire très attention à la ponctuation (; à la fin d'une instruction), aux majuscules : llsay et llSay sont deux choses différentes, le compilateur y est sensible. De même, si on ouvre une parenthèse, il ne faut pas oublier de la fermer.


Voila, c'est tout pour aujourd'hui. Cette première introduction au LSL est finie. Elle se veut simple, pour poser les bases du scripting.
Ah que n'ais-je eu cela lorsque j'ai commencé !!!

Le premier enjeu...

Je conseille à ce qui ne l'on pas encore vu (qu'ils se dénoncent tout de suite) ce film magnifque intitulé : HERO

Beau, poétique, une ode a la gloire du katana !! et à l'esprit du sabre, à la voie du sabre......
Accompagné d'une musique formidable....

Un extrait, qui explique bien ce qu'est la voie du sabre....

Le premier enjeu du maitre d'arme, est de ne faire qu'un avec son épée... Lorsque l'homme est dans l'épée, et l'épée dans l'homme, meme un brin d'herbe peut se révéler tranchant.


Le second enjeu est atteint lorsque l'épée, absent de sa main, reste présent en son coeur... Alors il peut terrasser son ennemi jusqu'à une distance de 100 pas.


L'ultime enjeu du maitre d'arme est de n'avoir d'épée ni à la main, ni dans le coeur... Alors le maitre d'arme ne fait plus qu'un avec l'univers. Il ne cherche plus a semer la mort sur son passage, mais l'amour dans le cœur des hommes


Paix et sérénité

5 septembre 2008

Pensée de maitre Zen

Pensée Zen ... tout simplement



Si nous ouvrons les mains, nous pouvons recevoir toutes choses. Si nos sommes vides, nous pouvons contenir l'univers entier. Vide est la condition de l'esprit qui ne s'attache à aucune chose.

Meme si le lieu de méditation est exigu, il renferme l'univers. Meme si notre esprit est petit, il contient l'illimité.....

Taisen Deshimaru

La voie du Sabre

Aujourd'hui, pour se préparer au Week End, voici un petit conte Zen... sur l'art du sabre !!

Asseyez-vous confortablement autour du feu, ou allongez vous et regardez le ciel Sleep .... Il fait beau, le ciel est dégagé, la voie lactée s'étend paresseusement au firmament.....
Vous y êtes ?? Alors commençons......



Un jeune et fougueux samouraï voulut un jour parfaire son art auprès du plus grand maitre de Kendo, la voie du sabre.

Il alla le voir et lui dit : "Maitre, enseignez moi la vrai voie du sabre".

Le vieux maitre lui répondit : Bien mon jeune élève... tu vois ce seau et cette hache ?? Va me chercher de l'eau à la rivière, et coupe moi du bois pour l'hiver.


Le jeune samouraï se mit au travail, sans broncher.... Au bout de 2 ans a ne faire que cela, il dit au vieux maitre : Mais enfin, depuis tout le temps que je suis chez vous, je n'ai fait que porter de l'eau et couper du bois, et jamais encore vous ne m'avez permis d'entrer dans votre dojo !!

Ce a quoi le vieux maitre répondit : Bien ! Je suis content de ton travail, suis moi dans le dojo...


Le jeune samouraï était content, son enseignement allait enfin commencer.

Il entra donc à la suite du vieux maitre dans le dojo. Le vieux maitre lui désigna le tatami et lui dit : regarde ce tatami... marche et fais en le tour en prenant bien garde de marcher juste sur le bord. Fais le consciencieusement et patiemment.

Puis le maitre se retira.



Le samourai fit l'exercice durant 1 an. Au bout d'un an, énervé, car il n'avait toujours rien appris sur la voie du sabre, il alla a nouveau trouver le vieux maitre et lui dit : Maitre ! Depuis que je suis arrivé, vous m'avez fait porter de l'eau, couper du bois et marcher le long du tatami, mais jamais encore vous ne m'avez enseigné la voie du sabre !!!


Le vieux maitre dit : Aujourd'hui je vais te donner ta dernière leçon... Suis moi dans la foret...


Ils partirent donc tous deux dans la foret, et finirent par arriver au pied d'un précipice. Un tronc d'arbre assez étroit enjambait le précipice... Au fond l'eau bouillonnait. Le jeune samouraï s'approcha du bord et regarda en bas.... puis il fit un pas en arrière : le gouffre était profond et la mort était assurée a celui qui y tomberait !!


Le vieux maitre dit : passe de l'autre coté, et va me cueillir cette fleur bleue que tu vois la-bas...


Le jeune samouraï hésita : mais maitre, c'est dangereux, je puis tomber et me tuer, cela serait dommage de perdre ainsi la vie pour une petite fleur bleue....


A ce moment la, de l'autre coté du précipice, apparut un aveugle qui se guidait avec un bâton.... il traversa sur le tronc, sans peur, et continua son chemin...


Alors le jeune samouraï comprit, il traversa sur le tronc cueillit la fleur et la ramena a son maitre...


C'est bien lui dit le maitre, maintenant tu n'as plus besoin de moi, tu as appris tout ce que je pouvais t'apprendre. Pendant 2 ans tu t'es forgé une musculature forte en portant des seaux, puis pendant un an tu as appris la précision, le geste juste, en marchant le long du tatami, et aujourd'hui tu as vaincu ta peur de mourir. Tu as été au bout de la voie, elle est en toi à présent.


Le samouraï s'inclina devant son maitre en signe de respect.




Voila, c'est tout pour aujourd'hui, vous pouvez fermer vos paupières et aller faire dodo Sleep


4 septembre 2008

Sagesse éternelle...

Petite pensée du jour........
Je la laisse là, au regard de tous, puisse-t-elle vous réchauffer le cœur.....
Le sage ne doute pas..... et je connais des personnes très sages, car elles suivent leur cœur.


Qui veut agir juste
N'agit que par nécessité
Telle est la voie du sage

Tchouang Tseu

Il est tranquille l'esprit du sage
Miroir de l'univers et des êtres

Tchouang Tseu


Qui veut demeurer toujours calme
Règle sa respiration
Qui cherche l'inspiration exacte
Suit son cœur

Tchouang Tseu

3 septembre 2008

Pourquoi.... ??

Pourquoi ??
Vaste question... Pourquoi un blog, pourquoi écrire ici...

Je ne répondrai pas à cette question. D'autres je pense l'ont déjà fait. Apporter ici ma contribution ne servirait pas a grand chose...
Mais alors, que va-t-on trouver de beau ici ??
Mmmmm question beaucoup plus interessante....

Mais d'abord, qui suis-je... en sachant cela, on devinera déjà ce qui se trouvera sur ce blog.

Je suis Deirdre, Fille de Lune, de la Mère Eternelle.... Adepte de Second Life, SL pour les intimes.
J'y passe de nombreuses heures, à construire (builder comme on dit la bas), scripter aussi, et pratiquer l'Art du Sabre... J'aime lire aussi, beaucoup, beaucoup trop....

Ce blog sera donc le reflet de mes expériences SL, au fil de mes voyages, de mes découvertes. de mes rencontres.

Cours de build et de scripting LSL (Liden Scripting Language), Art du Sabre, poésie, pensées et reflexions diverses, lecture, ...., enfin tout ce qui fait la vie d'un blog !!
Vaste programme....

Ô toi lecteur qui passe par là,
Arrête toi un instant ici.
Lis les quelques mots
Que ma plume jette là,
Sur ces pages virtuelles.
Ecrits sur du vent,
Paroles qui volent,
Tout n'est qu'illusion.
La vraie vie est ailleurs
Comme dit le poête,
Mais où se trouve donc la vérité ?
Nulle part et partout
Comme il se doit !

Pensée du jour

Un commencement est toujours une chose délicate...

Par quoi commencer, qu'écrire, que dire...... Alors commençons simplement par une petite pensée taoiste de Tchouang Tseu.

Sous la lune, hommes et papillons se ressemblent. L'un vole en esprit, l'autre par ses ailes..

Une fois, moi Tchouang Tseu, je révai que j'étais un papillon volettant de-ci, de-là, butinant, satisfait de mon sort et ignorant mon état humain.....

Brusquement, je m'éveillai et me retrouvai, surpris d'etre moi meme.

A présent je ne sais plus si je fus un homme révant d'etre un papillon, ou si je suis un papillon revant d'etre un homme.

Entre le papillon et moi existe une différence : c'est ce qu'on appelle la mutation constante.