Flash: array multidimensionali e depth

Di: alice33 | 26/09/2020 18:29:17
Ho trovato in rete questo esempio di quiz tramite drag & drop, con verifica annessa e ho cercato di studiarmelo un po' per vedere se riesco a fare qualcosa del genere. Però non riesco a capire bene il codice....
Mi pare di capire che usa un array con due dimensioni.... Qualcuno gentilmente potrebbe spiegarmi come funzionano?
... E poi: ho provato ad aggiungere una funzione al fla, in modo che se tutte le risposte sono corrette compaia un pulsante per passare al frame successivo; però una volta passati al frame successivo una delle etichette rimane nello stage e non capisco perchè
http://downloads.flashkit.com/movies/Scripting/drag_n-Andrew_K-11475/drag_n-Andrew_K-11475.zip

Risposte



Ciao Alice,
Un Array può contenere al suo interno diversi tipi di dati, questi dati possono essere variabili (String, Number, Boolean), possono essere oggetti, e possono essere altri Array.
Se gli elementi di un Array sono a loro volta Array si parla di Array multidimensionali.
Sembra una cosa complicata ma non lo è.
Vediamo subito un esempio:
var frutta:Array = new Array("mela", pera", "pesca", "arancia");
Questo è un Array ad una dimensione, contiene quattro elementi che possiamo richiamare utilizzando il loro indice numerico:
frutta[0] = "mela";
frutta[1] = "pera";
frutta[2] = "pesca";
frutta[3] = "arancia";
E fin qui ci siamo....
Ma ora abbiamo bisogno di memorizzare per ogni frutto il suo colore, quindi per ogni frutto creiamo un Array che contiene nome e colore:
var array0:new Array = Array("mela", "rossa");
var array1:new Array = Array("pera", "verde");
var array2:new Array = Array("pesca", "rosa");
var array3:new Array = Array("arancia", "arancione");
Abbiamo 4 Array abbastanza inutili, li mettiamo tutti dentro ad un Array “padre”...
var frutta:Array = new Array(array0, array1, array2, array3);
Abbiamo creato un Array di Array, per richiedere un elemento di questo Array possiamo affidarci sempre al suo indice numerico:
frutta[0] = ["mela", "rossa"];
Di conseguenza se vogliamo accedere direttamente a uno dei due valori di questo elemento dobbiamo utilizzare due volte gli indici:
frutta[0][0] = "mela";
frutta[0][1] = "rossa";
Perché se “frutta[0]” è un Array, questo Array ha degli indici, come tutti gli altri.
Per fortuna è possibile abbreviare tutto quello che abbiamo scritto fin’ora, possiamo creare un Array multidimensionale uguale all’ultimo che abbiamo visto scrivendo una volta sola questo rigo:
frutta = [["mela", "rossa"], ["pera", "verde"], ["pesca", "rosa"], ["arancia", "arancione"]];
Il risultato è sempre lo stesso... abbiamo un Array chiamato frutta, questo Array contiene quattro elementi, ognuno di questi quattro elementi è un Array che contiene due elementi.
Ora aggiungiamo le terza dimensione, sappiamo di avere quattro elementi che sono frutti, che ognuno di questi elementi ha il suo nome all’indice 0 e il suo colore all’indice 1, il nome e il colore sono scritti in italiano.
Il cliente ci dice che vuole memorizzare anche i nomi e i colori in inglese!!!
Per memorizzare un’altra lingua faremo in modo che ogni elemento di ogni Array figlio sia a sua volta un Array, questo conterrà la parola in italiano all’indice 0 e la stessa parola in inglese all’indice 1.
frutta = [[["mela", "apple"], ["rossa", "red"]], [["pera", "pear"], ["verde", "green"]], [["pesca", "peach"], ["rosa", "pink"]], [["arancia", "orange"], ["arancione", "orange"]]];
Ecco fatto, ora voglio sapere il colore, in inglese, del terzo frutto, lo chiedo così:
frutta[2][1][1]
Si legge partendo da destra: Elemento numero 1 (in lingua inglese), dell’elemento numero 1 (il colore), dell’elemento numero 2 dell’Array “frutta”.
Ora passiamo a “non scompare l’ultimo elemento che ho draggato”.
La colpa è della profondità... i movieclip con un valore di Depth troppo alto saltano fuori dalla _root e non ne seguono il destino.
Il filmato cambia la Depth dei clip per farli venire in primo piano, quindi il movieclip che sposti assume profondità 0 (che tu ci creda o no è un valore altissimo), per questo motivo l’ultima clip che hai toccato non rimane al suo fotogramma e ti segue ovunque tu vada.
Per ovviare a questi inconvenienti io faccio sempre un controllo preventivo sulle profondità, così mi faccio dare “il più basso valore di Depth per essere in primo piano”.
Per il filmato che usi tu ho scritto questo:
for (i=1; i<=5; i++) {
num = _root["a"+i].getDepth();
myDepth = (num>myDepth||isNaN(myDepth))?num:myDepth;
}
Che chiede i valori di profondità iniziali delle clip a1, a2, a3, a4, a5 e mi restituisce il valore più alto (per la cronaca -16358)... poi uso questo valore al posto di 0 nello script che cambia la Depth, cioè nelle azioni dei movieclip di risposta:
on (press) {
this.startDrag();
_root.clearDrop(this._name, 4);
this.swapDepths(0);
}
Diventa così:
on (press) {
this.startDrag();
_root.clearDrop(this._name, 4);
this.swapDepths(_root.myDepth);
}

Di: Professore | 26/09/2020 18:29:17


Grazie mille, Professore! Chiaro, esaustivo e disponibile come sempre! Lo script che mi hai scritto per ovviare al problema dell'etichetta "appiccicosa" funziona benissimo! Da sola non sarei mai riuscita nè a capire il motivo nè a inventarmi una cosa del genere!
Sto cercando di comprendere bene il funzionamento dell'esempio che ho scaricato: è comodo modificare un fla esistente per piegarlo alle proprie esigenze, ma io vorrei IMPARARE a scriverli da sola, perciò devo ben capire cosa fa il codice...
Dunque: ho capito che è stato creato un array con 2 dimensioni, una per i target (q)e una per le etichette (a); le due dimensioni altro non sono che due array distinti, poi riuniti in un altro array "padre".
E fin qui credo di esserci.
Però non capisco bene il sistema che permette prima di far agganciare le etichette ai target e poi di verificare se il target è giusto oppure no...
sul frame c'è
myAnswers = [[1, 1], [2, 2], [3, 5], [4, 4]];// e questo è l'array padre
function doDrop(dragSprite, numTargets) {
for (i=1; i<numTargets+1; i++) {
if (_root[dragSprite].hitTest("_root.q"+i)) {
if (_root["q"+i]._currentframe<>2) {
_root[dragSprite]._x = _root["q"+i]._x+5;
_root[dragSprite]._y = _root["q"+i]._y+2;
_root["q"+i].gotoAndStop(2);
} else {
_root[dragSprite]._x = _root[dragSprite].stx;
_root[dragSprite]._y = _root[dragSprite].sty;
}
}
}
}
function clearDrop(dragSprite, numTargets) {
for (i=1; i<numTargets+1; i++) {
if (_root[dragSprite].hitTest("_root.q"+i)) {
if (_root["q"+i]._currentframe == 2) {
_root["q"+i].gotoAndStop(1);
break;
}
}
}
}
.... Current frame indica il frame dell'animazione del target, che ha al suo interno le 4 posizioni "vuoto","con etichetta", con segnalazione giusto e con segnalazione sbagliato. _root["q"+i]è l'array dei target;_root["a"+i]è l'array delle etichette;
Però: come fa flash a capire che _root[dragSprite]è la root di ogni etichetta e _root[numTargets] quella dei target? basta la funzione
function doDrop(dragSprite, numTargets) {
for (i=1; i<numTargets+1; i++)
per inizializzare l'array "padre" e i due array "figli"?
Nel codice del pulsante, al rilascio c'è
for (i=1; i<5; i++) {
Q = _root.myAnswers[i-1][0];
A = _root.myAnswers[i-1][1];
if (_root["q"+Q].hitTest("_root.a"+A)){
_root["q"+Q].gotoAndStop(3)... eccetera;
...E qui, dove si verificano le risposte, mi perdo...Perchè [i-1]?
Scusate le ulteriori richieste di spiegazioni... lo so, sono una rompi.... Ma vorrei capire davvero, altrimenti non riuscirò mai a fare da sola, resterò una "copiona"!
Grazie per la pazienza

Di: alice33 | 26/09/2020 18:29:17


Ciao Alice,
ti faccio luce su alcune questioni che ti agevoleranno non poco il lavoro...
Per riferirti ad un’istanza di movieclip che si chiama “mio_mc”, che sta sulla _root, puoi scrivere:
_root.mio_mc;
Oppure puoi scrivere anche:
_root[“mio_mc”];
Questa sintassi (simile a quella che si usa per gli Array) è molto comoda per i casi in cui non sappiamo in anticipo a quale movieclip vogliamo riferirci.
Se per esempio facciamo una funzione che deve comandare di volta in volta un movieclip diverso possiamo passare il nome istanza dentro una variabile, successivamente useremo la variabile all’interno delle parentesi quadre che hai visto sopra:
function scompare(chi) {
_root[chi]._alpha = 0;
}
Quando richiamiamo la funzione gli passiamo il nome del movieclip che vogliamo fare scomparire:
scompare(“mio_mc”);
Il nome “mio_mc” viene inserito nella variabile “chi” e quindi la funzione si comporterà come se al suo interno ci fosse scritto:
_root[“mio_mc”]._alpha = 0;
che equivale a:
_root.mio_mc._alpha = 0;
Ecco perché è comoda la sintassi con le parentesi quadre.
prima si usava eval(.....); e ancora oggi è utile in alcuni casi, ma per i movieclip va bene la sintassi a parentesi quadre
Andiamo avanti con un altro esempio...
Ho 10 movieclip e devo impostare per tutti un’alpha al 50%.
Per fortuna i miei movieclip si chiamano “mc1”, “mc2”, “mc3”, ..., “mc10”.
Posso creare un ciclio da 1 a 10 e cambiare l’alpha a tutti in tra righe!!!
for (i=1; i<=10; i++) {
_root[“mc”+i]._alpha = 50;
}
Perché non importa cosa passo dentro alle parentesi quadre, l’importante è che il risultato sia una Stringa che rappresenti il nome della mia istanza.
Il ciclo di sopra compie lo stesso lavoro di questa noiosa lista qui sotto:
_root.mc1._alpha = 50;
_root.mc2._alpha = 50;
_root.mc3._alpha = 50;
_root.mc4._alpha = 50;
_root.mc5._alpha = 50;
_root.mc6._alpha = 50;
_root.mc7._alpha = 50;
_root.mc8._alpha = 50;
_root.mc9._alpha = 50;
_root.mc10._alpha = 50;
Ora veniamo al tuo filmato:
La funzione doDrop e la funzione clearDrop si occupano solo del trascinamento.
Se rilasci sopra una casella allora aggiusta la posizione sulla casella, altrimenti riporta alla posizione originale.
Il controllo avviene così:
for (i=1; i<5; i++) {
//Da uno a quattro (perché minore di cinque vuol dire che cinque non sarà incluso)
Q = _root.myAnswers[i-1][0];
//La variabile Q equivale alla posizione 0 dell’Array che si trova in posizione i-1.
//Bisogna sottrarre 1 perché gli indici dell’Array partono da zero, qui invece abbiamo i numeri da uno a quattro.
A = _root.myAnswers[i-1][1];
//La variabile A equivale alla posizione 1 dell’Array che si trova in posizione i-1.
if (_root["q"+Q].hitTest("_root.a"+A)){
/*------------------------
Se il clip che si chiama “q più il numero di domanda”
Tocca (hitTest)
Il clip che si chiama “a più il numero di risposta corrispondente”
------------------------*/
Etcetera etcetera etcetera....
Ora vado a lavoro che sono in ritardo...
A presto.

Di: Professore | 26/09/2020 18:29:17


Grazie Professore! La spiegazione è stata illuminante!

Di: alice33 | 26/09/2020 18:30:17


Professore, sono di nuovo qui.... Ho ripreso in mano il piccolo quiz che stavo facendo e ho ancora un problemino con la depth. Il codice che gentilmente mi hai scritto per l'inconveniente dell'etichetta "appiccicosa" funziona solo nei primi tre frame. Poi il problema ricomincia Da cosa può dipendere? Ho copiato e incollato lo script come nei frame precedenti....
Approfitto dell'occasione per augurare BUONE FESTE a tutti!!

Di: alice33 | 26/09/2020 18:30:17