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.