Introduzione
Passiamo alla terza sezione esterna: in questa creeremo delle finestre trascinabili e minimizzabili, contenenti del testo. Le finestre
potranno essere portate in primo piano semplicemente cliccandoci sopra, come quelle di Windows, per intenderci. Inoltre, nel nostro filmato,
creeremo un'unica finestra: a decidere il numero e il contento, sarà un file di testo esterno.
Come dalla funzione del menu, il filmato dovrà chiamarsi finestre.swf. Quindi creiamo un nuovo progetto Flash, con le stesse caratteristiche
dei precedenti, e anche in questo importiamo il movieclip base. Infine salviamo con il nome finestre.fla
Le finestre
Disegno
Apriamo il file finestre.fla: clicchiamo sul pulsante + nella libreria, e aggiungiamo un movieclip che chiameremo finestra.
All'interno di questo movieclip, creiamo 7 layer di due frame ciascuno, con i nomi come quelli in figura.
Prima di tutto, in un layer qualsiasi, al primo frame mettiamo uno stop(). Nel layer "base", in basso, trasciniamo dalla libreria
un'istanza del movieclip base: come dimensioni assegniamo 200x130, lo posizioniamo con il lato superiore al centro del movieclip,
ruotato di 180 gradi, in modo che sembri in rilievo.
Nel secondo frame dello stesso layer, posizioniamo un'altra istanza del movieclip base, sempre nella stessa posizione rispetto al
movieclip, solo che questa volta le dimensioni saranno 200x22. Infatti, il secondo frame del movieclip finestra, conterrà la grafica della
finestra ridotta.
Andiamo al primo frame del layer "interno". Trasciniamo dalla libreria un'istanza del movieclip base, come dimensioni
assegniamo 195x105, per poi posizionarla alle coordinate -97.5,22. Associamo al movieclip:
onClipEvent(load){
colore = new Color(rettangolo);
colore.setRGB(0xEEEEEE);
}
in modo che appaia (ma solo il rettangolo all'interno, a cui si riferisce lo script), più scuro di quello di base. Il secondo frame lo
lasciamo vuoto.
Andiamo al primo frame del layer "rettangolo", nel quale trasciniamo dalla libreria un'istanza del movieclip rettangolo.
Lo stesso contenuto (con F5), lo passiamo anche al secondo frame, e assegniamo come nome di istanza rettangolo. Allo stesso modo, nei
due frame del layer cornice, inseriamo un'istanza del movieclip cornice, che tingeremo di nero tramite il pannello Effetti. Se esportiamo
adesso, questo è quello che vediamo.
Nell'unico frame del layer "testo", inseriamo una casella di testo della grandezza del rettangolo in "interno": le
opzioni saranno testo dinamico, multi-linea, html, variabile associata testo. Nel layer "titolo", inseriamo in entrambi i
frame una casella di testo delle dimensioni della barra alta, con queste opzioni: testo dinamico, linea singola, html, variabile associata
titolo.
Dal layer "rettangolo", copiamo il movieclip rettangolo, e incolliamolo nei due frame uniti del layer "pulsante".
Selezioniamo il rettangolo, e premiamo F8. Nella finestra di dialogo per convertire in simbolo, scegliamo button, e come nome diamo
pulsante.
Editiamo ora il pulsante, facendo doppio click su di esso: quello che vogliamo fare, è renderlo trasparente. La timeline interna del pulsante
sarà come nella prima figura: noi clicchiamo sul primo frame, e trasciniamo il contenuto nell'ultimo, come nella seconda figura.
Â
Adesso il pulsante non ha più niente nel frame Up, e quindi non è visibile: tuttavia, ha il rettangolo nel frame Hit (rettangolo a cui
togliamo il nome di istanza), quindi è cliccabile. Usciamo dal pulsante e associamogli:
on (press) {
rettangolo.colore.setRGB( 0xFF9900 );
_root.swap(_name);
startDrag (this, false,
_width/2, 0, 700-_width/2,
300-_height);
if (!premuto) {
if (getTimer()-click<300) {
if (!chiuso) {
nextFrame();
} else {
prevFrame ();
}
chiuso = !chiuso;
} else {
click = getTimer();
}
}
}
on (release) {
rettangolo.colore.setRGB( 0xFFCC33 );
stopDrag ();
}
Vediamo come funziona lo script: quando clicchiamo sul pulsante, questo richiama una funzione che sta nella root, e che si chiama swap.
A questa funzione, passa come parametro il nome di istanza del movieclip finestra in cui è contenuto: questo servirà a far capire alla
funzione, da quale finestra proviene la chiamata.
Inoltre, fintantoché il pulsante è cliccato, possiamo trascinare il movieclip, entro dei limiti che sono quelli del filmato: non possiamo
quindi far uscire una finestra dall'area visibile.
Un altro controllo, con il getTimer, viene effettuato per stabilire se l'ultimo click sia avvenuto meno di tre decimi di secondi prima:
se la risposta è negativa, la finestra non cambia aspetto, altrimenti, se aperta si chiude, e se chiusa si apre. Questa è la simulazione di un
doppio click, mentre l'apertura e la chiusura della finestra vengono effettuate mandando il movieclip avanti o indietro di un frame.
Infine, finché il pulsante è premuto, è di colore arancione; quando viene rilasciato, diventa giallo.
// quando il mouse viene premuto
on (press) {
// setta colore in rettangolo come arancione
rettangolo.colore.setRGB( 0xFF9900 );
// chiama la funzione "swap" passando come parametro il nome del
// movieclip che contiene il pulsante
_root.swap(_name);
// trascina la finestra entro i limiti del filmato
startDrag (this, false,
_width/2, 0, 700-_width/2,
300-_height);
// se la variabile "premuto" è falsa
if (!premuto) {
// il click precedente è sato meno di tre decimi di secondo fa
if (getTimer()-click<300) {
// se la variabile "chiuso" è false
if (!chiuso) {
// vai al frame seguente
nextFrame();
// altrimenti
} else {
// vai al frame precedente
prevFrame ();
}
// setta il valore della variabile "chiuso" come il suo opposto
chiuso = !chiuso;
// altrimenti (più di tre decimi di secondo)
} else {
// resetta la variabile per il calcolo del doppio click
click = getTimer();
}
}
}
// al rilascio
on (release) {
// setta colore in rettangolo come giallo
rettangolo.colore.setRGB( 0xFFCC33 );
// smetti di trascinare il movieclip finestra
stopDrag ();
}
La funzione che viene richiamata, e che sta nel primo frame del filmato, al livello della timeline principale, è questa:<
function swap (nome) {
if (alto != nome) {
_root[nome].swapDepths(++num);
_root[alto].rettangolo.colore.setRGB( 0x999999 );
alto = nome;
}
}
La funzione riceve il nome del movieclip contenente il pulsante da cui arriva la chiamata: se questo nome è diverso da quello contenuto nella
variabile alto, (e quindi lo stesso pulsante non esegue questa azione due volte di seguito), allora mette il movieclip finestra in cima
alla lista dei livelli dei duplicati, mentre cambia in grigio il colore del rettangolo in quello precedente.
Piccola digressione: i duplicati di un movieclip, vengono posizionati in livelli assimilabili ai level dei filmati. Ogni duplicato deve stare
in un livello diverso dagli altri: se un duplicato viene posizionato in un livello dove ne è già presente un altro, quest'ultimo lascia il
posto al nuovo arrivato. Inoltre, come nei level, il livello con il valore più elevato copre quelli con il valore inferiore.
La sequenza di numeri che rappresentano i livelli in cui sono posizionati i movieclip, determina l'ordine di
"impilamento", e il livello
determina la profondità del movieclip. Con lo swapDepths(), alla base della funzione, si possono scambiare due movieclip di livello: se lo
eseguo su un movieclip sul livello 3, e su uno sul livello 10, il primo andrà al livello 10, e il secondo al livello 3. Non solo, è possibile
anche assegnare ad un movieclip il livello su cui posizionarsi, senza dover prendere il posto di un altro.
La variabile num, presente nella funzione, contiene proprio il numero dei livelli iniziali: se all'apertura del filmato ho
stabilito di avere 3 finestre, num sarà uguale a 3. Quando richiamo la funzione swap dal movieclip presente nel livello 1, il
valore di num viene aumentato di una unità, e diventa 4: allora il movieclip da cui viene la chiamata, viene posizionato nel livello 4, sopra
tutti gli altri (il più alto stava nel 3). La volta dopo, il movieclip chiamante verrà posizionato nel livello 5, poi in quello 6, e così
via.
Questo sistema presenta dei vantaggi e degli svantaggi. E' il più semplice in assoluto, ed è efficace, non presentando il bug proprio
dello swap depth tra due movieclip (se ho tre movieclip, dal basso verso l'alto l'uno, il due, e il tre, e scambio di profondità il
primo con il terzo, il primo andrà in cima, ma il terzo andrà in fondo: in Windows non è così,
poiché la finestra cliccata va in cima, ma la
sequenza di tutte quelle dietro resta inalterata).
Lo svantaggio, in via teorica, ci sarebbe con un gran numero di finestre, o con un gran movimento delle stesse. Aumentando sempre di più il
valore dell'impilamento massimo, si potrebbe giungere al limite del lettore. Magari dovrei cliccare 16.000 volte le finestre, per
arrivarci: improbabile ma possibile. D'altronde, per evitare questo problema, dovrei utilizzare un sistema che ad ogni cambio di
profondità, sposti tutte le finestre per compattarle nel minor numero di livelli possibili, senza buchi, spostandole tutte verso il basso.
Per i nostri scopi, decisamente eccessivo.
Stage
Andiamo alla timeline principale: trasciniamo sullo stage, dalla libreria, un'istanza del movieclip finestra, e assegniamogli, come
nome di istanza, mc. In un qualsiasi punto dello stage, trasciniamo un qualsiasi movieclip dalla libreria: lo
rimpiccioliamo, e lo
portiamo fuori dall'area visibile. A questo movieclip associamo:
onClipEvent (load) {
loadVariables ("finestre.txt", this);
_root.mc._visible = 0;
}
onClipEvent (data) {
num = _root.num = Number(num);
for (i = 1; i < num + 1; ++i) {
nuovo = "finestra"+i;
duplicateMovieClip ("_root.mc", nuovo, i);
with (_root[nuovo]) {
rettangolo.colore = new Color(rettangolo);
rettangolo.colore.setRGB(0x999999);
titolo = this["titolo"+i];
testo = this["testo"+i];
_x = _root.mc._x+(100*i);
_y = _root.mc._y+(20*i);
}
_root[nuovo].swapDepths(i);
}
_root["finestra"+num].rettangolo.colore.setRGB(0xFFCC33);
_root.alto = _root["finestra"+num]._name;
}
Questo codice, finalmente, è quello che carica il file di testo esterno e crea le finestre. Per posizionare le finestre duplicate, ci sono
mille modi: io ne ho scelto uno semplice per questioni di coerenza grafica, argomento che in altre situazioni può non essere il più
opportuno.
Il file di testo esterno che viene caricato, si chiama finestre.txt. Durante la costruzione del movieclip finestra, abbiamo visto come
al suo interno fossero presenti due campi di testo, titolo e testo. Queste saranno le variabili presenti, per ogni finestra. Il numero totale è scritto all'inizio.
num=3&titolo1=SIMBOLI GRAFICI&testo1=Usare i simboli grafici....bla.....&titolo2=PULSANTI&testo2=Usare i simboli di
pulsanti....bla..... &titolo3=CLIP FILMATO&testo3=Un clip filmato è un
....bla.....
Questo è il contenuto di finestre.txt: la prima variabile rappresenta il numero di duplicati ( e anche il massimo livello di impilamento
iniziale), le altre sono in sequenza i valori di titolo e testo per ogni movieclip.
// al caricamento del movieclip (una volta sola)
onClipEvent (load) {
// carica in questo movieclip il file di testo
// esterno finestre.txt
loadVariables ("finestre.txt", this);
// nascondi il movieclip "mc"
_root.mc._visible = 0;
}
// Quando i dati sono stati tutti caricati
onClipEvent (data) {
// setta il valore di num come il numero corrispondente
// alla stringa Num (le variabili dal testo esterno sono sempre stringhe)
num = _root.num = Number(num);
// per tutti i valori di i che vanno da 1 a num
for (i = 1; i < num + 1; ++i) {
// assegna alla variabile "nuovo", il valore di "finestra"+1
nuovo = "finestra"+i;
// duplica il movieclip mc sullo stage, dopo averlo reso invisibile
duplicateMovieClip ("_root.mc", nuovo, i);
// del movieclip duplicato, settiamo i colori;
// inseriamo nelle due caselle di testo il corrispondente per ogni
// movieclip; ne settiamo la posizione a scalare partendo da quella di mc
with (_root[nuovo]) {
rettangolo.colore = new Color(rettangolo);
rettangolo.colore.setRGB(0x999999);
titolo = this["titolo"+i];
testo = this["testo"+i];
_x = _root.mc._x+(100*i);
_y = _root.mc._y+(20*i);
}
// scambiamo ogni volta l'ordine di impilamento, in modo che
// l'ultimo duplicato sia in cima
_root[nuovo].swapDepths(i);
}
// l'ultima finestra duplicata sta in cima, e ha il colore giallo
// inoltre, il nome del primo movieclip, è anche quello
// che la funzione considera come l'ultimo chiamato, all'avvio.
_root["finestra"+num].rettangolo.colore.setRGB(0xFFCC33);
_root.alto = _root["finestra"+num]._name;
}
Brevemente:
viene caricato il file di testo e duplicate le finestre
ogni finestra viene riempita con i valori corrispondenti
l'ultima finestra è quella attiva