Archivi tag: Scripting LSL

Terza Lezione di LSL

Terza Lezione di LSL

Terza lezione di LSL alla Land del Forum!

Abbiamo continuato il discorso iniziato alla seconda lezione di LSL: la Comunicazione.

Ovvero come fa un oggetto ad ascoltare su di un canale ed a rispondere. Abbiamo creato due oggetti: il primo che ascolta su un canale, il secondo che appena toccato parla sullo stesso canale.

In questo modo abbiamo simulato la comunicazione tra i due oggetti. Il progetto consiste in due oggetti distinti, ognuno con il proprio script, che comunicano tra di loro.

Il primo script inizializza un listener tramite la chiamata a funzione llListen sul canale 1234567890. Al listen non vengono applicati filtri, quindi qualunque agent può interagire con esso.
Dentro l’evento listen è stata inserita una chiamata a funzione llSay su canale PUBLIC_CHANNEL (ovveo il canale 0), per avere un feedback del messaggio ascoltato.

integer CHANNEL = 1234567890;

default {
    state_entry() {
        key owner = llGetOwner();
        llSetText("Oggetto che riceve di "+llKey2Name(owner),<0.0,1.0,0.0>,1.0);
        llListen(CHANNEL,"",NULL_KEY,"");
    }

    listen(integer channel, string name, key id, string message) {
        llSay(PUBLIC_CHANNEL,name+" mi ha detto \""+message+"\" sul canale "+(string)channel);
    }

    changed(integer change) {
        if(change & CHANGED_OWNER) llResetScript();
    }
}

Il secondo script si occupa di attendere un click dal proprietario dell’oggetto per inviare nel canale prestabilito la stringa “NOME_AGENT mi ha toccato!”. In questo modo, questa stringa verrà intercettata dallo script del primo oggetto!

integer CHANNEL = 1234567890;

default {
	state_entry() {
		key owner = llGetOwner();
		llSetText("Oggetto che invia di "+llKey2Name(owner),<1.0,0.0,0.0>,1.0);
	}

	touch_start(integer total_number) {
		key agent = llDetectedKey(0);
		if(agent==llGetOwner()) {
			llOwnerSay("Invio messaggio '"+llKey2Name(agent)+" mi ha toccato!' sul canale "+(string)CHANNEL);
			llSay(CHANNEL, llKey2Name(agent)+" mi ha toccato!");
		}
		else {
			llInstantMessage(agent,"Non puoi toccare il mio oggetto!");
		}
	}

	changed(integer change) {
		if(change & CHANGED_OWNER) llResetScript();
	}
}

In tutti e due gli script è stata fatta un’aggiunta: l’evento changed. Questa è stata fatta per gestire un eventuale cambio di owner. In questo caso, infatti, l’intero script viene resettato per permettere la ridefinizione dei listener.

Possiamo provare il funzionamento del progetto in due modi:

  • Cliccando sul secondo oggetto;
  • Parlando sul canale (nel nostro caso ci basta scrivere nella chat “/1234567890 Prova!”).

Alla prossima lezione!

Seconda lezione di LSL

Giorno 26 Maggio si è tenuta la seconda lezione di LSL sempre alla Land del Forum. Oggetto della lezione, questa volta, la Comunicazione degli oggetti.

Abbiamo tre tipi fondamentali di comunicazione nel linguaggio LSL:

  • Comunicazione all’interno dell’oggetto, ovvero tra i prim che compongono l’oggetto;
  • Comunicazione tra un oggetto ed un altro oggetto o un Agent;
  • Comunicazione tra un oggetto e l’esterno.

Nella lezione ci siamo soffermati sulla comunicazione tra un oggetto e l’agent, ma abbiamo già predisposto l’oggetto per effettuare una comunicazione interna tra i prim che lo compongono. Abbiamo, infatti, creato un oggetto formato da due prim: un cubo come root e una piramide come child. Una primissima osservazione che abbiamo fatto è stata quella di notare la seguente differenza:

Uno script inserito nel prim root di un oggetto ha effetto su tutto l’oggetto, mentre uno script inserito in un prim child ha effetto esclusivamente su quel child.

Abbiamo notato questa differenza semplicemente inserendo lo script di default (quello che viene creato in automatico quando si crea un nuovo script) prima sul prim child e poi su quello root.

Ebbene, se inserito solo nel child ottenevamo la scritta “Touched.” esclusivamente se toccavamo il prim piramide dell’oggetto non nel cubo, mentre se inserito nel root ottenevamo la scritta “Touched.” sia se toccavamo la piramide sia se toccavamo il cubo.

Notata questa differenza, ci siamo inoltrati nello studio della Comunicazione tra oggetto ed Agent. Ci siamo quindi dedicati allo studio della funzione

integer llListen(integer canale, string nome, key id, string messaggio)

e del suo evento associato

listen(integer canale, string nome, key id, string messaggio)

I parametri di ingresso, come potete notare da soli, sono del tutto simili ed infatti assumono lo stesso significato:

Canale – Indica il canale di comunicazione. Vi ricordo che il canale pubblico ha valore 0 ed è identificato dalla costante PUBLIC_CHANNEL. Tutti gli altri canali, in un range compreso tra -2.147.483.648 a 2.147.483.647, sono i canali privati. Comunemente bisognerebbe utilizzare i canali negativi per interazioni tra oggetti e quelli positivi per interazioni con agent;
Nome – Indica il filtro di ascolto su un determinato nome;
Id – Indica il filtro di ascolto su una determinata key;
Messaggio – Indica il filtro su un determinato messaggio.

Il nostro intento è stato quello di creare uno script in ascolto su un canale privato della parola “Ciao” detta dall’owner, al quale l’oggetto doveva rispondere con messaggio “Ciao a te!” diretto esclusivamente
all’owner.

Abbiamo dovuto applicare i seguenti filtri alla funzione llListen:
Canale = 1
Nome = “”
Key = llGetOwner()
Messaggio = “Ciao”

Ovvero, abbiamo usato il canale 1, non abbiamo specificato il nome ma la key dell’owner dell’oggetto (recuperata in automatico grazie alla funzione llGetOwner()), ed abbiamo aggiunto il filtro “Ciao” al messaggio.

Tradotto in LSL, il comando da eseguire per impostare un ascoltatore è il seguente:

integer handler = llListen(1, "", llGetOwner(), "Ciao")

questo comando restituisce un handler dell’ascoltatore. Questo può essere usato per disattivare l’ascoltatore in un altro punto del codice. In questo nostro semplice script, abbiamo ignorato l’handler.

Una volta che abbiamo impostato il nostro ascoltatore, non ci resta che rispondere “Ciao a te!” quando viene sollevato l’evento ed il gioco è fatto!

Questo è lo script risultante:

default {
	state_entry() {
		llListen(1, "", llGetOwner(), "Ciao");
	}

	listen(integer canale, string nome, key id, string messaggio) {
		llOwnerSay("Ciao a te!");
	}
}

Per poterlo provare ci basta scrivere:

/1 Ciao

(vi ricordo che il “/1” iniziale significa “ridirigi questa stringa sul canale 1”. Infatti, questa comunicazione non viene letto in modo diretto da nessun agent, non essendo fatta nel canale pubblico).

Ricordatevi che c’è differenza tra “Ciao”, “CIAO” e “ciao”… il nostro script funziona solo con la prima stringa visto che il linguaggio LSL è case-sensitive!

Se tutto va bene il nostro oggetto ci risponderà con “Ciao a te!” e noi abbiamo completato con successo la nostra comunicazione tra Agent e Oggetto!

Alla prossima lezione!

Prima lezione di LSL

Lezione di LSL alla Land del Forum

Giorno 19 Maggio alle 21:30 si è tenuta la prima Lezione di Scripting LSL alla Land del Forum. Era la prima lezione ufficiale, in passato ne avevo tenuta un’altra per fare delle prove generali. Devo dire che nel complesso tutto è andato bene! Alcuni miei problemi legati al client: ho avuto tre crash e addirittura una schermata blu… ma forse quello è più un problema di Vista!

Il log completo della serata e tutte le foto della serata, compresa questa nel mio blog, sono disponibili nel Blog di Eleonora Porta.

Il tema della serata è stato quello di spiegare, banalmente, come è strutturato un listato LSL: che cosa sono gli stati, che cosa sono gli eventi, che cosa sono le funzioni. Fatto questo ci siamo dedicati allo studio di una funzione in particolare: llSetText, utile per visualizzare un testo sopra un prim. La firma della funzione è la seguente:

llSetText(string testo, vector colore, float alpha)

Testo – Indica il testo da visualizzare sopra il prim;
Colore – Indica il colore del testo nelle componenti RGB;
Alpha – Indica il livello di trasparenza in percentuale (1.0 totalmente opaco, 0.0 trasparente).

Molti dubbi sono nati con l’utilizzo del colore. Infatti, non si riesce a capire infatti come rappresentare un colore attraverso tre numeri. La questione è più semplice di quello che sembra. La totalità dei colori rappresentabili non sono altro che una combinazione dei tre colori del modello RGB (Red, Green, Blue).

Per fare qualche esempio:
la totale assenza dei tre colori indica il Nero;
la presenza contemporanea massima dei tre colori indica il Bianco;
la presenza massima delle sole componenti Red è Green indica il Giallo.

Quindi ci basta mischiare nella variabile vector colore la presenza in percentuale dei vari colori, per ottenere il colore voluto.

Alla fine della lezione abbiamo ottenuto il seguente codice:

default {
	state_entry() {
		llSetText("Esempio prima lezione LSL!",<1.0,0.0,0.0>,1.0);
	}
}

che visualizza il testo “Esempio prima lezione LSL!” di colore rosso sopra il prim.

Ringrazio tutti gli intervenuti alla Lezione e rinnovo l’appuntamento per la seconda lezione!