Lingo è il linguaggio di scripting che accompagna il software Macromedia Director .
L'autore di Lingo è lo sviluppatore John Henry Thompson. Il gergo è stato arricchito da molte aziende che hanno sviluppato xtras , tra cui intel , ageia, havok ...
La parola Lingo significa in gergo inglese , in senso volgare , una lingua specializzata appartenente a un gruppo specifico (es. Gergo dei tipografi).
A differenza dei più diffusi linguaggi di livello 4 (basic, javascript ...), il gergo script non riproduce i concetti di programmazione in modo identico ma li riorganizza a suo modo per un'applicazione efficiente e semplice. Per contrassegnare la distinzione utilizza termini diversi, ad esempio "array" viene rinominato "list", una classe viene chiamata "parent script" ...
Lingo attualmente usa la sintassi BASIC .
Lingo originariamente aveva una sintassi dettagliata derivata dal linguaggio HyperTalk utilizzato nel software di authoring HyperCard distribuito su MacIntoshes dal 1986. Originariamente era inteso per essere il più leggibile possibile per chi parla inglese.
Ecco un esempio di una funzione:
on multiplie(a, b) return a*b end multiplieTutte le funzioni iniziano con [nome funzione] [(argomenti)] e finiscono con [nome funzione] . Lingo è un linguaggio molto rilassato, ad esempio ci è permesso non mettere parentesi dopo il nome della funzione (moltiplichiamo a, b).
Nota, le variabili sono tipizzate dinamicamente e non c'è differenza tra l'assegnazione "=" e il confronto "=".
if a=1 then b=2 else if a="une chaîne" then b=3 end if end ifDopo anni di evoluzione sintattica, Lingo è diventato un linguaggio "point-in" abbastanza classico, e quindi molto leggibile.
Director è un software dedicato all'interattività. Pertanto, Lingo consente una facile intercettazione di un gran numero di eventi come: preparemovie (prima della visualizzazione), startmovie (al momento della visualizzazione), mousedown (clic giù), mouseup (clic rilasciato), ecc. Alcuni script di intercettazione di eventi riguardano l'intero programma, altri possono essere applicati solo a oggetti specifici, come gli sprite (occorrenza di un oggetto, ad esempio grafico, sullo stage ).
on mouseup -- lorsque l'on clique sur l'objet auquel s'applique ce script'' if the mouseh<320 then -- si la position horizontale de la souris est inférieure à 320 puppetsound(1, "bing") -- on déclenche le son nommé "bing" sur la piste 1. end if endLe variabili numeriche in gergo sono semplificate. Le variabili globali o oggetto vengono dichiarate solo al di fuori delle funzioni. Le variabili locali vengono dichiarate implicitamente.
La digitazione è implicita, quindi:
Non ci sono variabili booleane, il gergo utilizza gli interi 0 e 1, che per ragioni di leggibilità possono comunque essere scritti come veri e falsi.
Le stringhe possono essere lette come array utilizzando la variabile globale "itemDelimiter" e la priorità .item delle stringhe o le proprietà .line e .word delle stringhe.
i nomi delle variabili possono contenere lettere, numeri o il segno di sottolineatura. Non possono iniziare con un numero.
È possibile creare simboli con il segno di cancelletto ( # ). Un simbolo non è una variabile ma un nome di variabile o funzione.
Ad esempio, in myColor = #red , la parola #red non significa nulla per Lingo; d'altra parte, myColor = colors [#rouge] ti permette di trovare la proprietà red dell'oggetto colors, la funzione call (#rouge, obj, arguments ...) ti permette di chiamare il metodo red dell'oggetto obj.
Lingo ha un elenco di classi corrispondenti alle strutture dati classiche, con importanti automazioni.
classe di gergo | dati corrispondenti |
elenco | matrice lineare |
propList | array / struttura associativa |
matrice | Array bidimensionale |
punto | Vettore 2d |
rect | rettangolo 2d |
vettore | Vettore 3D |
trasformare | Matrice 3d |
La classe list contiene una matrice di memoria dinamica. Questi array sono "a base uno", il primo indice è uguale a 1. Ciò consente di utilizzare lo zero come identificatore nullo quando si fa riferimento agli indici.
Scrivere o leggere il contenuto di una cella è un'operazione pesante quanto la sintassi puntata (più lenta su liste grandi che su quelle piccole). Per ottimizzare le operazioni sugli array, utilizzare il più possibile l'algebra degli array, che evita molte letture di celle.
Gli elenchi vengono creati come segue:
myArray = [] o myArray = [1,2, "a", 0, "b"]Gli array possono contenere qualsiasi tipo di dati:
myArray = [[1, vector (1,2,3)], [model1, image12]] Alcuni metodiLe tabelle possono utilizzare tutti i tipi di operatori compatibili con il contenuto delle celle. Ciò consente una notevole accelerazione dei loop di calcolo poiché vengono poi gestiti in modo nativo.
Esempi con numeri interi e decimali:
[1,2,3] + [4,5,6] restituisce [5,7,9] [1,2,3] - [1,1,1] restituisce [0,1,2] [1,2,3] * [1,2,3] restituisce [1,4,9] [1,1] / [2,2.0] restituisce [0,0.5] [1,1] mod [2,2.0] restituisce [1,1] [1,2] > [2,1] restituisce false (0)Per esempi con array di vettori e matrici, vedere le classi vector e transform.
Classe PropListContiene un array associativo. Gli identificatori possono essere:
L'algebra è identica a quella delle liste lineari.
Classe MatrixCodifica un array bidimensionale. Aggiunto alla v11 per l'atterraggio del motore Physx.
Classi di geometria 2d Classe di puntiCodifica un vettore 2d. Le sue coordinate sono chiamate "locH" e "locV". Possono essere interi o decimali.
p = punto (a, b)I dati vengono letti dalle proprietà locV / locH o come array:
p.locH o p [1] restituisce a p.locV o p [2] restituisce bL'algebra vettoriale 2d si comporta esattamente come l'algebra degli array e può essere combinata con:
punto (1,1) + punto (2,2) restituisce il punto (3,3) [p1, p2] + [p3, p4] restituisce [p1 + p3, p2 + p4] Classe rectCodifica un rettangolo. I valori possono essere interi o decimali.
: r = rect (sinistra, in alto, a destra, in basso) : r.left, r.top, r.right, r.bottom or r [1], r [2], r [3], r [4] return le sue coordinate : r.width e r.height restituiscono la sua larghezza e altezza
Alcuni metodi:
r1.intersects (r2) restituisce il rettangolo di intersezione tra due rettangoli point.inside (r1) restituisce true se il punto è all'interno del rettangolo map (targetRect, sourceRect, destinationRect) esegue un homothety del punto map (targetPoint, sourceRect, destinationRect) esegue un homothety del rettangolo rect1.union (rect2) restituisce il rettangolo che racchiude altri due rettangoliL'algebra dei rettangoli è identica a quella dei punti 2d.
Classe quadruplaCodifica un quadrilatero. Utile soprattutto per la manipolazione delle immagini.
Classi di geometria 3D Classe di vettoreCodifica un vettore 3d. Solo numeri decimali.
v = vettore (10,20,30)È possibile accedere alle sue coordinate in due modi: con le proprietà x, y, z o con l'indice di dimensione:
vx o v [1] restituisce 10Alcuni metodi:
vector.magnitude restituisce la lunghezza vector.normalize () gli dà una lunghezza uguale a 1 senza cambiarne la direzione vector1.cross (vector2) restituisce il prodotto di due vettoriL'algebra dei vettori 3d differisce da quella delle liste e dei vettori 2d:
L'algebra dei vettori può essere combinata con quella degli array.
[vettore (1,0,0), vettore (0,1,0)] + [vettore (0,1,0), vettore (1,0,0)] restituisce [vettore (1,1,0), vettore (1,1,0)] [vector (1,0,0), vector (0,1,0)] * [vector (0,1,0), vector (1,0,0)] restituisce [0,0] Trasforma la classeCodifica una matrice di trasformazione 3D composta da 16 cifre decimali.
matrice = trasformazione ()I primi 3 gruppi di 4 numeri codificano i 3 vettori del sistema di coordinate. L'ultimo gruppo codifica l'origine. (il 4 ° numero di questi gruppi viene utilizzato per i calcoli interni).
Esempio: scegli il vettore (0,0,1) per l'asse X:
matrice [1] = 1 matrice [2] = 0 matrice [3] = 0Alcuni metodi:
matrix.invert () inverte la matrice matrix.inverse () restituisce l'inverso della matrice matrix.rotate () matrix.translate () esegue una trasformazione assoluta matrix.preRotate () matrix.preTranslate () esegue una trasformazione relativa matrix1.multiply (matrix2) restituisce la matrice 2 trasformata dalla matrice 2 matrix1.preMultiply (matrix2) restituisce la matrice 2 trasformata dalla matrice 1 in relativa matrix1.interpolate (matrix2, percentuale) restituisce l'interpolazione tra due trasformazioniAlgebra della matrice:
matrice1 * matrice2 è equivalente a moltiplicare matrix * vector restituisce il vettore trasformato dalla matriceL'algebra delle matrici può anche essere combinata con gli array:
[matrice1, matrice2] * [vettore1, vettore2] restituisce la matrice di vettori trasformati [matrice1, matrice2] * [matrice3, matrice4] restituisce l'array di matrici trasformateSottoclasse di "membro" che viene visualizzato come sprite e consente il rendering di una scena 3D con directx o opengl
Segue un pattern di tipo "factory": tutti gli elementi della scena 3d vengono istanziati e distrutti utilizzando i metodi della classe scene. Eccone alcuni:
Classe ModelresourceMemorizza i buffer dei vertici ("mesh") e fa riferimento agli shader per impostazione predefinita.
Nota: i suoi metodi di costruzione non seguono la struttura del buffer di vertice, ogni triangolo viene inserito indipendentemente. Una volta chiamato il metodo build (), i vettori vengono ordinati per gruppo utilizzando lo stesso shader, i vertexBuffer risultanti sono accessibili tramite il modificatore #meshDeform dei modelli che utilizzano la risorsa.
Classe modelloFa riferimento a una matrice, un elenco di shader e una risorsa modello. Genera automaticamente una boundingSphere. La classe del modello viene utilizzata per visualizzare modelResource. Il suo modificatore #meshDeform fornisce l'accesso al vertexBuffer di modelResource.
Classe PhysxTi consente di controllare una scena 3D con il motore Physx nvidia. Sottoclasse di membri extra, controlli come un classico script xtra.
Segue il modello di fabbrica che consente di creare vari oggetti fisici: convesso, concavo, tessuto, carattere, ecc. Richiede il modificatore #meshDeform per leggere le strutture poligonali.
Ci sono 4 tipi di script in Lingo, due di tipo procedurale, due di tipo oggetto:
Usa solo variabili e funzioni globali. Il loro utilizzo deve rimanere limitato perché le variabili globali consumano cpu e ram: vengono duplicate nell'interprete javascript.
Gli script oggetto vengono utilizzati il più possibile, gli script procedurali solo quando necessario.
Questi sono gli script utilizzati per il codice procedurale.
Questi script ricevono alcuni eventi funzione predefiniti che corrispondono all'apertura dell'applicazione, alla sua chiusura, all'aggiornamento dell'immagine.
Eventi di apertura e chiusura:
Eventi di aggiornamento dell'immagine:
Evento indipendente:
Eventi del mouse:
Questi sono script che si trovano direttamente all'interno di un attore. Il loro tipo non è definito ma funzionano come "copioni cinematografici".
Ricevono il mouse e aggiornano gli eventi quando un'istanza dell'attore è visibile.
Permette di simulare classi di oggetti. La sintassi dei metodi rimane procedurale: è necessario passare un riferimento all'oggetto "me" come primo argomento.
classe istanziabile un esempio di uno script genitore istanziato: -- propriétés property pNombre -- méthodes constructeur et destructeur on new me, n , obj pObject = obj pNombre = n return me end on delete me pObject = void end -- méthodes utilisateur on incremente me pNombre = pNombre +1 endSe questo script si chiama "numero", lo istanziamo ad esempio in questo modo:
monNouveauNombre = new(script "nombre", 10, obj)e invocheremo la sua funzione di "incremento" in questo modo:
monNouveauNombre.incremente() classe staticaUno script genitore può fungere da classe statica.
Accediamo al suo riferimento in questo modo:
myStaticClass = Script("script_name") ereditàL'ereditarietà di Lingo non funziona come nei classici linguaggi a oggetti, si basa sulla proprietà "antenato" degli script genitore, che corrisponde a un'istanza della classe genitore. Non si tratta quindi di eredità ma di sovraccarico.
Director torna automaticamente alle proprietà dell'oggetto antenato dal riferimento figlio, il che rende possibile trovare l'effetto di una classe ereditata. Quindi attenzione al valore dell'argomento "me": deve sempre corrispondere all'istanza di ultima generazione.
Questo non funziona per tutte le proprietà e i metodi delle classi director native (nel qual caso devi puntare all'antenato).
Esempio di simulazione di una sottoclasse di Listproperty ancestor on new ( me ) -- sous classe de l'objet list ancestor = [1,10,20,30] return me -- attention: on ne renvoie pas "ancestor" mais "me" end obj=new Script( "testClass" ) put obj[ 1 ] -- on retrouve les propriétés de l'ancestorSi tratta di oggetti complessi il cui script non è direttamente accessibile. Contengono molti eventi che consentono di interagire con gli sprite, il mouse, la tastiera, ad esempio per creare pulsanti o editor di testo.
Gli script di comportamento vengono spesso sviluppati per essere riutilizzati da grafici o integratori. Semplicemente trascinando e rilasciando questi script vengono allegati agli oggetti nella scena: immagine, sprite, attore, frame ... Questi script hanno funzioni predefinite che consentono di configurare manualmente le istanze così come i componenti flash .
Lingo è un linguaggio proprietario, quindi c'è solo un'implementazione.
Dalla sua versione MX2004 , il software Director accetta l'uso di due linguaggi differenti: Lingo e un'implementazione di JavaScript / ECMAScript che esegue gran parte delle operazioni in gergo.