Gergo

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 ...

Origine del nome

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" ...

Caratteristiche della lingua

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.

Sintassi

Ecco un esempio di una funzione:

on multiplie(a, b) return a*b end multiplie

Tutte 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 if

Dopo 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 end

Variabili

Le 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.

Simboli

È 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.

Alcuni operatori e funzioni

gli operatori sono gli stessi sia che si confrontino interi, stringhe o altro.

Classi di base

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
Classi di gestione degli array Classe di elenco

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 metodi
  • list.sort () consente l'ordinamento crescente automatico.
  • list.add () consente di inserire dati in un elenco di output mantenendo l'ordinamento.
  • list.append () aggiunge un elemento alla fine dell'array, interrompe l'ordinamento
  • list.getOne (valore) esegue una ricerca automatica nell'array per trovare l'indice del valore
  • list.deleteOne (valore) trova l'indice del valore quindi elimina la cella
  • list.deleteAt (index) cancella un valore in corrispondenza di un indice specifico
  • list.addAt (index, value) inserisce un valore in corrispondenza dell'indice desiderato
Algebra degli array

Le 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 PropList

Contiene un array associativo. Gli identificatori possono essere:

  • simboli: myArray = [#age: 24, #sex: "male", #size: 1.80]
  • stringhe (attenzione, la lettura è molto lenta): monTableau = ["age": 10, "sex": "m"]

L'algebra è identica a quella delle liste lineari.

Classe Matrix

Codifica un array bidimensionale. Aggiunto alla v11 per l'atterraggio del motore Physx.

Classi di geometria 2d Classe di punti

Codifica 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 b

L'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 rect

Codifica 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 rettangoli

L'algebra dei rettangoli è identica a quella dei punti 2d.

Classe quadrupla

Codifica un quadrilatero. Utile soprattutto per la manipolazione delle immagini.

Classi di geometria 3D Classe di vettore

Codifica 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 10

Alcuni 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 vettori

L'algebra dei vettori 3d differisce da quella delle liste e dei vettori 2d:

  • divisione e modulo non sono consentiti
  • la moltiplicazione restituisce il prodotto scalare
vector (1,0,0) * vector (0,1,0) restituisce 0,0

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 classe

Codifica 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] = 0

Alcuni 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 trasformazioni

Algebra della matrice:

matrice1 * matrice2 è equivalente a moltiplicare matrix * vector restituisce il vettore trasformato dalla matrice

L'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 trasformate

Classi motori 3d

Classe di scena

Sottoclasse 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 Modelresource

Memorizza 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 modello

Fa 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 Physx

Ti 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.

Tipi di script

Ci sono 4 tipi di script in Lingo, due di tipo procedurale, due di tipo oggetto:

Script procedurali

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.

"sceneggiatura"

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:

  • on prepareMovie viene eseguito prima di visualizzare il primo fotogramma. Qui è dove prepariamo la schermata iniziale.
  • on startMovie viene eseguito dopo aver visualizzato il primo fotogramma. Qui è dove inizializziamo l'applicazione.
  • on stopMovie viene eseguito quando l'applicazione viene chiusa, è qui che il suo contenuto viene distrutto.

Eventi di aggiornamento dell'immagine:

  • we prepareFrame viene eseguito prima del rendering dell'immagine, qui è dove mettiamo i record di tempo.
  • su enterFrame viene eseguito per il tempo rimanente prima di eseguire il rendering dell'immagine successiva, che è dove inseriamo tutti i calcoli.
  • su exitFrame viene eseguito appena prima di spostare la testina di riproduzione, qui è dove indichiamo l'immagine che dovrebbe renderizzare (con vai a)

Evento indipendente:

  • in caso di inattività viene eseguito a un intervallo multiplo di 16 millisecondi (60 fotogrammi al secondo). Qui è dove mettiamo il codice indipendente dal frameRate dell'applicazione.

Eventi del mouse:

  • on mouseDown e mouseUp , chiamati quando il mouse viene premuto o rilasciato.

I cosiddetti copioni dell'attore

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.

Script di oggetti

I cosiddetti script "genitori"

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 end

Se 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 statica

Uno 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'ancestor

Script o "comportamenti" dell'applicazione

Si 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 .

Implementazioni

Lingo è un linguaggio proprietario, quindi c'è solo un'implementazione.

Comandi Lingo e sintassi javascript

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.