Je tiens à rappeler que
les scripts que je propose dans ces tutoriaux ont une vocation
essentiellement didactique. Le but est de présenter chaque
fois des éléments nouveaux tout en revoyant certaines
choses déjà rencontrées dans les tutos
précédents. Ces scripts ne sont pas forcément
complets et sans bugs, parfois il existe d'autres manières
de faire plus performantes mais moins pédagogiques. Je livre
donc ces codes sans aucune garantie si ce n'est celle d'apprendre
un peu à programmer avec LSL...
Continuons notre animation des
avatars avec cette fois un Danceball. Au niveau du fonctionnement
envisageons du classique : une boule avec un texte flottant
"Danser", avec un clic droit le menu propose "Danser" à la
place de "Sit", le danceball contient plusieurs animations et le
choix est aléatoire, au clic sur "Danser" une
première danse démarre et le DanceBall
disparaît ainsi que le texte flottant. Au bout d'un certain
délai l'animation change, et ainsi de suite jusqu'à
ce qu'on clique sur "Se lever", à ce moment là
l'animation s'arrête et le Danceball réapparaît
avec son texte flottant. Vous avez juste à créer une
boule de votre couleur favorite et de poser dedans le code suivant
:
// Animation en cours
string Animation;
// Nombre total de danses
integer Total;
initialisations()
{
// Danceball visible au depart
llSetAlpha(TRUE, ALL_SIDES);
// Texte au-dessus du Danceball
llSetText("Danser", <1.0,1.0,1.0>,
1.0);
// Positionnement de l'animation
llSitTarget(<0,0,-.3>,
ZERO_ROTATION);
// Nombre de danses
Total =
llGetInventoryNumber(INVENTORY_ANIMATION);
if (Total == 0)
{
llWhisper(0, "Erreur: Pas
d'animation...");
return;
}
// Changement du menu
llSetSitText("Danser");
}
animer(string anim)
{
// Arret de l'animation
precedente
llStopAnimation(anim);
// Animation aleatoire nouvelle
string TempAnim = Animation;
do {
Animation = llGetInventoryName(INVENTORY_ANIMATION,
(integer)llFrand(Total - 1));
}
while (Animation == TempAnim);
// Animation en marche
llStartAnimation(Animation);
}
default
{
state_entry()
{
initialisations();
}
on_rez(integer start_param)
{
initialisations();
}
changed(integer change)
{
// Test de changement dans les
liaisons
if (change & CHANGED_LINK)
{
// Determination de la clef de
l'avatar
key AgentKey =
llAvatarOnSitTarget();
// Un avatar present ?
if (AgentKey)
{
// Permission d'animation
llRequestPermissions(AgentKey,
PERMISSION_TRIGGER_ANIMATION);
// Demarrage du timer
llSetTimerEvent(60.0);
// Effacement du Danceball
llSetAlpha(FALSE, ALL_SIDES);
// Effacement du texte flottant
llSetText("", <0,0,0>,
1.0);
}
else
{
// Arret de l'animation
llStopAnimation(Animation);
// Reinitialisation du script pour le prochain
avatar
llResetScript();
}
}
}
timer()
{
// Changement de l'animation
animer(Animation);
}
run_time_permissions(integer
permissions)
{
if(permissions == PERMISSION_TRIGGER_ANIMATION &&
Total > 0)
// Desactivation de l'animation par defaut "sit" et
depart premiere animation
animer("sit");
}
}
Il faut aussi poser des
animations de danse dans votre boule. Au final votre Danceball
contient donc un script et des animations. Comme à notre
habitude nous allons analyser ce code dans le
détail.
Deux variables globales
permettent de mémoriser l'animation en cours et le nombre
total d'animations contenues dans le Danceball. A la phase
d'initialisation le Danceball est rendu visible avec la
fonction llSetAlpha
qui possède deux paramètres : le
premier est la valeur alpha, c'est-à-dire le degré de
transparence souhaité (à 0 c'est complètement
transparent et à 1 totalement opaque, entre les deux la
transparence est plus ou moins importante), comme nous voulons
parfaitement voir le Danceball il faut utiliser la valeur 1.
Pourquoi avoir utilisé TRUE ?
Vous vous souvenez sans doute que TRUE
correspond à 1 et FALSE
à 0. Le fait de mettre TRUE apporte plus de
lisibilité au code, enfin c'est mon point de vue ! Le
deuxième paramètre correspond aux faces (side) que vous désirez affecter avec votre
valeur alpha. La constante ALL_SIDES signifie "toutes les
faces", pour notre sphère de toutes façon il n'y a
qu'une seule face et nous aurions tout aussi bien pu mettre la
valeur 0. Mais si vous avez par exemple un cube alors vous avez 6
faces et la constante devient bien pratique pour affecter toutes
les faces d'un coup.
Le texte flottante st
créé avec la fonction llSetText. Le premier
paramètre est le texte à afficher, le second sa
couleur et le troisième sa transparence (alpha). Le
vecteur <1.0,1.0,1.0> correspond aux
valeurs maximales des primaires rouge, vert et bleu, donc à
la couleur blanche. Quant à la transparence la valeur 1
signifie opaque comme nous l'avons déjà vu
ci-dessus.
Nous avons déjà vu
la fonction au précédent tuto, je passe donc à
l'instruction suivante. Elle va me permettre d'introduire la notion
d'inventaire (inventory). Jetez un
coup d'oeil à cette page :
http://www.lslwiki.net/lslwiki/wakka.php?wakka=inventory
Vous pouvez y lire qu'il existe
deux sortes d'inventaires; celui de l'avatar que vous connaissez
bien dans lequel vous stockez vos habits, animations et autres
merveilles, et celui des objets que vous connaissez moins. Vous
pouvez mettre ce que vous voulez dans un objet, nous avons
déjà vu que nous pouvons y mettre des scripts, des
sons et des animations. Mais vous pouvez aussi y mettre des
textures, des landmarks, des notecards... Il existe un certain
nombre de fonctions pour gérer tout ce bazar. Ce qui nous
intéresse pour le moment est le nombre d'animations
contenues dans notre Danceball. C'est la fonction
llGetInventoryNumber
qui va nous le dire. Il suffit de lui passer en
paramètre le type de contenu dont nous voulons
connaître la quantité. Vous avez sur la page du WIKI
toutes les constantes qui peuvent être utilisées. Dans
notre cas il nous faut INVENTORY_ANIMATION puisque nous
voulons connaître le nombre d'animations. Cette valeur est
stockée dans la variable globale Total pour être utilisée
ultérieurement dans le script.
Ensuite j'ai prévu un
petit test pour vérifier que notre Danceball contient
effectivement des animations. Si le Total est égal à
0 alors on envoie une message au niveau du Chat. Remarquez que
l'utilisation de la fonction llWhisper
à la place de llSay permet de
limiter la portée du message à 10 mètres au
lieu des classiques 20 mètres de llSay. Ensuite le return permet de sortir de l'initialisation sans
accéder à l'instruction suivante. Par contre si le
test est positif on change l'indication du menu comme nous l'avons
fait au tuto précédent.
Arrivés à ce stade
il ne se passe plus rien tant qu'un avatar n'a pas la bonne
idée de s'asseoir sur le Danceball. A ce moment là
l'événement changed est
déclenché. Je passe rapidement sur les
premières instructions qui sont identiques à celle du
précédent tuto. On teste si une nouvelle liaison est
présente, si c'est un avatar, et si c'est le cas on demande
la permission de l'animer. On sait que cela déclenche
l'événement run_time_permissions, au niveau de
cet événement on vérifie la permission et
aussi que le total des animation est bien supérieur à
0, donc que nous allons pouvoir lancer une animation. A ce moment
là nous appelons la méthode animer avec comme paramètre l'animation par
défaut sit :
animer(string
anim)
{
// Arret de l'animation
precedente
llStopAnimation(anim);
// Animation aleatoire nouvelle
string TempAnim = Animation;
do {
Animation = llGetInventoryName(INVENTORY_ANIMATION,
(integer)llFrand(Total - 1));
}
while (Animation == TempAnim);
// Animation en marche
llStartAnimation(Animation);
}
On commence par arrêter
l'animation passée en paramètre, dans notre cas il
s'agit de sit, mais au prochain appel de la méthode ce sera
la première animation lancée, et ainsi de suite...
l'instruction suivante crée une variable de type string pour
mémoriser l'animation actuelle, dans notre premier passage
celle-ci est vide mais pour les passages suivant elle contiendra
l'animation en cours. Ensuite nous avons un nouvel
élément avec le mot clef do. Il s'agit d'une boucle, on dit de faire
(do) une chose tant qu'une condition
est satisfaite (while). Que
faisons-nous dans cette boucle ? Avec la fonction
llGetInventoryName
nous allons chercher une animation dans l'inventaire
du Danceball. Cette fonction attend comme premier paramètre
le type d'élément désiré, nous
retrouvons notre constante déjà vue plus haut, et en
deuxième paramètre l'index dans la collection des
éléments concernés. Imaginons que nous avons
mis 6 animations, elles sont indexées de 0 à 5. c'est
cette valeur qu'attend la fonction. ici nous utilisons la fonction
llFrand que nous connaissons déjà pour
générer une valeur aléatoire dans la gamme des
index possible en nous référant au nombre total
d'animations. Mais à quoi sert donc la boucle ? Et bien le
test de la boucle est constitué par la vérification
que l'animation choisie au hasard n'est pas celle
déjà en cours. Autrement dit on ne veut pas avoir
deux fois de suite la même danse. A la sortie on lance la
nouvelle animation sélectionnée.
Revenons maintenant à
l'événement changed que
nous avons un peu abandonné. Nous voyons qu'après la
demande de permission nous lançons un timer réglé à 60 secondes.
Délai choisi entre les différentes danses. Au niveau
de l'événement du timer
vous constatez qu'on se contente d'appeler notre méthode
animer avec l'animation en cours en
paramètres. Nous comprenons maintenant pourquoi.
Après l'initialisation du timer on efface la Danceball avec
la fonction llSetAlpha
en mettant cette fois son premier paramètre
à 0 (FALSE). Il ne reste plus
après qu'à effacer le texte flottant avec la
même fonction qui nous a servi pour l'afficher
llSetText mais
cette fois en passant une chaîne de caractères vide et
la couleur noire <0,0,0>.
J'espère que ce tutorial
vous donnera envie de vous lancer dans la création.
N'hésitez pas à me faire part de vos
réalisations.