Recherche

Recherche personnalisée

dimanche 29 mars 2009

Tutorial 14 Toboggan 2/3

Dans le précédent tutorial je vous ai proposé un toboggan et je vous avais promis une version plus élaborée qui pallie les défauts les plus évidents. En particulier le fait que la ball ne soit pas solidaire du toboggan peut poser quelques problèmes lors des déplacements. Sans parler de la perte éventuelle de la ball.

Je vous propose donc une version plus élégante dans laquelle la ball est contenue dans le toboggan. Un clic sur celui-ci fait apparaître un menu avec trois options :

Glissade


Stop


Position

Cette option permet de faire apparaître la ball


Cette option fait disparaître la ball


Cette option permet de mémoriser la position et la rotation de la ball

D’autre part la ball ne peut survivre sans le toboggan. Celui-ci envoie une information cyclique, sans cette information la ball se suicide.

On se retrouve avec deux scripts : un dans le toboggan et un dans la ball.

Le toboggan doit savoir effectuer les opérations suivantes :

Ø créer une ball en la positionnant correctement,

Ø supprimer la ball,

Ø demander à la ball sa position et sa rotation et mémoriser ces informations,

Ø envoyer une information cyclique à la ball pour lui demander de survivre.

Voici le code correspondant à ces objectifs pour le toboggan :

integer canal_ball ; // Canal pour parler a la ball
integer canal_de_ball ; // Canal pour parler au toboggan
integer canal_menu ; // Canal pour le menu
integer ecoute ; // Ecoute
list menu; // Options du menu
vector offsetPos ; // Offset de positionnement
rotation offsetRot ; // Offset de rotation

// Initialisation du script
initialisations () {

canal_ball = 37;
canal_de_ball = 38;
canal_menu = 47;
menu =["Glissade" , "Stop" , "Position" ];
offsetPos = <0.0,0.0,1.0>;
}

// Initialisation de la ball

rez_ball( ) {

// Suppression eventuelle
llSay ( canal_ball , "Meurs" );
// Calcul du deplacement et de la rotation
vector tobPos = llGetPos ();
rotation tobRot = llGetRot ();
vector DestPos = (offsetPos * tobRot ) + tobPos ;
rotation DestRot = offsetRot * tobRot ;
// Creation de la ball
llRezObject ( "ball", DestPos , ZERO_VECTOR , DestRot , canal_ball );
// Activation du timer
llSetTimerEvent ( 60.0);
}

// Etat par defaut
default {

// Entree de l'etat
state_entry( ) {
initialisations ();
}

// Reinitialisation
on_rez( integer start_param ) {
initialisations ();
}

// Touche
touch_start (integer total_number ) {
// Suppression de l'ecoute eventuelle
llListenRemove ( ecoute );
// Mise en place de l'ecoute
ecoute = llListen (canal_menu , "", NULL_KEY , "");
// Affichage du dialogue
llDialog ( llDetectedKey (0), "Choisissez une option", menu, canal_menu );
}

// Stimulation reguliere de la ball
timer ( ) {
// Message pour la ball
llSay ( canal_ball , "Vis" );
}

// Ecoute
listen (integer channel, string name, key id, string message ) {
// Affichage de l'option choisie
llWhisper ( 0, name + " a choisi l'option '" + message + "'." );
// Suppression de l'ecoute
llListenRemove ( ecoute );
// Selection selon l'option
if (message == "Glissade" ) {
// Affichage d'initialisation
llWhisper ( 0, "Initialisation du toboggan");
// Initialisation de la ball
rez_ball( );
}
else if (message == "Stop" ) {
// Suppression de la ball
llSay ( canal_ball , "Meurs" );
// Arret du timer
llSetTimerEvent ( 0.0);
}
else if (message == "Position" ) {
// Ecoute de la ball
ecoute = llListen (canal_de_ball , "", NULL_KEY , "");
// Demande positions
llSay (canal_ball, "Positions" );
}
else if (llGetSubString (message, 0, 0) == "<" ) {
// Reception des positions
list pos = llParseString2List (message, ["|"], []);
offsetPos = (vector )llList2String (pos , 0) - llGetPos ();
offsetRot = (rotation )llList2String (pos , 1) / llGetRot ();
llWhisper ( 0, "Memorisation de la position " + (string )offsetPos + " " + (string )offsetRot );
}
}
}

Sept variables nous sont nécessaires :

Variable


Type


Rôle

canal_ball


integer


Canal du toboggan vers la ball

canal_de_ball


integer


Canal de la ball vers le toboggan

canal_menu


integer


Canal pour le dialog

ecoute


integer


Mémorisation de l’écoute pour sa suppression

menu


list


Données du dialog

offsetPos


vector


Offset de positionnement de la ball

offsetRot


votation


Offset de rotation de la ball

La méthode initialisations permet de renseigner la valeur des canaux du chat et les données du Dialog. Les offset ont au départ une valeur nulle et l’écoute sera renseignée au moment nécessaire, c’est-à-dire lors de la création de l’écoute.

Une méthode intéressante est rez_ball qui permet de créer la ball. On commence par supprimer une ball éventuellement présente en envoyant un message de suicide. On calcule ensuite la position et la rotation de la future ball en se basant sur les informations de positionnement et de rotation du toboggan et de la valeur des offset. Je laisse les formules mathématiques aux amateurs de quaternions et autres fantaisies de ce genre pour en venir directement à l’importante fonction llRezObject. Celle-ci permet de créer un objet, ou plus exactement une instance d’un objet, parce que l’objet correspondant doit déjà exister dans l’objet qui contient le script. En d’autres termes dans notre cas la ball est déjà contenu dans le toboggan, on se contente d’en créer une instance. Observez les paramètres de cette fonction :

Paramètre


Type


Fonction

Inventory


string


Elément de l’inventaire à instancier

Pos


vector


Position de création

Vel


vector


Vélocité de l’objet créé

Rot


rotation


Rotation de création

Param


integer


Paramètre libre

Dans notre cas le premier paramètre correspond au nom de la ball contenue dans le toboggan. Le second et quatrième paramètres nous permettent d’ajuster la position et la rotation de la ball. Nous ignorons le troisième paramètre parce que nous voulons une ball immobile. Enfin nous profitons du dernier paramètre pour transmettre le canal d’écoute.

Tous les Rezzers que vous rencontrez sur sl sont fondés sur cette fonction ou sa sœur llRezAtRoot. Par exemple une maison imposante est découpée en morceaux et recréée sur place avec un Rezzer. Vous pouvez aussi imaginer un aménagement d’appartement modulable…

Je dois toutefois préciser que ce rezzer m’a passablement occupé ces derniers temps et mes amis sur sl s’amusaient de me voir en train de m’énerver sur mon toboggan. J’avais beau analyser mon code je ne trouvais pas la faille. Jusqu’au moment où j’ai eu l’idée de faire un essai avec des objets simples plutôt qu’avec les prims torturées de mon toboggan. Et là grosse surprise : tout fonctionnait parfaitement ! J’avais passé beaucoup de temps à chercher des erreurs qui n’existaient pas… Moralité : si vous voulez créer un rezzer utilisez plutôt une prim sans trop de modifications sinon vous risquer de galérer comme je l’ai fait avec des positionnements aléatoires. Il m’a suffit d’ajouter un cube à mon toboggan et de le définir comme root et tout s’est bien passé ensuite…

La dernière action de la méthode initialisations est de déclencher un timer réglé à 60 secondes pour envoyer une impulsion régulière à la ball pour lui demander de vivre. Ce que vous retrouvez dans la fonction timer avec le message « Vis » sur le canal de la ball.

Le reste du code ne présente pas de nouveauté. L’événement touch_start commence par supprimer une écoute éventuelle, mets en route l’écoute pour le dialog, et affiche le dialog.

L’événement listen récupère l’action de l’utilisateur :

Option


Action

Glissade


Mise en œuvre de la méthode rez_ball

Stop


Envoi du message « Meurs » à la ball

Position


Ecoute de la ball et envoi du message « Positions » à la ball

Lors de l’écoute de la ball le seul message qui peut revenir est celui qui contient les coordonnées. On teste le message avec la fonction llGetSubString qui permet d’extraire une sous-chaîne d’une chaîne en transmettant l’index du caractère de début et l’index du dernier à extraire. Pour extraire le premier caractère il faut mettre 0 pour les deux paramètres. Les coordonnées sont transmises sous le format string séparées par le caractère « | ». La fonction llParseString2List permet de récupérer dans une list les éléments séparés par le caractère passé en paramètre (en fait une liste de séparateurs au format string). Il suffit ensuite d’extraire les coordonnées avec un cast (transformation de type) et de les combiner aux coordonnées du toboggan pour obtenir les offset et les mémoriser.

Suite au tutorial suivant...

5 commentaires:

  1. Merci beaucoup pour ce site et toutes les informations qu’il regorge. Je le trouve très intéressant et je le conseille à tous !
    Bonne continuation à vous.
    voyance gratuitement

    RépondreSupprimer
  2. Je découvre ton site il est magnifique super bravo a toi.
    voyance par mail gratuite

    RépondreSupprimer
  3. Félicitation pour ton site que je visite quasiment chaque jour, il est très bien fait et agréable.

    voyance gratuite par mail

    RépondreSupprimer
  4. Super blog, j'adore vos articles et reportages, bonne continuation.

    voyance gratuite

    RépondreSupprimer
  5. J’aime beaucoup ce blog car vous êtes un de ceux qui a le plus de recul par rapport “au monde virtuel”…
    gay telephone

    RépondreSupprimer