vendredi 28 décembre 2007

llGetRot

La notion d'aujourd'hui est très compliqué, c'est pourquoi nous ne ferons que la survolée pour le revoir plus en profondeur plus tard.
llGetRot nous donne la rotation d'un objet sous forme d'un vecteur. Vous avez pu le constater que lorsque l'on change la position d'un prim, ca n'a pas le même effet si on a changé la rotation.
En effet le déplacement reste le même mais plus dans le sens de la rotation. Pour ceux qui ont des notions de trigonométrie, cela sera plus facile à comprendre.

tout le secret réside ici:
offset*=llGetRot();

ca pourrait déja s'ecrire offset=offset*llGetRot() mais on utilise généralement se raccourci d'ecriture
En faisant le produit entre la rotation(ou angle) et le vecteur de position on modifie la position en fonction de la rotation.
Intuitivement on peut se douter que la rotation doit rentrer en ligne de compte.
Pour l'instant admettez juste pos*rot prise compte de la rotation.


Notre script de porte a aussi une amélioration notable, on utilise un seul script pour les deux portes, il suffit juste de mettre -1 ou 1 dans la description

// defini un vecteur pour la position de l'objet
vector pos;
integer sens;
default
{
state_entry()
{
// fonction que l'on a déja vu qui recupère la description de l'objet
// la valeur de la description de l'objet sera -1 ou 1
// cette valeur permetra à le porte de s'ouvrir vers la gauche ou la droite
// en fonction de si il s'agit d'une porte de gauche ou de droite
// (integer) permet de transformer en entier le string en provenance de la description
sens=(integer)llGetObjectDesc();
}

touch_start(integer total_number)
{
vector size;
// float est un nombre décimal(a virgule)
float largeur;

// sauvegarde la position initiale
pos=llGetPos();

// recupère les dimension de l'objet
size=llGetScale();
largeur=size.y;

// on appelle un offset la différence de distance entre deux point
// en multipliant par le sens notre porte ira vers la gauche ou la droite
vector offset=<0,sens*largeur,0>;

// la fonction du jour
offset*=llGetRot();

// on ajoute l'offset à la porte pour la déplacer
llSetPos(pos+offset);


// delenchera l'evenement timer dans 20 secondes
llSetTimerEvent(20);
}
timer()
{
//remet en place l'objet
llSetPos(pos);

//empêche le déclenchement de l'evenement timer
llSetTimerEvent(0);
}
}

jeudi 27 décembre 2007

llGetScale

Notre script de porte commence à prendre tournure. Grâce à la fonction llGetScale, on obtient les dimensions de notre objet retournées par un vecteur. Il existe aussi la fonction llSetScale qui permet de définir la taille d'un objet.
Et aujourd'hui on découvre que l'on peut extraire la longueur, largeur, hauteur rien qu'en rajoutant un point après le nom du vecteur. L'avantage de travailler en fonction de la largeur c'est que quelque soit les dimension de votre porte votre script marchera sans le modifier.
Il nous reste un problème majeur, vous ferez le test, si vous tournez à 45° votre porte, elle ne s'ouvre pas dans le bon sens. On verra ça demain.

// défini un vecteur pour la position de l'objet
vector pos;
default
{
touch_start(integer total_number)
{
vector size;
integer largeur;

// sauvegarde la position initiale
pos=llGetPos();

// recupère les dimension de l'objet
size=llGetScale()

// ici on ne récupère que la composante y du vecteur
// il est en effet possible de récupérer
// que l'une des composantes d'un vecteur
// en suffixant la variable par un point et la lettre composante (x,y,z)
largeur=size.y;

// on redéfini l'emplacement de l'objet en le décalant de sa largeur
// sur l'axe des y
llSetPos(pos+<0,largeur,0>);

// delenchera l'evenement timer dans 20 secondes
llSetTimerEvent(20);
}
timer()
{
//remet en place l'objet
llSetPos(pos);

//empêche le déclenchement de l'evenement timer
llSetTimerEvent(0);
}
}

mercredi 26 décembre 2007

llSetTimerEvent

La fonction du jour llSetTimerEvent permet de déclencher l'événement timer à un rythme régulier spécifié en seconde pour celui ci. J'ai repris volontairement le script de la dernière fois car nous allons le faire évoluer pour arriver à faire une porte automatique genre super marché.
Ici lorsque l'on touche l'objet, il se décale de 1m sur le coté. 20 secondes après, l'événement timer se déclenche et remet notre objet en place. On met à 0 le déclenchement du timer pour le rendre inopérant et ainsi attendre le prochain événement touch


// defini un vecteur pour la position de l'objet
vector pos;
default
{
state_entry()
{

}

touch_start(integer total_number)
{
// sauvegarde la position initiale
pos=llGetPos();

// on redefini l'emplacement de l'objet en le décalant de 1 m
// sur l'axe des y
llSetPos(pos+<0,1,0>);

// delenchera l'evenement timer dans 20 secondes
llSetTimerEvent(20);
}
timer()
{
//remet en place l'objet
llSetPos(pos);

//empêche le déclenchement de l'evenement timer
llSetTimerEvent(0);
}

}

lundi 24 décembre 2007

llSetPos

Aujourd'hui on va voir comment déplacé un prim grâce à l'instruction llSetPos. Tout d'abord revoyons la notion de vecteur car elle sert aussi pour les positions. en effet, cela permet de déterminer l'emplacement d'un objet dans l'espace. Chaque nombre représente les axes x, y, z de l'objet.
En complément à cette fonction nous avons aussi llGetPos qui nous retourne la position actuelle de l'objet. Le script ci dessous déplace l'objet lorsque l'on rentre en collision avec et le remet à sa place quand on le touche. Disons que ca pourrait servir pour une porte.
La partie importante et délicate est celle de l'addition de vecteur, chaque terme s'ajoute un à un.
<10,10,10>+<0,0,1>=<10,10,11>
en ajoutant un vecteur à la position de l'objet on le déplace.

// defini un vecteur pour la position de l'objet
vector pos;
default
{
state_entry()
{

}
collision(integer total_number)
{
// sauvegarde la position initiale
pos=llGetPos();

// on redéfini l'emplacement de l'objet en le décalant de 1 m
// sur l'axe des y
llSetPos(pos+<0,1,0>);

}

touch_start(integer total_number)
{
//remet en place l'objet
llSetPos(pos);

}


}

vendredi 21 décembre 2007

llGetNotecardLine

Les notecards et leur contenu peuvent srvir pour beaucoup de choses, du paramètrages à de l'information en général.
Ici, nous voyons comme y acceder via l'evenement dataserver


// notre compteur de ligne
integer Ligne=0;
default
{
state_entry()
{
// voici notre fonction du jour
// on doit lui préciser le nom de la notecard contenu dans notre objet
// et aussi le numéro de la ligne
// en faisant ligne++ on augmente ligne de 1 et nous lisons donc la première ligne
// Lorsque la fonction est excuter cela déclenche l'evenement dataserver
// la fonction nous retourne une key identifiant de la demande
key k=llGetNotecardLine("notecard dans contenu", Ligne++);
}

dataserver(key requested, string data)
{
// comme nous ne savovons pas combien il y a de ligne dans notre notcard
// on va testé que la valeur de la notecard n'est pas EOF(End of file)
// si ce n'est pas le cas alors nous avons des données
if(data!=EOF)
{
// ici nous affichons data, le contenue de notre ligne
llSay(PUBLIC_CHANNEL,data);

// maintenant nous redemandons une ligne, faisant ligne ++
// on augmente sa valeur et donc la ligne suivante
// donc on va revenir dans dataserver et recommencer tant que
// data ne sra pas à EOF
key k=llGetNotecardLine("notecard dans contenu", Ligne++);

}

}

}

jeudi 20 décembre 2007

llDialog

Tout d'abord je rappelle que ce soir il y a un cours à l'ecole de SL à 21h30
http://slurl.com/secondlife/Terra%20Bordeaux/153/67/25/

Voici une fonction très simple d'utilisation et très puissante. Elle permet aussi de rendre les scripts un peu conviviaux.
La fonction llDialog permet d'afficher un menu avec un ensemble de bouton. Lorsque l'on appui sur le bouton le script va "dire" le nom du bouton sur le channel il ne reste plus que à écouter le nom du bouton pour faire l'action, ici on fera changer la couleur de l'objet.
Important, la fonction doit être couplé avec un listen car si votre script "n'écoute pas" sur un channel la dialog pour dire ce qu'elle veut ^^
Maintenant les paramètres :
D’abord qui l'utilise sa key
Le libellé du menu
une list avec la list des boutons
et un channel
Il est recommandé d'utilisé une variable pour déterminer le channel et ainsi être sure de ne pas se mélanger. On verra dans d'autres script que c'est aussi utile pour la sécurité



// Une list est une variable dans laquelle on peut mettre des variable de tout type
// ici des string correspondant au nom des bouton
// une list commence et se termine par un crochet et
// chaque élément est séparé par des virgules
list bouton=["rouge","vert","bleu"];

default
{
state_entry()
{
// on défini le channel commun du listen et de la dialog
integer channel=1;

// ecoute le channel pour le proprio
llListen(channel,"",llGetOwner(),"");

// la fonction du jour !
llDialog(llGetOwner(),"Choisissez la couleur",bouton, channel);
}
listen(integer channel, string name, key id, string message)
{
// mets la couleur désiré en fonction du message
if(message=="rouge") llSetColor(<1,0,0>,ALL_SIDES);
if(message=="vert") llSetColor(<0,1,0>,ALL_SIDES);
if(message=="bleu") llSetColor(<1,0,0>,ALL_SIDES);
}

}

mardi 18 décembre 2007

llSetColor

Sous son apparence anodine cette fonction qui détermine la couleur n'est qu'un prélude à tout un ensemble de fonctions complexes concernant la manipulation graphique des prims.
Notre fonction du jour llSetColor permet de déterminer la couleur d'un prim.
La couleur est détermine par une composante RVB c'est à dire un mélange des couleurs rouge vert bleu sous la forme d'un vecteur.
http://forums.jeuxonline.info/showthread.php?t=737580
Sur ce lien vous trouverez une énorme liste de ces couleurs avec des libellés en clair.
Pour finir le deuxième paramètre de la fonction est la face, en effet par code il est aisé de modifier indépendamment les faces. dessus, 0, bas 5, etc.. Enfin vous testerez
Sinon Vous pouvez mettre ALL_SIDE pour modifier toutes les faces

default
{
state_entry()
{
// ecoute le channel 1 our le proprio
llListen(1,"",llGetOwner(),"");
}
listen(integer channel, string name, key id, string message)
{
// on determine la couleur du prim toutes les faces on la même couleur
if(message=="blanc") llSetColor(<1,1,1>,ALL_SIDES);

// prends une face au hasard et lui mets une couleur RVB
if(message=="rouge") llSetColor(<1,0,0>,(integer)llFrand(6.0));
if(message=="vert") llSetColor(<0,1,0>,(integer)llFrand(6.0));
if(message=="bleu") llSetColor(<0,0,1>,(integer)llFrand(6.0));
}

}

lundi 17 décembre 2007

llGetOwner

Aujourd'hui sera un article très court mais est fondamental en LSL, la notion de Owner. La fonction llGetOwner retourne la key du propriétaire de l'objet, cette fonction est constamment utilisée. En effet, on a très souvent besoin d'être sure que l'utilisateur de l'objet est bien le propriétaire. Vous pouvez par exemple ne faire s'ouvrir les portes de chez vous que si c'est vous. Mais vous verrez au travers des fils suivant que cette fonction est incontournable


key proprio;
default
{
state_entry()
{
// on stock la key du proprietaire
proprio=llGetOwner()
}
touch_start(integer total_number)
{
// on test si la personne detecte est bien le propietaire
// on peut remarque que nous n'avons pas utilisés les accolades. En effet, quand
// un if ne contient qu'une seule instruction elles ne sont pas nécéssaire
if(llDetectedKey(0)==proprio) llSay(PUBLIC_CHANNEL,"Seul mon proprio peut voir ce message");
}
}

vendredi 14 décembre 2007

llDetectedName

On va parler aujourd'hui de la famille des lldetected elles permettent d'obtenir des informations sur un avatar qui interagit avec l'objet. On peut obltenir cette information pendant les evenment suivant:
collision(), collision_start(), collision_end(), sensor(), touch(), touch_start(), or touch_end()
llDetectName prend en paramètre un integer il correspond à la nième personne à avoir effectué l'événement.
C'est particulièrement utile pour sensor où plusieurs personne peuvent déclencher l'evenement en même temps. Ici, on mets 0 donc le premier à l'avoir toucher, car de toute facon il sera forcement seul.

default
{
state_entry()
{

}

touch_start(integer total_number)
{
string nom=llDetectedName(0);

// une key un type qui permet d'identifier de manière unique quelque chose dans SL

key KeyTouch=llDetectedKey(0);

// on transforme notre key en texte pour pouvoir l'afficher, UID est l'identifiant d'un
// ca key

string UID=(string)KeyTouch;

// affiche le nom et l'UID de la l'avatar qui viens de toucher le cube

llSay(PUBLIC_CHANNEL,nom + " votre UID est " + UID);
}

}

jeudi 13 décembre 2007

llFrand

La fonction llFrand() permet de tirer un chiffre au hasard. On lui passe un float(nombre décimal) et il en retourne un autre entre 0 et celui passer en paramètre. Cette petite fonction peut ce se révèler utile dans nombre de cas.
Une application de llFrand aujourd'hui, le script choisi un nombre au hasard et vous devez deviner le nombre. pour répondre vous saissez dans la fenêtre de chat qu'il ecoute via un listen eet compare le message par rapport à la valeur tappée

// integer defini un nombre de type entier donc san virgule
// en placant notre déclaration ici, la varaible est utilisable dans tout le script
// sinon elle n'est visible que dans l'envenement

integer nb;

default
{
state_entry()
{
// Ici on écoute tout ce que dit le propriétaire sur le channel public

llListen(PUBLIC_CHANNEL,"",llGetOwner(),"");

// Rapidement on met un libelle pour informer

llSetText("touchez moi",<1,0,0>,1.0);
}

touch_start(integer total_number)
{
// en touchant on a déclencher le jeu, donc il n'attend plus que on le touche
llSetText("",<1,0,0>,1.0);

// la fonction du jour
nb=(integer)llFrand(10.0);

// on informe que le nombre a ete choisi
llSay(PUBLIC_CHANNEL,"j'ai choisi un nombre");
}

listen(integer channel, string name, key id, string message)
{
// ici on rencontre se que l'on appelle un "cast" ou transtypage en francais
// on transforme un type en un autre
// ici message est un string mais nous voulons un integer en le mettant
// entre paranthèse il va essayer de le transformer
// on remarque aussi l'attribution direct pendant la déclaration

integer reponse=(integer)message;

// ici on va tester l'ensenble des possibilités

if(reponse>nb)
{
llSay(PUBLIC_CHANNEL, "non c'est trop grand");
}
else
{
if(reponse
{
llSay(PUBLIC_CHANNEL, "non c'est trop petit");
}
else
{
llSay(PUBLIC_CHANNEL, "bravo vous avez gagner");
}

}

}


}

mercredi 12 décembre 2007

llListen

La fonction du jour "ecoute" un channel particulier le texte ecrit soit par un avatar , soit par un objet via la fonction llSay. Cette fonction est très utilisé pour déclencher des comportements par voix. Par exemple les pose ball se cache et s'affiche par
/1 hide ou /1 show

la fonction paramètre un ensemble de critère qui déclenche l'evenement Listen.
Mais llListen ne le déclenche que sous les conditions de ses paramètres.

Notion déjà vu pour llSay, ici on ecoute un canal particulier
Integer channel

ne déclenchera l'evenement que si dans le message il y a ce string, on met "" si l'on ne veux pas de filtre
string filtre

On peut preciser d'ecouter qu'une seul personne, mais ce n'est pas obligatoire, le cas échéant on mets NULL_KEY
key QuiParle

Ce filtre est encore plus restrictif, l'evenment ne ce déclanchera que si ce texte est dit.
string message

passons maintenant à une partie tout aussi importante l'evenement listen
Nous avons comme paramètre le channel ecouté, car on peut ecouter plusieurs channels à la fois.
Nous avons une key qui l'identifiant de qui ou quoi a déclenché l'evenement. Et pour finir, bien évidement le message

Il ne reste plus qu'a tester les différents parmètre pour faire notre action.
Nous Serions en droit de penser que nous pourrions ecrire ceci à chaque fois et de tester dans le listen
llListen(0,"",NULL_KEY,"");

Le problème ici, c'est le lag(ralentissement général), car l'événement est appellé très souvent. Il vaut mieux qu'il soit restreint au maximum


// Key est un numéro unique pour définir quelque chose dans second life
// chaque objet, avatar, etc... sont identifiés par une key
key Proprio;

default
{
state_entry()
{
// on affiche un texte en rouge(fonction connue)
llSetText("mon texte est rouge",<1,0,0>,1.0);

// cette fonction retourne la key du propriétaire de l'objet
Proprio=llGetOwner();

// notre fonction du jour
llListen(1,"texte",Proprio,"");
}
listen(integer channel, string name, key id, string message)
{
// ici on test le contenu du message "entendu" et change la couleur du texte
if(message=="texte rouge") llSetText("mon texte est rouge",<1,0,0>,1.0);
if(message=="texte vert") llSetText("mon texte est vert",<0,1,0>,1.0);
if(message=="texte bleu") llSetText("mon texte est bleu",<0,0,1>,1.0);

}
}

mardi 11 décembre 2007

llSay

La fonction llSay est certainement la fonction la plus commune de toute. Elle permet généralement d'afficher du texte dans la zone de chat. Mais on s'en sert pour commander aussi à des objets avec son complément llListen

Elle possède deux paramètres le channel en premier qui est un chiffre arbitraire à la manière de la fréquence d'une radio FM. Le canal général où l'on parle est le zéro ou PUBLIC_CHANNEL
PUBLIC_CHANNEL est en faite une constante qui vaut zéro, mais il est préférable de l'utiliser pour des raisons de lisibilité.
Le second paramètre est un string, le texte à afficher.
Il existe des variantes llShout, llWhisper qui ont la même finalité mais la portée est plus ou moins grande. Au delà de 20m vous ne verrez plus le texte afficher par un llSay car vous êtes hors de portée.

default
{
state_entry()
{
// ici dans la déclaration du string on peut remarquer que
// l'on a donné directement une valeur à la variable.
// deuxième chose \n il symbolise un retour à la ligne.
string phrase="premiere ligne\n seconde ligne";

llSay(PUBLIC_CHANNEL, phrase); //parle à 20m

llShout(PUBLIC_CHANNEL, phrase);//parle à 100m

llWhisper(PUBLIC_CHANNEL,phrase);//parle à 10m
}
}

llSetText

llSetText permet d'afficher un texte au dessus d'un objet. Cette fonction présente de nombreuses applications. Elle permet surtout d'informer sur le comportement ou le contenu de l'objet. Par exemple il y a les teleports, pose balls, les vendeurs d'article, etc..
L'image vous montre en résultat de "floating text"
Elle est très simple d'utilisation comme le montre le script du jour.

default
{
state_entry()
{
// il est de type sting c'est a dire un texte séparé par des guillemets
// attention l'accentuation n'est pas accèpté en LSL
string message;

// le type float est un réel, un nombre à virgule. Il doit avoir un point
f loat transparence;

// le type vecteur est une combinaison de 3 réel spéaré par des virgules
// et encadré par des <>
vector couleur;

// libelle du message au dessus de l'objet
message="Ce message flotte au dessus de votre objet";

// la transparence du texte, elle varie de 0 transparent à 1.0 opaque
transparence=1.0;

// la couleur est définir par un vecteur
// chaque chiffre représente une composante Rouge Vert ou bleu RVB
// les valeurs varient de 0 à 1. Ici c'set rouge <1,0,1> fera du violet
couleur=<1,0,0>;

//là il s'agit de la fonction à proprement dit
llSetText(message,couleur,transparence);
}

}