02.06.2013 Views

Comsigli per creare un intero sito in Flash - Ultimi Inserimenti

Comsigli per creare un intero sito in Flash - Ultimi Inserimenti

Comsigli per creare un intero sito in Flash - Ultimi Inserimenti

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Introduzione<br />

Prima di <strong>in</strong>iziare la costruzione di <strong>un</strong> <strong>sito</strong> web, è buona cosa stilare <strong>un</strong> progetto che ne comprenda gli scopi, il tipo di<br />

utilizzo, di aggiornamento, di utenti a cui farà riferimento.<br />

Tralasciando i particolari, trattati diffusamente nei corsi e nelle lezioni <strong>per</strong> webmaster di HTML.it, mi limiterò ad<br />

analizzare alc<strong>un</strong>i p<strong>un</strong>ti focali, e di immediata comprensione.<br />

Dimensioni e proporzioni<br />

Per motivi che mettiamo da parte (assolutamente <strong>in</strong>ventati), decidiamo che il <strong>sito</strong> debba avere delle proporzioni<br />

particolari: la larghezza del filmato deve essere i 7/3 dell'altezza. Vogliamo qu<strong>in</strong>di che il <strong>sito</strong> si espanda <strong>in</strong> orizzontale<br />

più che <strong>in</strong> verticale.<br />

Preciso che non esiste <strong>un</strong>a dimensione "giusta", anche se di solito i filmati <strong>in</strong> flash vengono <strong>in</strong>seriti <strong>in</strong> <strong>un</strong>a pag<strong>in</strong>a html<br />

<strong>in</strong> modo che non ci sia la necessità di usare le barre di scorrimento, <strong>per</strong> visualizzarli <strong>in</strong>teramente, a scelta del designer<br />

<strong>un</strong> filmato potrebbe essere anche 200x800. Le dimensioni e le proporzioni del progetto sono così discrezionali, che a<br />

volte possono essere dettate esclusivamente dal gusto.<br />

Inoltre, non vogliamo che il filmato venga visualizzato nella f<strong>in</strong>estra pr<strong>in</strong>cipale del browser, bensì <strong>in</strong> <strong>un</strong>a f<strong>in</strong>estra<br />

secondaria, a<strong>per</strong>ta come popup tramite javascript. Questo ci <strong>per</strong>metterà di aggi<strong>un</strong>gere alc<strong>un</strong>i attributi, come la costanza<br />

delle proporzioni e dimensioni <strong>in</strong> caso di ridimensionamento, e <strong>un</strong> certo controllo sulla posizione rispetto alle altre<br />

f<strong>in</strong>estre.<br />

Inf<strong>in</strong>e, dal momento che vogliamo che le dimensioni siano costanti (così da essere sicuri di cosa vedrà l'utente), <strong>per</strong> non<br />

affaticare gli occhi di chi usa <strong>un</strong>a risoluzione come 1600x1200, o "uscire dal monitor" di chi naviga a 640x480,<br />

ridimensioneremo automaticamente il filmato a seconda dei casi.<br />

Requisiti di sistema<br />

Plug<strong>in</strong><br />

È dato di fatto che i browser più recenti vengano rilasciati con il plug<strong>in</strong> <strong>per</strong> il <strong>Flash</strong>5 già <strong>in</strong>stallato: altrettanto certo <strong>per</strong>ò<br />

è che moltissime <strong>per</strong>sone, <strong>per</strong> le ragioni più disparate, utilizz<strong>in</strong>o ancora browser datati, con il plug<strong>in</strong> assente o capace di<br />

supportare solo versioni <strong>in</strong>feriori alla 5.<br />

Per questo motivo, bisogna prendere <strong>in</strong> considerazione la maggior parte, se non l'<strong>in</strong>terezza, dei casi possibili, ed<br />

eventualmente lasciare all'utente <strong>un</strong>a certa discrezionalità sulle scelte da fare.<br />

Offriremo qu<strong>in</strong>di all'utente, approdato alla pag<strong>in</strong>a <strong>in</strong>iziale del nostro <strong>sito</strong>, tre diverse opzioni:<br />

1. la possibilità di scaricare il plug<strong>in</strong> aggiornato (tramite <strong>un</strong> collegamento alla pag<strong>in</strong>a di download del <strong>sito</strong> della<br />

Macromedia);<br />

2. la possibilità di visualizzare il <strong>sito</strong> <strong>in</strong> versione html (qualora non potesse scaricare il plug<strong>in</strong>, come ad esempio<br />

nelle aule computer delle scuole o dei campus <strong>un</strong>iversitari);


3. la possibilità di visualizzare la versione <strong>in</strong> <strong>Flash</strong>.<br />

Qualora l'utente scelga di visualizzare la versione <strong>in</strong> flash, <strong>un</strong>a pag<strong>in</strong>a di controllo verificherà la presenza effettiva del<br />

plug<strong>in</strong>. In caso sia presente, aprirà la pag<strong>in</strong>a <strong>in</strong> flash, altrimenti offrirà nuovamente più scelte, compresa quella di<br />

procedere com<strong>un</strong>que (il controllo sul plug<strong>in</strong> non è sicuro al 100%).<br />

Processore<br />

Per questo <strong>sito</strong> prediligeremo <strong>un</strong> f<strong>un</strong>zionamento veloce e fluido alla presenza di grandi effetti grafici. Qu<strong>in</strong>di eviteremo<br />

il più possibile l'uso di gradienti, di animazioni frame a frame, di effetti alpha, di immag<strong>in</strong>i e suoni.<br />

Inoltre, <strong>per</strong> poter rendere i movimenti più scattanti, alzeremo il frame rate, dal valore di default di 12 frame al secondo,<br />

a quello di 24 frame al secondo: questo potrebbe rendere il filmato meno gestibile <strong>per</strong> le CPU più lente, ma mescolando<br />

con <strong>un</strong> po' di attenzione leggerezza e velocità, riusciremo ad ottenere <strong>un</strong> prodotto largamente compatibile.<br />

Banda<br />

Per quanto riguarda la velocità di scaricamento a disposizione dell'utente f<strong>in</strong>ale, ci sono tre metodi fondamentali volti a<br />

rendere le attese le più brevi possibile. L'uso di suoni <strong>in</strong> stream<strong>in</strong>g, l'uso delle librerie condivise, e l'ottimizzazione del<br />

filmato.<br />

In questo caso non utilizzeremo le prime due: il suono <strong>in</strong> stream<strong>in</strong>g non si presta ai loop (ogni ripetizione costa <strong>in</strong><br />

term<strong>in</strong>i di peso), e non ci consente di controllarne il volume, le librerie condivise <strong>in</strong>vece sono ben l<strong>un</strong>gi dall'essere<br />

efficaci, sopratutto <strong>per</strong>ché agli oggetti condivisi non possono essere applicati script, se non nella libreria stessa.<br />

Quello che faremo allora sarà ottimizzare il filmato, con tutti i metodi che abbiamo a disposizione. Il che significa:<br />

• riduzione dei gradienti a favore di colori solidi<br />

• riduzione o elim<strong>in</strong>azione delle animazioni frame a frame, a favore dell'uso di script<br />

• utilizzo diffuso di simboli presenti nella libreria del filmato, sotto forma di istanza<br />

• utilizzo di pochi suoni e di poche immag<strong>in</strong>i importate, e com<strong>un</strong>que di ridotta qualità<br />

• utilizzo di poche Font, e dei caratteri dispositivo<br />

• divisione del filmato <strong>in</strong> porzioni <strong>in</strong>dipendenti<br />

Per divisione del filmato, <strong>in</strong>tendo dire questo: avremo <strong>un</strong> filmato pr<strong>in</strong>cipale, contenente il menu di navigazione, e vari<br />

filmati esterni da caricare solo su richiesta dell'utente. In questo modo, l'attesa <strong>per</strong> vedere la schermata pr<strong>in</strong>cipale sarà<br />

ridotta all'osso, e l'utente deciderà quanto e cosa aspettare.<br />

Filmato <strong>in</strong>troduttivo<br />

Il nostro <strong>sito</strong> sarà sì dotato di <strong>un</strong> filmato <strong>in</strong>troduttivo, <strong>per</strong>ò da visualizzare solo alla prima visita. Le volte successive,<br />

l'<strong>in</strong>tro dovrà essere saltata a piè pari, <strong>per</strong> non annoiare <strong>in</strong>utilmente l'utente. Questo lo otterremo direttamente da <strong>Flash</strong>,<br />

senza l'utilizzo di metodi javascript o la scrittura di cookies.<br />

Inoltre, tutti i preloader presenti <strong>in</strong> tutti i filmati saranno fatti <strong>in</strong> modo da non essere visibili ai caricamenti successivi al<br />

primo.<br />

Sezioni <strong>in</strong>dipendenti


Come già accennato, il <strong>sito</strong> sarà diviso <strong>in</strong> sezioni <strong>in</strong>dipendenti, <strong>per</strong> ridurre i tempi d'attesa: <strong>in</strong> queste sezioni spiegherò<br />

diverse tecniche molto richieste. Naturalmente i metodi utilizzati non sono gli <strong>un</strong>ici possibili, e a seconda dei casi ce ne<br />

possono essere di migliori o più efficaci: l'importante è studiare il sistema che più si adatta alle nostre necessità.<br />

Spiegherò qu<strong>in</strong>di come <strong>creare</strong> diversi scroll<strong>in</strong>g di testo, di cui <strong>un</strong>o con <strong>un</strong>o scroller oltre ai pulsanti, la creazione di<br />

f<strong>in</strong>estre trasc<strong>in</strong>abili, due differenti slide di immag<strong>in</strong>i, l'<strong>in</strong>vio di messaggi tramite il client di posta (ness<strong>un</strong> l<strong>in</strong>guaggio<br />

esterno), l'<strong>in</strong>terazione con il browser, il controllo del suono.<br />

Accorgimenti vari<br />

Oltre alle cose già accennate, ce ne sono altre che cito qui senza ord<strong>in</strong>e di importanza.<br />

Una delle cose che vogliamo, è controllo del suono di sottofondo. Non ci limiteremo a <strong>creare</strong> <strong>un</strong> pulsante <strong>per</strong> fermare e<br />

<strong>un</strong>o <strong>per</strong> avviare il suono, ma anche <strong>un</strong> controllo <strong>per</strong> il volume, <strong>in</strong> due sistemi differenti.<br />

L'<strong>in</strong>terazione con il browser si basa fondamentalmente nel richiamo di f<strong>un</strong>zioni javascript, di solito <strong>in</strong>serite nella pag<strong>in</strong>a<br />

html che <strong>in</strong>corpora il filmato. In questo caso, <strong>in</strong>vece, richiameremo f<strong>un</strong>zioni raccolte <strong>in</strong> <strong>un</strong> file .js, <strong>in</strong> modo da<br />

mantenere il codice il più pulito possibile.<br />

Daremo all'utente la possibilità di decidere sull'utilizzo di <strong>un</strong> cursore <strong>per</strong>sonalizzato, e di <strong>un</strong> piccolo effetto grafico di<br />

contorno. Permetteremo <strong>in</strong>oltre la stampa <strong>in</strong> vettoriale di <strong>un</strong>a pag<strong>in</strong>a composta da scritte e immag<strong>in</strong>i, non visibile sullo<br />

stage.<br />

Altro piccolo accorgimento molto apprezzato, è quello di ridurre al m<strong>in</strong>imo l'utilizzo di pulsanti, sostituendoli con<br />

movieclip. Questo <strong>per</strong> elim<strong>in</strong>are la tanto sgradita man<strong>in</strong>a che si forma al passaggio su <strong>un</strong> pulsante: <strong>in</strong>fatti la<br />

comprensione della presenza di <strong>un</strong>'area cliccabile, può essere <strong>in</strong>dotta semplicemente tramite effetti def<strong>in</strong>ibili di<br />

"rollover". Naturalmente questo accorgimento diventa <strong>in</strong>utile nel caso dell'uso di p<strong>un</strong>tatori <strong>per</strong>sonalizzati.<br />

Disegno del filmato di base<br />

Rettangolo e cornice<br />

Prima di passare alla spiegazione della grafica di base, descriviamo la composizione di <strong>un</strong> oggetto che useremo più<br />

volte all'<strong>in</strong>terno dei nostri filmati: <strong>un</strong> semplice rettangolo con cornice.<br />

Il rettangolo sarà formato chiaramente da <strong>un</strong> riempimento solido di forma rettangolare, mentre la cornice sarà composta<br />

dal contorni del rettangolo stesso, con i lati di colore differente. Il disegno f<strong>in</strong>ale sarà questo:<br />

Come salta immediatamente all'occhio, questa figura dà <strong>un</strong> naturale senso di profondità: quello che sembra di guardare,<br />

è <strong>un</strong> piano con <strong>un</strong>'area leggermente depressa, illum<strong>in</strong>ato da s<strong>in</strong>istra <strong>in</strong> alto. Naturalmente, <strong>un</strong>iformando il colore della<br />

cornice, si può elim<strong>in</strong>are il senso di profondità, oppure, <strong>in</strong>vertendone i colori, <strong>creare</strong> <strong>un</strong> senso di rilievo.


Partendo da questa figura, e servendoci dell'Actionscript, o del pannello Effetti, possiamo modificarne a piacere<br />

posizione, dimensioni, colore, trasparenza, comportamento. Qu<strong>in</strong>di, nella sua <strong>in</strong>terezza, o nelle parti che la compongono,<br />

ci servirà a <strong>creare</strong> tutte le figure a quattro lati che dovremo usare.<br />

Costruzione<br />

Procediamo allora alla costruzione del filmato di base di e di questa figura. Apriamo il <strong>Flash</strong> con <strong>un</strong> nuovo documento,<br />

e andiamo al menu Modifica/Filmato (Modify/Movie):<br />

Nel pannello impostiamo quelle che saranno le dimensioni del filmato di base (e di tutti quelli esterni), cioè 700 pixel <strong>in</strong><br />

larghezza e 300 pixel <strong>in</strong> altezza. Il colore di fondo sarà il bianco, codice RGB #FFFFFF, e il Frame Rate 24 fps.<br />

Apro qui <strong>un</strong>a piccola parentesi: se il filmato pr<strong>in</strong>cipale ha <strong>un</strong> frame rate di 24 fps, i filmati esterni caricati sopra questo,<br />

sia con il loadMovie che con il loadMovieNum, prenderanno lo stesso frame rate, qual<strong>un</strong>que sia quello orig<strong>in</strong>ale, e<br />

verranno riprodotti a 24 fps. La cosa migliore da fare, allora, quando si hanno filmati con frame rate differente, è di<br />

affidare al pr<strong>in</strong>cipale quello più elevato, e di rallentare eventualmente le altre animazioni tramite Actionscript.<br />

Fatte queste considerazioni, sembrerebbe che, <strong>un</strong>a volta impostato il frame rate del filmato pr<strong>in</strong>cipale, non ci sia più la<br />

necessità di impostare quello degli altri filmati, poiché tutti assumono la stessa velocità, <strong>in</strong> riproduzione. D'altronde è<br />

preferibile impostare questo valore com<strong>un</strong>que, <strong>per</strong> poter, nella modalità Prova Filmato, vedere quello che sarà<br />

effettivamente l'andamento delle animazioni.<br />

Salviamo qu<strong>in</strong>di il filmato con il nome flash5.fla<br />

Apriamo nuovamente il filmato, e apriamo la libreria: premendo il pulsante + aggi<strong>un</strong>giamo <strong>un</strong> movieclip (clip filmato),<br />

e chiamiamolo base.<br />

Adesso disegniamo all'<strong>in</strong>terno di questo movieclip il rettangolo di base. Dal momento che <strong>un</strong>a l<strong>in</strong>ea <strong>in</strong>grandita può<br />

variare visibilmente come dimensioni, mentre, rimpicciolendola, non può diventare più sottile del tratto "hairl<strong>in</strong>e",<br />

questa sarà l'impostazione da dargli: allo stesso modo è preferibile che il rettangolo sia di dimensioni elevate, da<br />

rimpicciolire poi, e non il contrario.<br />

Selezioniamo lo strumento rettangolo, tracciamo <strong>un</strong>a figura delle stesse dimensioni del filmato pr<strong>in</strong>cipale (700x300)<br />

con contorno nero e riempimento grigio (#cccccc), e centriamola nel movieclip. Tagliamo il contorno e <strong>in</strong>colliamolo su


<strong>un</strong> nuovo livello, su<strong>per</strong>iore a quello del riempimento. Selezioniamo il lato <strong>in</strong>feriore e il lato destro, e coloriamoli di<br />

bianco, così da ottenere la figura d'<strong>in</strong>izio lezione.<br />

A questo p<strong>un</strong>to convertiamo la cornice <strong>in</strong> movieclip: chiameremo il movieclip cornice, e cornice sarà anche il nome di<br />

istanza.Selezioniamo la cornice, e apriamo il pannello Istanza (Istance Ctrl+I): nel campo Istance <strong>in</strong>seriamo il nome.<br />

Stessa identica procedura <strong>per</strong> il riempimento. Lo convertiamo, tramite il pulsante F8, <strong>in</strong> <strong>un</strong> movieclip che chiameremo<br />

rettangolo, e che avrà rettangolo come nome di istanza.<br />

A questo p<strong>un</strong>to abbiamo nella libreria il movieclip base: questo movieclip sarà composto da due livelli. In <strong>un</strong>o c'è la<br />

cornice, con nome di istanza cornice, e nell'altro c'è il rettangolo, nome di istanza rettangolo.<br />

Sullo stage<br />

Trasc<strong>in</strong>iamo dalla libreria <strong>un</strong>'istanza del movieclip "rettangolo" sull'area di lavoro, diamo come dimensioni 700x80,<br />

tramite il pannello Info, e posizionandola <strong>in</strong> alto al centro dello stage.<br />

Selezioniamo nuovamente lo strumento rettangolo, e disegniamo <strong>un</strong>a figura di dimensioni 700x150 sotto il primo<br />

rettangolo. Selezioniamo il pannello Fill, e cambiamo il riempimento dando <strong>un</strong> gradiente che va dal colore #333333 al<br />

colore #686868. Questo è quello che otteniamo.


L<strong>in</strong>ee<br />

Disegniamo <strong>in</strong> <strong>un</strong> nuovo livello <strong>un</strong>a l<strong>in</strong>ea di colore bianco, l<strong>un</strong>ga quanto lo stage: come stile scegliamo i p<strong>un</strong>t<strong>in</strong>i, e poi<br />

convertiamo <strong>in</strong> movieclip. Posizioniamo più istanze della l<strong>in</strong>ea a varie altezze, facendo attenzione a non esagerare, dal<br />

momento che le l<strong>in</strong>ee "dotted" pesano moltissimo e affaticano non poco la cpu. Trattandosi di movieclip, possiamo<br />

modificarne il colore tramite il pannello Effect, scegliendo T<strong>in</strong>ta dal menu a discesa.<br />

A questo p<strong>un</strong>to come elemento decorativo f<strong>in</strong>ale della base <strong>in</strong>seriamo il logo del <strong>Flash</strong>, di colore grigio, al centro dello<br />

stage, <strong>in</strong> modo che crei senza ulteriore aggi<strong>un</strong>te <strong>un</strong> gradevole effetto sfumato sul gradiente precedentemente <strong>in</strong>serito.<br />

Altri elementi grafici verranno <strong>in</strong>seriti più avanti, <strong>in</strong> <strong>un</strong> altro filmato. Quest'ultimo, che verrà caricato sopra tutti gli altri,<br />

con i propri oggetti creerà ombra e coprirà gli elementi degli altri livelli, dando <strong>un</strong> naturale effetto di profondità.<br />

Il menu pr<strong>in</strong>cipale<br />

Premessa<br />

Partiamo da <strong>un</strong> ass<strong>un</strong>to. Il <strong>sito</strong> sarà composto da vari filmati esterni, come già detto. Uno verrà caricato all'avvio sopra il<br />

pr<strong>in</strong>cipale, e altri c<strong>in</strong>que formeranno le varie sezioni, oltre a quella che si presenta all'utente quando accede al <strong>sito</strong>. Il<br />

menu sarà qu<strong>in</strong>di composto da 6 pulsanti, c<strong>in</strong>que <strong>per</strong> i filmati esterni, e <strong>un</strong>o <strong>per</strong> l'homepage.<br />

Il pulsante<br />

Costruiamo il menu partendo dal s<strong>in</strong>golo pulsante. I colori attorno ai quali abbiamo deciso di im<strong>per</strong>niare la grafica del<br />

<strong>sito</strong>, sono il giallo, il bianco, e varie sfumature di grigio. Abbiamo deciso di posizionare il menu nella parte bassa del<br />

filmato, cioè sulla banda bianca sotto il gradiente centrale. E i nostri pulsanti saranno gialli.<br />

Premendo il segno + <strong>in</strong> basso a s<strong>in</strong>istra della libreria, aggi<strong>un</strong>giamo <strong>un</strong> movieclip, che chiameremo pulsanteDentro.<br />

Editiamo questo movieclip: nel livello più <strong>in</strong> basso posizioneremo, trasc<strong>in</strong>andola dalla libreria, <strong>un</strong>'istanza del movieclip<br />

rettangolo, quello che avevamo costruito <strong>per</strong> <strong>creare</strong> la figura di base. Riduciamo le dimensioni a <strong>un</strong> rettangolo di 65x10<br />

di lato. Posizioniamo il rettangolo al centro del movieclip, apriamo il pannello Effetti, scegliamo T<strong>in</strong>ta dal menu, e a<br />

destra <strong>in</strong>seriamo i valori del giallo (#FFCC33 oppure 255 204 51).


Aggi<strong>un</strong>giamo, con F6, <strong>un</strong> keyframe (fotogramma chiave) al frame numero 11, e <strong>un</strong> altro al numero 22. Selezioniamo il<br />

rettangolo del frame 11, e tramite il pannello Effetti, t<strong>in</strong>giamo l'oggetto di bianco: qu<strong>in</strong>di creiamo <strong>un</strong> motion tween<br />

(<strong>in</strong>terpolazione di movimento) dal frame 1 al frame 11, e dal 12 al 22.<br />

Aggi<strong>un</strong>giamo ora <strong>un</strong>'altro layer, nel cui primo frame <strong>in</strong>seriamo <strong>un</strong>'istanza del movieclip cornice. Dal pannello Effetti<br />

t<strong>in</strong>giamo la cornice di nero, <strong>in</strong> modo da elim<strong>in</strong>are i due lati bianchi, ed all<strong>un</strong>ghiamo il layer, tramite F5, f<strong>in</strong>o alla f<strong>in</strong>e<br />

del movieclip (frame 22). Inf<strong>in</strong>e, <strong>in</strong> <strong>un</strong> altro layer, <strong>in</strong>seriamo al frame 1 e al frame 11, due stop();<br />

Il risultato f<strong>in</strong>ale è il movieclip pulsanteDentro, contenente tre livelli. Nel primo dal basso, il rettangolo, con il motion<br />

tween, nel secondo la cornice, nel terzo le azioni.<br />

Prima di vedere il codice da associare al movieclip, vediamo <strong>un</strong>a parte che utilizzeremo molte volte, e che ci <strong>per</strong>mette<br />

di capire se siamo o no sul movieclip (e qu<strong>in</strong>di di renderlo assimilabile ad <strong>un</strong> pulsante).<br />

Se associamo ad <strong>un</strong> movieclip:<br />

if(this.hitTest(_root._xmouse,_root._ymouse,false))<br />

diciamo: se questo movieclip (this) entra <strong>in</strong> collisione con le coord<strong>in</strong>ate del p<strong>un</strong>tatore del mouse rispetto al<br />

sistema di riferimento della timel<strong>in</strong>e pr<strong>in</strong>cipale, allora.....<br />

Supponendo che il movieclip stia fermo, e che sia il mouse a muoversi, stiamo dicendo: se il mouse tocca il movieclip,<br />

allora...<br />

Partendo da questo codice possiamo emulare su <strong>un</strong> movieclip tutti gli eventi dei pulsanti: con il vantaggio di non avere<br />

la man<strong>in</strong>a. Ultima considerazione: scrivere true o false alla f<strong>in</strong>e di quel codice, rende le due cose molto differenti.<br />

Citando dal manuale, "..specifica se valutare <strong>per</strong> l'<strong>in</strong>tera forma dell'istanza specificata (true) oppure solo il riquadro di<br />

limitazione (false). Se la figura è <strong>un</strong> quadrato, la cosa non fa differenza, dal momento che la forma e il riquadro di<br />

limitazione co<strong>in</strong>cidono, ma se la figura ad esempio è <strong>un</strong> cerchio, le cose cambiano...


Torniamo a pulsanteDentro. Trasc<strong>in</strong>iamo <strong>un</strong>'istanza di questo movieclip sullo stage: gli associamo il seguente script:<br />

onClipEvent (mouseMove) {<br />

if (this.hitTest(_root._xmouse, _root._ymouse, false) && !a<strong>per</strong>to) {<br />

if (_currentframe>(_totalframes/2)) {<br />

gotoAndPlay (_totalframes-_currentframe);<br />

} else {<br />

play ();<br />

}<br />

a<strong>per</strong>to = true;<br />

} else if (!this.hitTest(_root._xmouse, _root._ymouse, false) && a<strong>per</strong>to) {<br />

if (_currentFrame(_totalframes/2)) {<br />

// riproduci il movieclip a partire dal frame corrispondente al<br />

// numero dei frame totali meno il frame attuale<br />

gotoAndPlay (_totalframes-_currentframe);<br />

// altrimenti (e qu<strong>in</strong>di il frame corrente è m<strong>in</strong>ore della metà)<br />

} else {<br />

// riproduci dal frame corrente<br />

play ();


}<br />

// setta la variabile "a<strong>per</strong>to" come vera<br />

a<strong>per</strong>to = true;<br />

// altrimenti, se il movieclip non tocca il mouse e "a<strong>per</strong>to" è vera<br />

// (e qu<strong>in</strong>di con il mouse sto "uscendo" dal movieclip)<br />

} else if (!this.hitTest(_root._xmouse, _root._ymouse, false) && a<strong>per</strong>to) {<br />

// se il frame attuale è m<strong>in</strong>ore della metà dei totali<br />

if (_currentFrame


onClipEvent (mouseMove) {<br />

if (!premuto) {<br />

if (this.hitTest(_root._xmouse, _root._ymouse, false) && !a<strong>per</strong>to) {<br />

if (_currentframe>(_totalframes/2)) {<br />

gotoAndPlay(_totalframes-_currentframe);<br />

} else {<br />

play ();<br />

}<br />

a<strong>per</strong>to = true;<br />

} else if (!this.hitTest(_root._xmouse, _root._ymouse, false) && a<strong>per</strong>to) {<br />

if (_currentFrame


Adesso abbiamo sullo stage 6 istanze del movieclip pulsanteFuori, con 6 diversi nomi di istanza. Ricordiamo che le sei<br />

istanza contengono il movieclip pulsanteDentro, nome di istanza <strong>in</strong>terno, a cui è associato lo script: questo è possibile<br />

<strong>per</strong>ché lo script è <strong>un</strong>iversale, e <strong>per</strong> diventare relativo ad azioni differenti, fa riferimento al nome di istanza del movieclip<br />

che lo contiene. E questa è l'<strong>un</strong>ica cosa che cambia da <strong>un</strong> movieclip all'altro.<br />

Selezioniamo ora tutti e sei i movieclip, e convertiamoli ancora <strong>in</strong> <strong>un</strong> movieclip, che chiameremo menu, e che avrà<br />

menu come nome di istanza. Editiamo il movieclip menu: <strong>in</strong> <strong>un</strong> layer ci sono i 6 movieclip pulsanteFuori.<br />

Aggi<strong>un</strong>giamo <strong>un</strong> layer, e scriviamoci, corrispondendo ai vari pulsanti, i nomi delle 6 differenti sezioni. Quello che<br />

otteniamo è questo:<br />

La f<strong>un</strong>zione<br />

Adesso non rimane che def<strong>in</strong>ire la f<strong>un</strong>zione che <strong>per</strong>metterà al menu di fare qualcosa. Come abbiamo già detto, la<br />

pressione di <strong>un</strong>o dei pulsanti, richiamerà <strong>un</strong>a f<strong>un</strong>zione che si chiama comandi, alla quale come variabile viene <strong>in</strong>viato il<br />

nome di istanza del movieclip PulsanteFuori che contiene il pulsante. In pratica, se premo sul movieclip "homepage",<br />

alla root arriverà il comando:<br />

comandi("home");<br />

L'aver usato <strong>un</strong>a f<strong>un</strong>zione, ci <strong>per</strong>mette di non dover più toccare i pulsanti, <strong>per</strong> cambiare le azioni corrispondenti: basterà<br />

modificare la f<strong>un</strong>zione <strong>per</strong> rispondere alle nostre esigenze.<br />

Selezioniamo il primo frame del filmato sulla timel<strong>in</strong>e pr<strong>in</strong>cipale, e apriamo il pannello Azioni: scriviamo il seguente<br />

codice<br />

f<strong>un</strong>ction comandi (nome) {<br />

loadMovieNum (nome + ".swf", 1);<br />

}<br />

Molto semplicemente la f<strong>un</strong>zione riceve come parametro il nome di istanza del movieclip che contiene il pulsante, e<br />

assegna questo parametro alla variabile nome. Qu<strong>in</strong>di carica <strong>un</strong> filmato esterno, sul livello 1, che si chiama come la<br />

variabile più la str<strong>in</strong>ga ".swf": <strong>in</strong> parole povere, se clicco il pulsante dentro il movieclip slide, la f<strong>un</strong>zione carica sul<br />

livello 1 il filmato slide.swf.<br />

D'altronde, premendo più volte lo stesso pulsante, caricheremmo altrettante volte lo stesso filmato: effetto decisamente<br />

sgradevole, e oltretutto non <strong>in</strong>nocuo. Se <strong>in</strong>fatti stiamo utilizzando il filmato esterno, e lo carichiamo di nuovo, <strong>per</strong>diamo<br />

tutte le variabili e le impostazioni raggi<strong>un</strong>te a quel momento.<br />

Inseriamo qu<strong>in</strong>di <strong>un</strong> semplice controllo sul nome della variabile. Se è la stessa, allora non caricare di nuovo: o meglio,<br />

carica solo se è diversa dall'ultima impostata. Inoltre, dobbiamo <strong>in</strong>serire <strong>un</strong> nome di partenza: quello della homepage, <strong>in</strong><br />

modo che all'avvio del filmato, sia come se avessimo premuto il pulsante "homepage".<br />

ultimo = "home";<br />

f<strong>un</strong>ction comandi (nome) {<br />

if (nome != ultimo) {<br />

loadMovieNum (nome + ".swf", 1);<br />

}<br />

ultimo = nome;<br />

}


In questo modo con la prima riga abbiamo impostato il valore della variabile ultimo, che conterrà il nome dell'ultimo<br />

pulsante premuto. Al richiamo della variabile, avviene <strong>un</strong> confronto tra ultimo e nome: se sono diversi, viene caricato il<br />

filmato esterno corrispondente, e il valore di ultimo diventa quello di nome.<br />

Adesso <strong>per</strong>ò abbiamo <strong>un</strong> problema: premendo home, non abbiamo alc<strong>un</strong> filmato da caricare, dal momento che home<br />

corrisponde al filmato pr<strong>in</strong>cipale. Allora, <strong>un</strong>a volta verificato che ultimo sia diverso da nome, se il pulsante premuto è<br />

home, allora scarichiamo il livello 1, altrimenti carichiamo il filmato esterno corrispondente.<br />

ultimo = "home";<br />

f<strong>un</strong>ction comandi (nome) {<br />

if (nome != ultimo) {<br />

if (nome == "home") {<br />

<strong>un</strong>loadMovieNum (1);<br />

} else {<br />

loadMovieNum (nome+".swf", 1);<br />

}<br />

ultimo = nome;<br />

}<br />

}<br />

F<strong>in</strong> qui ci siamo. Ora dobbiamo tornare al fatto che, <strong>un</strong>a volta premuto <strong>un</strong> pulsante, questo si ferma al frame 11, <strong>in</strong><br />

modo che sia completamente bianco, ed escludendo le animazioni di rollover e rollout. Qu<strong>in</strong>di, quando premiamo <strong>un</strong><br />

pulsante, quello premuto precedentemente, fisso sul bianco, deve tornare gradualmente al giallo. Inoltre, come <strong>per</strong> la<br />

variabile ultimo, già impostata all'avvio del filmato, dobbiamo impostare il pulsante homepage come se fosse già stato<br />

premuto.<br />

Per questo motivo, ricapitolo come raggi<strong>un</strong>gere i pulsanti contenuti nel movieclip menu. Sullo stage abbiamo il<br />

movieclip menu con nome di istanza menu: questo contiene i sei movieclip pulsanteFuori, con i nomi di istanza riferiti<br />

alle sezioni. Dentro ogn<strong>un</strong>o di questo movieclip, c'è il movieclip pulsanteDentro, nome di istanza <strong>in</strong>terno, all'<strong>in</strong>terno<br />

del quale si svolge l'animazione di rollover. Ad ogn<strong>un</strong>o dei movieclip pulsanteDentro, è associato lo script <strong>per</strong><br />

l'animazione, e anche il controllo sulla pressione del movieclip stesso.<br />

Come abbiamo già visto, il movieclip è fermo al frame 11, e bloccato dalla variabile premuto, che è vera. Dobbiamo<br />

qu<strong>in</strong>di, alla pressione di <strong>un</strong> nuovo pulsante, riprendere la riproduzione dell'animazione del pulsante premuto<br />

precedentemente, e far tornare falsa la variabile premuto.<br />

Se ad esempio l'ultimo pulsante premuto era home, e vogliamo riprist<strong>in</strong>arlo, il <strong>per</strong>corso che ci <strong>in</strong>teressa sarà:<br />

menu.home.<strong>in</strong>terno<br />

<strong>per</strong> avviare la riproduzione useremo:<br />

menu.home.<strong>in</strong>terno.play();<br />

<strong>per</strong> resettare la variabile:<br />

menu.home.<strong>in</strong>terno.premuto = false;


Inoltre useremo <strong>un</strong>a particolare notazione: movieclip[variabile].comando<br />

Questo significa che, avendo <strong>un</strong>a variabile che contiene il nome di <strong>un</strong> movieclip, possiamo utilizzarla <strong>per</strong> completare il<br />

<strong>per</strong>corso. Se il valore di ultimo è "home", la scrittura<br />

menu[ultimo].<strong>in</strong>terno.premuto = false;<br />

corrisponderà a:<br />

menu.home.<strong>in</strong>terno.premuto = false;<br />

ultimo = "home";<br />

menu[ultimo].<strong>in</strong>terno.premuto = true;<br />

menu[ultimo].<strong>in</strong>terno.gotoAndStop(11);<br />

f<strong>un</strong>ction comandi (nome) {<br />

if (nome != ultimo) {<br />

if (nome == "home") {<br />

<strong>un</strong>loadMovieNum (1);<br />

} else {<br />

loadMovieNum (nome + ".swf", 1);<br />

}<br />

menu[ultimo].<strong>in</strong>terno.premuto = false;<br />

menu[ultimo].<strong>in</strong>terno.play();<br />

ultimo = nome;<br />

}<br />

}<br />

Nel dettaglio:<br />

// settiamo come ultimo "home" (è come se avessimo<br />

// premuto "home" all'avvio)<br />

ultimo = "home";<br />

// blocchiamo il rollover del pulsante "home"<br />

menu[ultimo].<strong>in</strong>terno.premuto = true;<br />

// mandiamo il movieclip "home" al frame 11<br />

menu[ultimo].<strong>in</strong>terno.gotoAndStop(11);<br />

f<strong>un</strong>ction comandi (nome) {<br />

if (nome != ultimo) {<br />

if (nome == "home") {<br />

<strong>un</strong>loadMovieNum (1);<br />

} else {<br />

loadMovieNum (nome + ".swf", 1);<br />

}<br />

// resettiamo la variabile "premuto" del pulsante<br />

// attivato precedentemente<br />

menu[ultimo].<strong>in</strong>terno.premuto = false;<br />

// riavviamone la riproduzione


menu[ultimo].<strong>in</strong>terno.play();<br />

ultimo = nome;<br />

}<br />

}<br />

Lo scroll<strong>in</strong>g<br />

Introduzione<br />

Siamo ancora all'<strong>in</strong>terno del primo filmato, e quello che stiamo <strong>per</strong> <strong>creare</strong> è <strong>un</strong> primo metodo <strong>per</strong> lo scorrimento del<br />

testo. Il nostro scopo di poter visualizzare, all'a<strong>per</strong>tura del <strong>sito</strong>, <strong>un</strong> testo che rappresenti le novità e gli aggiornamenti <strong>in</strong><br />

relazione alle attività svolte, e la possibilità di scorrerlo tramite pulsanti.<br />

Perché questo progetto sia efficace, vogliamo anche che sia facilmente aggiornabile: il che significa che quando avremo<br />

la necessità di modificare il testo, non dovremo più toccare il filmato, ma limitarci a rendere disponibile <strong>un</strong> file da cui<br />

prendere il testo aggiornato.<br />

Il loadVariables<br />

Le variabili<br />

Innanzitutto, spieghiamo come f<strong>un</strong>ziona il sistema del caricamento del testo. Il <strong>Flash</strong>5, tramite il comando<br />

loadVariables, ci <strong>per</strong>mette di caricare, all'<strong>in</strong>terno del filmato, le variabili contenute nel file oggetto dell'azione. Questo<br />

file può essere di vario tipo, <strong>un</strong> .php, .asp, <strong>un</strong> .pl: nel nostro caso sarà <strong>un</strong> com<strong>un</strong>issimo file di testo con estensione .txt.<br />

La cosa che com<strong>un</strong>que rimane <strong>in</strong>variata, nell'utilizzo di questi diversi file, il modo <strong>in</strong> cui devono essere presentate le<br />

variabili:<br />

&variabile1=valore1&variabile2=valore2&variabile3=valore3 &...<br />

Come è evidente, le variabili vengono scritte <strong>un</strong>a dopo l'altra secondo <strong>un</strong>o schema fisso. La "e" commerciale, il nome<br />

della prima variabile, il segno uguale e il suo valore: e qui f<strong>in</strong>isce la dichiarazione della prima variabile. Le altre<br />

variabili vengono dopo secondo lo stesso schema: variabili divise dalla "&", e nomi e valori <strong>un</strong>iti dal "=".<br />

Se vogliamo qu<strong>in</strong>di che nel nostro filmato, <strong>un</strong>a volta effettuato il caricamento, sia presente la variabile pippo il cui<br />

contenuto è la str<strong>in</strong>ga "flasher <strong>in</strong>callito", nel nostro file di testo scriveremo semplicemente:<br />

&pippo=flasher <strong>in</strong>callito<br />

Due app<strong>un</strong>ti fondamentali. Le str<strong>in</strong>ghe che rappresentano il contenuto delle variabili, possono, naturalmente, contenere<br />

degli spazi, ma tra il nome della variabile, il segno "=" e il primo carattere della str<strong>in</strong>ga, di spazi non ce ne devono<br />

essere.<br />

Secondo app<strong>un</strong>to, tutte le variabili caricate <strong>in</strong> questo modo, <strong>per</strong> il plug<strong>in</strong> del <strong>Flash</strong>, sono str<strong>in</strong>ghe, anche se contengono<br />

esclusivamente numeri. Qu<strong>in</strong>di, se nel file di testo scriviamo:<br />

&pippo=123456<br />

<strong>in</strong> <strong>Flash</strong> otteremo il corrispondente di <strong>un</strong>:<br />

pippo = "123456";


e non di <strong>un</strong><br />

pippo = 123456;<br />

Se allora volessimo caricare <strong>in</strong> <strong>Flash</strong> la variabile numerica pippo, <strong>per</strong> poterla trattare, nell'ambiente di lavoro<br />

scriveremmo:<br />

pippo = Number(pippo);<br />

Nel nostro caso, visto che non abbiamo bisogno di valutare variabili numeriche, il file di testo, che si chiamerà news.txt,<br />

sarà scritto così:<br />

&news=bla bla bla contenuto degli aggiornamenti bla bla bla....<br />

La s<strong>in</strong>tassi<br />

Vediamo quali s<strong>in</strong>tassi usare, e dist<strong>in</strong>guiamo due comandi a seconda del target del caricamento.Se ad esempio vogliamo<br />

che la nostra variabile testo abbia valore a livello della _root, la s<strong>in</strong>tassi sarà:<br />

loadVariablesNum("news.txt", 0);<br />

In questo modo, è come se avessimo scritto:<br />

_root.news = "bla bla bla contenuto degli aggiornamenti bla bla bla....";<br />

Invece, se vogliamo che la variabile venga caricata all'<strong>in</strong>terno di <strong>un</strong> movieclip, potremo associare al movieclip stesso :<br />

loadVariables("news.txt", this);<br />

dove this <strong>in</strong>dica al player che il file di testo deve essere caricato nel movieclip che chiama il loadVariables. Se il<br />

movieclip <strong>in</strong> questione ha come nome di istanza scorrimento, è come se avessimo scritto:<br />

_root.scorrimento.news = "bla bla bla contenuto degli aggiornamenti bla bla bla....";<br />

Questo è esattamente quello che faremo: caricheremo il file di testo e le variabili <strong>in</strong> esso contenute, all'<strong>in</strong>terno di <strong>un</strong><br />

movieclip. Questo ci serve <strong>per</strong> poter effettuare <strong>un</strong> controllo molto particolare: quello dell'avvenuto caricamento delle<br />

variabili.<br />

Uno degli eventi propri dei movieclip, <strong>in</strong> <strong>Flash</strong> 5, è il data. Sottoponendo <strong>un</strong> comando a questo evento, verrà eseguito<br />

solo quando le variabili saranno state caricate. Qu<strong>in</strong>di al nostro movieclip assoceremo:<br />

onClipEvent(load) {<br />

loadVariables ("news.txt", this);<br />

}<br />

onClipEvent (data) {<br />

...comando...<br />

}<br />

Il nostro scopo è, all'a<strong>per</strong>tura del <strong>sito</strong>, di chiamare il caricamento delle variabili. Quando, e solo quando le variabili<br />

saranno state caricate, visualizzeremo gli strumenti <strong>per</strong> lo scorrimento, testo e pulsanti.


Il movieclip<br />

Il campo di testo<br />

Apriamo il file flash5.fla, e visualizziamo la libreria.<br />

Premiamo il pulsante con il simbolo + <strong>in</strong> basso a s<strong>in</strong>istra, e aggi<strong>un</strong>giamo <strong>un</strong> movieclip che chiameremo news.<br />

Dentro questo movieclip creiamo tre layer di due frame ciasc<strong>un</strong>o, dal basso verso l'alto con i nomi testo, titolo e<br />

pulsanti<br />

Nel layer "titolo", mettiamo <strong>in</strong> entrambi i frame (basta nel primo, e poi <strong>creare</strong> il secondo con F5), <strong>un</strong> campo di testo con<br />

la scritta "ultime novità": poi, tramite il pannello Align, posizioniamo il campo di testo con il vertice su<strong>per</strong>iore s<strong>in</strong>istro<br />

al centro del movieclip.<br />

Nel layer "testo", <strong>in</strong>vece posizioniamo <strong>un</strong> movieclip composto da due frame: nel primo ci sarà la scritta "caricamento <strong>in</strong><br />

corso...", il secondo sarà vuoto. Questo ci darà <strong>un</strong>a scritta lampeggiante nell'attesa del caricamento.<br />

Passiamo al secondo frame del layer testo: selezioniamo lo strumento Text, dal pannello Text Options lo settiamo come


d<strong>in</strong>amico e multil<strong>in</strong>ea, e disegniamo il campo di testo <strong>in</strong> cui visualizzeremo il contenuto del file esterno. Selezioniamo il<br />

campo di testo, e ancora nel pannello Options ne settiamo tutte le proprietà:<br />

Il Font usato sarà il _sans. In questo modo non avremo bisogno di <strong>in</strong>corporare alc<strong>un</strong> carattere, dal momento che il<br />

player ne conserva già le <strong>in</strong>formazioni. Le dimensioni saranno 10pt, e il colore bianco (<strong>per</strong> contrastare la banda di<br />

colore scuro al centro del filmato). Come abbiamo già detto, il testo sarà d<strong>in</strong>amico e multil<strong>in</strong>ea: ticchiamo anche la<br />

casella HTML (ci <strong>per</strong>metterà di usare alc<strong>un</strong>i tag html nel testo) e Word Wrap (manderà automaticamente a capo il<br />

testo alla f<strong>in</strong>e della casella). Inf<strong>in</strong>e, come variabile associamo news: <strong>in</strong>fatti questa è la variabile che abbiamo def<strong>in</strong>ito<br />

nel file di testo.<br />

Torniamo alla timel<strong>in</strong>e pr<strong>in</strong>cipale, e dalla libreria trasc<strong>in</strong>iamo <strong>un</strong>'istanza del movieclip news sullo stage. La<br />

posizioniamo al centro verso destra, e gli associamo:<br />

onClipEvent (load) {<br />

stop ();<br />

loadVariables ("news.txt", this);<br />

}<br />

onClipEvent (data) {<br />

nextFrame ();<br />

}<br />

Il f<strong>un</strong>zionamento è già molto chiaro: all'avvio del filmato, il movieclip news si fermerà al primo frame (caricamento) e<br />

caricherà il file news.txt. Quando il file sarà stato caricato e le variabili saranno def<strong>in</strong>ite, il movieclip si sposterà al<br />

secondo frame, dove è presente la casella di testo che conterrà gli aggiornamenti.<br />

Ora andiamo al secondo frame del layer "pulsanti" (il primo resterà vuoto), e disegniamo <strong>in</strong> alto a destra i pulsanti <strong>per</strong><br />

lo scorrimento.<br />

I pulsanti<br />

Come previsto nel nostro progetto, vogliamo evitare il più possibile l'utilizzo di pulsanti veri e propri, sostituendoli con<br />

movieclip: questo passaggio ci è utile anche <strong>per</strong> <strong>un</strong> altro motivo, evitare l'uso di <strong>un</strong> ulteriore movieclip <strong>per</strong> rendere lo<br />

scorrimento cont<strong>in</strong>uo.


(Parto dal presupposto che chi legge conosca già le basi dello scroll<strong>in</strong>g di testo <strong>in</strong> <strong>Flash</strong>5, e il significato delle proprietà<br />

scroll e maxscroll.<br />

Abbiamo <strong>un</strong> campo di testo d<strong>in</strong>amico che contiene <strong>un</strong> testo più l<strong>un</strong>go di quanto possa visualizzare. Per questo motivo<br />

dobbiamo essere <strong>in</strong> grado di variare la proprietà scroll del campo di testo, che ci <strong>in</strong>dica il numero della riga visualizzata<br />

<strong>in</strong> alto. In questo caso la proprietà maxscroll non ci serve, <strong>per</strong>ché lo scorrimento si ferma automaticamente all'<strong>in</strong>izio e<br />

alla f<strong>in</strong>e del testo.<br />

Il comando <strong>per</strong> scorrere verso l'alto, se dato al livello della timel<strong>in</strong>e pr<strong>in</strong>cipale del movieclip news, sarà:<br />

news.scroll = news.scroll - 1; oppure, <strong>in</strong> forma abbreviata: news.scroll


secondo quanto sono i frame al secondo del frame rate.<br />

Lo script del movieclip <strong>per</strong> scorrere verso il basso è <strong>per</strong>fettamente identico, tranne che <strong>per</strong> <strong>un</strong>a riga: dove <strong>in</strong> <strong>un</strong>o c'è<br />

_parent.news.scroll-- metteremo_parent.news.scroll++<br />

Ultimo accorgimento, metteremo <strong>un</strong> cambio di colore del movieclip alla pressione sulla freccia.<br />

onClipEvent (load) {<br />

colore = new Color(this);<br />

}<br />

onClipEvent (mouseDown) {<br />

if (this.hitTest(_root._xmouse,_root._ymouse,false)) {<br />

colore.setRGB( 0xFFFFFF );<br />

premuto = true;<br />

}<br />

}<br />

onClipEvent (mouseUp) {<br />

colore.setRGB( 0xFFCC33 );<br />

premuto = false;<br />

}<br />

onClipEvent (enterFrame) {<br />

if (premuto) {<br />

_parent.news.scroll--;<br />

}<br />

}<br />

Al caricamento del movieclip creiamo <strong>un</strong>a istanza dell'oggetto color legata al movieclip stesso. Quando clicchiamo sul<br />

movieclip, il colore diventerà bianco, quando (ne settiamo il valore RGB su FFFFFF), e quando rilasciamo il tasto, il<br />

colore diventerà il giallo precedentemente impostato. Lo stesso vale <strong>per</strong> entrambe le frecce.<br />

Se adesso lanciamo il nostro filmato, questo è quello che possiamo vedere.<br />

F<strong>un</strong>zione del menu<br />

Prima di concludere, dobbiamo riprendere <strong>in</strong> mano la f<strong>un</strong>zione del menu. Infatti, quando caricheremo i filmati esterni,<br />

dovremo rendere <strong>in</strong>visibile lo scroll<strong>in</strong>g, <strong>per</strong> farlo riapparire quando clicchiamo sul tasto "homepage". I cambiamenti da<br />

fare sono m<strong>in</strong>imi:<br />

f<strong>un</strong>ction comandi (nome) {<br />

if (nome != ultimo) {<br />

if (nome == "home") {<br />

news._visible = 1;<br />

<strong>un</strong>loadMovieNum (1);<br />

} else {<br />

loadMovieNum ("filmati/" + nome + ".swf", 1);<br />

news._visible = 0;<br />

}


menu[ultimo].<strong>in</strong>terno.premuto = false;<br />

menu[ultimo].<strong>in</strong>terno.play();<br />

clip._x = -50;<br />

clip._alpha = 30;<br />

clip.tempo = getTimer();<br />

ultimo = nome;<br />

}<br />

}<br />

Come impostare i tag<br />

In <strong>Flash</strong>, è possibile utilizzare alc<strong>un</strong>i dei tag html all'<strong>in</strong>terno di campi di testo d<strong>in</strong>amici opport<strong>un</strong>amente impostati.<br />

Come abbiamo già visto, il campo di testo <strong>in</strong> cui visualizzare gli aggiornamenti del nostro <strong>sito</strong>, era così settato:<br />

Nella figura di destra, è ticcata la casella HTML: ed è tutto ciò che ci serve.<br />

I tag HTML<br />

I tag che si possono utilizzare non sono tantissimi, ma bastano e avanzano <strong>per</strong> i nostri scopi. A parte i tag e <br />

(che f<strong>un</strong>zionano anche <strong>in</strong> relazione alle dimensioni dei caratteri usati), possiamo usare il <strong>per</strong> mandare a capo, il<br />

<strong>per</strong> i colori, le dimensioni, e le Font vere e proprie, l' <strong>per</strong> i collegamenti cliccabili.<br />

Considerato che il nostro file di testo ha questo formato:<br />

news=...................................<br />

vediamo cosa possiamo scrivere al posto dei p<strong>un</strong>t<strong>in</strong>i.<br />

Se il nostro testo recita così:<br />

"Il capitolo 7 di questo manuale, "Dizionario di ActionScript", contiene <strong>un</strong>a descrizione dettagliata <strong>per</strong> ogni elemento di<br />

ActionScript."<br />

e al posto dei p<strong>un</strong>t<strong>in</strong>i mettiamo:


Il capitolo 7 di questo manuale, "Dizionario di ActionScript", contiene <strong>un</strong>a descrizione<br />

dettagliata <strong>per</strong> ogni elemento di ActionScript.<br />

come output otteniamo nel campo di testo:<br />

Il capitolo 7 di questo manuale, "Dizionario di ActionScript", contiene <strong>un</strong>a descrizione dettagliata <strong>per</strong> ogni elemento di<br />

ActionScript.<br />

Se aggi<strong>un</strong>giamo anche <strong>un</strong> , da:<br />

Il capitolo 7 di questo manuale, "Dizionario di ActionScript",contiene <strong>un</strong>a descrizione<br />

dettagliata <strong>per</strong> ogni elemento di ActionScript.<br />

otteniamo:<br />

Il capitolo 7 di questo manuale, "Dizionario di ActionScript",<br />

contiene <strong>un</strong>a descrizione dettagliata <strong>per</strong> ogni elemento di ActionScript.<br />

Con il tag impostiamo le caratteristiche dei caratteri, con le dimensioni <strong>in</strong> p<strong>un</strong>ti. Le parole "Dizionario di<br />

Actionscript", con le opport<strong>un</strong>e modifiche, da:<br />

Dizionario di Actionscript<br />

nel file di testo, <strong>in</strong> output diventano:<br />

Dizionario di Actionscript<br />

Con <strong>in</strong>vece colleghiamo le parole ad <strong>un</strong> l<strong>in</strong>k da aprire <strong>in</strong> <strong>un</strong>a pag<strong>in</strong>a esterna:<br />

<strong>Flash</strong>-MX.it - Risorse italiane su <strong>Flash</strong><br />

diventa<br />

<strong>Flash</strong>-MX.it - risorse italiane su flash<br />

Accorgimenti particolari<br />

• Mandando a capo con Invio, <strong>in</strong> <strong>un</strong> file di testo, nell'output otteniamo l'equivalente di <strong>un</strong> doppio , cioè a capo con<br />

riga vuota <strong>in</strong> mezzo. Questo <strong>per</strong>ò vale solo <strong>per</strong> alc<strong>un</strong>i browser, e su alc<strong>un</strong>e piattaforme: <strong>per</strong> evitare qu<strong>in</strong>di problemi di<br />

qualsiasi tipo, è meglio scrivere il file di testo senza andare mai a capo con Invio, usando <strong>in</strong>vece solo il .<br />

• Cambiando le dimensioni dei caratteri all'<strong>in</strong>terno di <strong>un</strong>o stesso campo di testo, talvolta si hanno delle spiacevoli<br />

ri<strong>per</strong>cussioni a livello delle righe. Se <strong>in</strong>fatti tariamo le dimensioni del campo <strong>per</strong> contenere <strong>un</strong> numero <strong><strong>in</strong>tero</strong> di righe, e<br />

poi <strong>in</strong>grandiamo <strong>un</strong>a riga con il tag , l'ultima potrebbe risultare tagliata a metà.<br />

• Non tutti i caratteri possono essere importati scrivendoli semplicemente nel campo di testo. Ad esempio, non posso<br />

scrivere:<br />

testo=<strong>Flash</strong> & Actionscript;<br />

dal momento che la e commerciale, "&", ha come significato la divisione delle variabili. Qu<strong>in</strong>di il lettore <strong>per</strong>cepisce<br />

come "testo" solo la prima parte, mentre non visualizza la seconda. Per evitare questo <strong>in</strong>conveniente, bisogna utilizzare<br />

la tecnica dell'URL ENCODING, che consiste nel sostituire alc<strong>un</strong>i caratteri con altri.


Nell'esempio di questo <strong>sito</strong>, gli aggiornamenti sono quelli presi dalla homepage di <strong>Flash</strong>5.it alla data <strong>in</strong> cui ho scritto<br />

questa sezione. Nei collegamenti, poichè <strong>Flash</strong>5.it è costruito <strong>in</strong> ASP, sono presenti le e commerciali <strong>per</strong> identificare i<br />

file ASP. Per poter passare questi caratteri, ho dovuto sostituirli sempre con %26. Qu<strong>in</strong>di, avrei scritto la frase sopra<br />

come:<br />

testo=<strong>Flash</strong> %26 Actionscript;<br />

• <strong>Flash</strong>guru sui tag HTML.<br />

Stampare<br />

Premessa<br />

<strong>Flash</strong> non è troppo flessibile <strong>per</strong> quanto riguarda la stampa. Ha alc<strong>un</strong>i vantaggi enormi, primo fra tutti il poter avere<br />

come oggetto forme vettoriali, e non solo raster, ma anche alc<strong>un</strong>e limitazioni, come quella <strong>in</strong> relazione al colore di<br />

fondo.<br />

Non affronterò il problema <strong>in</strong> modo completo (lo farò <strong>in</strong> altra sede), ma mi limiterò a spiegare la procedura <strong>per</strong> ottenere<br />

<strong>un</strong> particolare tipo di stampa, probabilmente l'<strong>un</strong>ico davvero necessario.<br />

Procedura<br />

F<strong>in</strong>alità<br />

Innanzitutto bisogna stabilire cosa stampare: <strong>in</strong> questo caso abbiamo optato <strong>per</strong> <strong>un</strong>a pag<strong>in</strong>a con i loghi (<strong>in</strong> vettoriale),<br />

alc<strong>un</strong>e righe con i term<strong>in</strong>i del copyright <strong>in</strong> relazione all'uso dei contenuti del <strong>sito</strong>, e l'elenco degli autori e dello staff.<br />

Partiamo dal presupposto che <strong>Flash</strong> dà come sfondo alle proprie stampe il colore di fondo del filmato. Per questo<br />

motivo, siamo praticamente costretti a usare il bianco. Infatti, se il colore di fondo è diverso dal bianco, all'atto della<br />

stampa la pag<strong>in</strong>a verrà colorata con quello impostato: solo che se l'utente non setta volontariamente, quando si apre la<br />

f<strong>in</strong>estra di dialogo con le opzioni della propria stampante, l'area di stampa massima ( e talvolta non basta neanche<br />

questo), attorno all'oggetto rimarrà com<strong>un</strong>que <strong>un</strong>a cornice bianca: potrebbe anche andare bene, <strong>in</strong> alc<strong>un</strong>i casi, ma<br />

generalmente è <strong>un</strong> effetto abbastanza sgradevole.<br />

Altra cosa da considerare è l'area di stampa, e le proporzioni del disegno rispetto ad essa. Per questo motivo useremo<br />

come base le dimensioni di <strong>un</strong> com<strong>un</strong>e foglio A4.<br />

Inf<strong>in</strong>e non avremo la necessità di elim<strong>in</strong>are il comando stampa dal menu contestuale del pulsante destro del mouse, dal<br />

momento che rimuoveremo tutto il menu, e <strong>per</strong> stampare utilizzeremo <strong>un</strong> pulsante.<br />

L'oggetto<br />

Il <strong>Flash</strong> non stampa propriamente degli oggetti, bensì dei frame. Un frame, <strong>per</strong> essere stampabile, deve essere<br />

identificato tramite l'etichetta (label), che deve avere <strong>un</strong> nome particolare: #p. Se ness<strong>un</strong> frame è etichettato <strong>in</strong> questo<br />

modo, non verrà stampato niente. Se più frame hanno questa etichetta, verranno stampati tutti quelli etichettati.<br />

Questa particolarità, nasconde evidentemente <strong>un</strong> problema di non poco conto. Se <strong>in</strong>fatti voglio rendere stampabili più<br />

frame, ma ad esempio poterli stampare separatamente (a scelta dell'utente), non li posso identificare <strong>in</strong> alc<strong>un</strong> modo.<br />

Per fort<strong>un</strong>a, il problema sorge solo con i frame appartenenti alla stessa timel<strong>in</strong>e: se qu<strong>in</strong>di posiziono i frame stampabili<br />

<strong>in</strong> timel<strong>in</strong>e separate, potrò ottere anche stampe dei s<strong>in</strong>goli frame. Per ottenere <strong>un</strong>a timel<strong>in</strong>e separata, il modo più<br />

semplice è di <strong>creare</strong> <strong>un</strong> movieclip. Con il comando pr<strong>in</strong>t, qu<strong>in</strong>di, chiederò di stampare la timel<strong>in</strong>e del movieclip <strong>in</strong>


questione, all'<strong>in</strong>terno del quale ci sarà <strong>un</strong> solo frame con l'etichetta #p. Questo significa anche che se voglio rendere<br />

stampabili più documenti, e poterli stampare separatamente, dovrò <strong>creare</strong> tanti movieclip quanti sono i documenti.<br />

L'area di stampa<br />

Per decidere quali saranno le dimensioni che avranno gli oggetti rispetto alla pag<strong>in</strong>a sulla quale verranno stampati, ho<br />

bisogno di <strong>creare</strong> <strong>un</strong> altro frame. Questo frame dovrà avere <strong>un</strong>'etichetta particolare, #b, e contenere <strong>un</strong> oggetto che mi<br />

rappresenterà l'area di stampa. La proporzione tra il contenuto della stampa e la pag<strong>in</strong>a stampata, sarà determ<strong>in</strong>ata dalla<br />

proporzione tra il contenuto di questi due frame.<br />

Vediamo qualche esempio <strong>per</strong> capire meglio cosa significa. Nel frame etichettato come #p (il frame da stampare), ho <strong>un</strong><br />

cerchio. Nel frame etichettato come #b, ho <strong>un</strong> rettangolo. Consideriamo che il cerchio rimanga di dimensioni costanti,<br />

<strong>in</strong> queste prove, e che a cambiare siano solo le dimensioni del rettangolo.<br />

Il movieclip<br />

Apriamo il file flash5.fla, e visualizziamo la libreria. Clicchiamo sul pulsante + <strong>in</strong> basso a s<strong>in</strong>istra, e aggi<strong>un</strong>giamo <strong>un</strong><br />

movieclip che chiameremo pag<strong>in</strong>a. Aggi<strong>un</strong>giamo <strong>un</strong> altro layer, <strong>in</strong> modo da avere due layer di <strong>un</strong> frame ciasc<strong>un</strong>o: nel<br />

frame <strong>in</strong> basso disegniamo <strong>un</strong> rettangolo di qualsiasi colore (non verrà stampato, qu<strong>in</strong>di può essere più utile che sia<br />

bianco) di dimensioni <strong>in</strong> pixel 210x290, esattamente come <strong>un</strong> foglio A4. Posizioniamo l'angolo su<strong>per</strong>iore s<strong>in</strong>istro del<br />

rettangolo sul centro del movieclip, e blocchiamo il layer.<br />

Nel frame <strong>in</strong> alto disegniamo i contenuti che appariranno nella pag<strong>in</strong>a stampata, basandoci, <strong>per</strong> le posizioni e le<br />

dimensioni, sul rettangolo presente nel layer sottostante. Quando abbiamo creato tutto il contenuto, nel layer <strong>in</strong> alto<br />

aggi<strong>un</strong>giamo <strong>un</strong> frame vuoto con F7. Sblocchiamo il layer <strong>in</strong>feriore, selezioniamo il rettangolo, tagliamolo e<br />

<strong>in</strong>colliamolo nel secondo frame del layer su<strong>per</strong>iore, cancelliamo il layer <strong>in</strong>feriore.<br />

Adesso abbiamo <strong>un</strong> <strong>un</strong>ico layer di due frame. Nel primo frame, abbiamo i contenuti, nel secondo, il rettangolo.<br />

Etichettiamo il primo frame con #p, e il secondo con #b. La posizione dei due frame è <strong>in</strong><strong>in</strong>fluente, basta che non siano


sovrapposti, e così è la loro durata nella timel<strong>in</strong>e. Nel fla d'esempio, <strong>in</strong>fatti, ho posizionato i due frame <strong>un</strong> po' distanziati,<br />

e all<strong>un</strong>gati nella timel<strong>in</strong>e <strong>per</strong>ché si potessero leggere le etichette: il risultato di stampa è identico.<br />

Torniamo alla timel<strong>in</strong>e pr<strong>in</strong>cipale del filmato, e aggi<strong>un</strong>giamo <strong>un</strong> layer: <strong>in</strong> questo layer trasc<strong>in</strong>iamo dalla libreria<br />

<strong>un</strong>'istanza del movieclip pag<strong>in</strong>a. Questo movieclip sarà scandalosamente enorme <strong>per</strong> il nostro filmato, ma le sue<br />

dimensioni e la sua posizione non avranno alc<strong>un</strong>a <strong>in</strong>fluenza sulla stampa. Per cui riduciamolo volentieri anche a <strong>un</strong><br />

decimo delle sue dimensioni orig<strong>in</strong>ali, e nascondiamolo spostandolo al di fuori dello stage. Inf<strong>in</strong>e selezioniamolo ancora<br />

<strong>un</strong>a volta, e diamogli pag<strong>in</strong>a come nome di istanza.<br />

Il comando<br />

pr<strong>in</strong>t ("_root.pag<strong>in</strong>a", "bmovie");<br />

Cosa significa questo comando? Su pr<strong>in</strong>t non c'è niente da dire, essendo l'azione che genera la stampa; _root.pag<strong>in</strong>a<br />

non altro che il <strong>per</strong>corso del movieclip all'<strong>in</strong>terno del quale è presente il frame da stampare. bmovie è <strong>in</strong>vece<br />

l'argomento che specifica che tipo di stampa vogliamo ottenere.<br />

Al posto di bmovie potevamo avere altre due opzioni, bframe e bmax. Nel primo caso, avrebbe considerato come area<br />

di stampa tutta l'area del frame stampabile, scalando gli oggetti <strong>per</strong> riempire la pag<strong>in</strong>a <strong>in</strong> uscita, mentre nel secondo<br />

caso la somma dei riquadri di delimitazione degli oggetti presenti <strong>in</strong> tutti i frame etichettati come #p.<br />

Noi scriviamo <strong>in</strong>vece bmovie, che considera come area di stampa il riquadro di delimitazione degli oggetti presenti nel<br />

frame etichettato come #b (il nostro rettangolo, app<strong>un</strong>to).<br />

Nel caso avessimo voluto stampare delle immag<strong>in</strong>i raster, <strong>in</strong>vece, avremmo potuto usare <strong>un</strong> altro comando:<br />

pr<strong>in</strong>tAsBitmap ("_root.pag<strong>in</strong>a", "bmovie");<br />

Le differenze tra i due comandi sono molto importanti: il primo stampa alla massima risoluzione possibile, mentre il<br />

secondo a quella del filmato. Inoltre pr<strong>in</strong>tAsBitmap <strong>per</strong>mette di mantenere nella stampa gli effetti alpha, mentre il<br />

semplice pr<strong>in</strong>t non può.<br />

Il pulsante<br />

Nel nostro caso, il pulsante sarà nuovamente <strong>un</strong> movieclip. Con lo strumento testo, scriviamo sullo stage la frase che<br />

risulterà cliccabile. Selezioniamola cliccando <strong>un</strong>a volta con il mouse, poi convertiamola <strong>in</strong> movieclip premendo F8.<br />

Torniamo alla timel<strong>in</strong>e pr<strong>in</strong>cipale, selezioniamo il movieclip con la scritta, apriamo il pannello azioni e scriviamo:<br />

onClipEvent (load) {<br />

colore = new Color(this);<br />

}<br />

onClipEvent (mouseMove) {<br />

if (this.hitTest(_root._xmouse, _root._ymouse, false)) {<br />

if (!premuto) {<br />

sopra = true;<br />

colore.setRGB(0xFFCC33);


}<br />

} else {<br />

sopra = false;<br />

if (!premuto) {<br />

colore.setRGB(0x000000);<br />

}<br />

}<br />

updateAfterEvent();<br />

}<br />

onClipEvent (mouseDown) {<br />

if (this.hitTest(_root._xmouse, _root._ymouse, false)) {<br />

premuto = true;<br />

colore.setRGB(0xFF9900);<br />

}<br />

updateAfterEvent();<br />

}<br />

onClipEvent (mouseUp) {<br />

premuto = false;<br />

if (sopra) {<br />

colore.setRGB(0xFFCC33);<br />

pr<strong>in</strong>t ("_root.pag<strong>in</strong>a", "bmax");<br />

} else {<br />

colore.setRGB(0x000000);<br />

}<br />

updateAfterEvent();<br />

}<br />

Senza ripetere <strong>per</strong> l'ennesima volta come simulare il rollover con <strong>un</strong> movieclip, notiamo semplicemente il comando<br />

pr<strong>in</strong>t sottoposto al mouseUp, cioè al rilascio del pulsante s<strong>in</strong>istro del mouse sopra la scritta: <strong>in</strong>fatti solo quando si è sul<br />

movieclip, la variabile premuto è vera.<br />

Adesso <strong>per</strong>ò vogliamo aggi<strong>un</strong>gere <strong>un</strong>a semplice gif rappresentante <strong>un</strong>a stampante vic<strong>in</strong>o alla scritta, e vogliamo che sia<br />

anche cliccabile, come la scritta. Non possiamo <strong>in</strong>serirla nel movieclip, altrimenti cambierebbe colore al rollover. Allora<br />

torniamo alla timel<strong>in</strong>e pr<strong>in</strong>cipale, e posizioniamoci nel frame con il pulsante <strong>per</strong> la stampa. Andiamo al menu<br />

File/import, cerchiamo la nostra gif, e importiamola nel filmato: la selezioniamo, premiamo F8 e la convertiamo <strong>in</strong><br />

movieclip. Torniamo <strong>per</strong> l'ultima volta alla timel<strong>in</strong>e pr<strong>in</strong>cipale, selezioniamo la "stampante", e diamo stampante come<br />

nome di istanza.<br />

Riprendiamo <strong>in</strong> mano lo script della scritta. Aggi<strong>un</strong>giamo due pezzett<strong>in</strong>i:<br />

onClipEvent (load) {<br />

colore = new Color(this);<br />

}<br />

onClipEvent (mouseMove) {<br />

if(this.hitTest(_root._xmouse,_root._ymouse,false)<br />

|| _parent.stampante.hitTest(_root._xmouse, _root._ymouse, true)) {


if (!premuto) {<br />

sopra = true;<br />

colore.setRGB(0xFFCC33);<br />

}<br />

} else {<br />

sopra = false;<br />

if (!premuto) {<br />

colore.setRGB(0x000000);<br />

}<br />

}<br />

updateAfterEvent();<br />

}<br />

onClipEvent (mouseDown) {<br />

if (this.hitTest(_root._xmouse, _root._ymouse, false)<br />

|| _parent.stampante.hitTest(_root._xmouse, _root._ymouse, true)) {<br />

premuto = true;<br />

colore.setRGB(0xFF9900);<br />

}<br />

updateAfterEvent();<br />

}<br />

onClipEvent (mouseUp) {<br />

premuto = false;<br />

if (sopra) {<br />

colore.setRGB(0xFFCC33);<br />

pr<strong>in</strong>t ("_root.pag<strong>in</strong>a", "bmax");<br />

} else {<br />

colore.setRGB(0x000000);<br />

}<br />

updateAfterEvent();<br />

}<br />

Adesso, la scritta cambia colore al rollover su entrambi gli oggetti, ed entrambi, al click del mouse, avviano la stampa.<br />

Barra di scorrimento testo<br />

Introduzione<br />

Iniziamo adesso la costruzione della prima delle sezioni esterne del nostro <strong>sito</strong>. Questa sezione, come previsto dal menu<br />

pr<strong>in</strong>cipale, sarà contenuta <strong>in</strong> <strong>un</strong> filmato dal nome testo.swf: <strong>per</strong> cui creiamo <strong>un</strong> nuovo documento flash, 700x300, frame<br />

rate 24 fps. Andiamo al menu File/Open as Library (apri come libreria), e apriamo il file flash5.fla. Dalla libreria che


appare (con il fondo grigio), trasc<strong>in</strong>iamo nella libreria del nostro nuovo fla il movieclip base. Salviamo con il nome<br />

testo.fla.<br />

Scorrimento<br />

Quello che vogliamo <strong>creare</strong>, <strong>in</strong> questa sezione, è <strong>un</strong>o scorrimento del testo particolare: oltre ai semplici pulsanti <strong>per</strong> lo<br />

scroll, avremo anche <strong>un</strong>a barra di scorrimento a dimensioni fisse, e la possibilità di spostarci velocemente nel testo<br />

cliccando sulla base della barra. Altra cosa importante, potremo cambiare il contenuto del campo di testo, att<strong>in</strong>gendo da<br />

due file txt esterni.<br />

Movieclip scorrimento<br />

Apriamo il file testo.fla, e visualizziamo la libreria. Clicchiamo il pulsante + <strong>in</strong> basso a s<strong>in</strong>istra del pannello, e<br />

aggi<strong>un</strong>giamo <strong>un</strong> nuovo movieclip con il nome scorrimento. All'<strong>in</strong>terno del movieclip scorrimento, creiamo sei layer<br />

come <strong>in</strong> figura.<br />

Nel primo frame del layer testo, <strong>in</strong>seriamo la scritta "caricamento dati...". La selezioniamo, e la convertiamo, tramite F8,<br />

<strong>in</strong> <strong>un</strong> movieclip con il nome caricamento. All'<strong>in</strong>terno del movieclip caricamento, <strong>in</strong>seriamo <strong>un</strong> secondo frame vuoto<br />

(avremo <strong>un</strong>a scritta lampeggiante durante l'attesa), poi torniamo al movieclip scorrimento.<br />

Aggi<strong>un</strong>giamo <strong>un</strong> secondo frame a tutti i layer (nel primo frame, solo il layer testo avrà <strong>un</strong> contenuto).<br />

Ombra<br />

Aggi<strong>un</strong>giamo alla libreria <strong>un</strong> nuovo movieclip, e chiamiamolo ombra. All'<strong>in</strong>terno di questo movieclip, con l'angolo<br />

su<strong>per</strong>iore s<strong>in</strong>istro al centro del movieclip stesso, disegniamo <strong>un</strong> rettangolo 130x5.<br />

Selezioniamo il rettangolo, e andiamo al pannello Fill (Riempimento). Impostiamo il riempimento su L<strong>in</strong>ear Gradient,<br />

attribuiamo lo stesso colore ad entrambi gli <strong>in</strong>dicatori (#333333), e spostiamo quello di s<strong>in</strong>istra <strong>in</strong> modo da essere quasi<br />

al centro dello slider.


A questo p<strong>un</strong>to andiamo al pannello Mixer, e abbassiamo l'<strong>in</strong>dicatore dell'alpha f<strong>in</strong>o allo 0 o poco più sopra.<br />

A questo p<strong>un</strong>to abbiamo <strong>in</strong>serito il gradiente desiderato, ma non con la direzione giusta. Clicchiamo sullo strumento<br />

Pa<strong>in</strong>t Bucket, e poi su Transform Fill.<br />

Clicchiamo sul rettangolo, e spostiamo ,tramite le apposite maniglie, il riempimento <strong>in</strong> modo da ottenere questo:<br />

La barra<br />

Aggi<strong>un</strong>giamo <strong>un</strong> altro movieclip, che chiameremo barraScroll. All'<strong>in</strong>terno del movieclip, trasc<strong>in</strong>iamo dalla libreria<br />

<strong>un</strong>'istanza del movieclip rettangolo, tramite il pannello Info diamole come dimensioni 10 pixel <strong>in</strong> larghezza e 120 <strong>in</strong><br />

altezza, e posizioniamola con l'angolo su<strong>per</strong>iore s<strong>in</strong>istro al centro del movieclip.<br />

La freccia<br />

Aggi<strong>un</strong>giamo <strong>un</strong> nuovo movieclip, nome freccia, al nel quale disegniamo <strong>un</strong> triangol<strong>in</strong>o a pixel con <strong>un</strong> vertice verso<br />

l'alto.<br />

Il pulsante<br />

Aggi<strong>un</strong>giamo ancora <strong>un</strong> movieclip alla libreria, nome pulsante. In questo movieclip, creiamo due layer di <strong>un</strong> frame<br />

ciasc<strong>un</strong>o, ai quali daremo come nomi, dal basso, base e freccia. Nel layer base, trasc<strong>in</strong>iamo dalla libreria <strong>un</strong>'istanza del<br />

movieclip base, al quale diamo come dimensioni 10 pixel <strong>in</strong> larghezza e altezza, e come nome di istanza, ancora base.<br />

Nel layer sopra <strong>in</strong>seriamo <strong>in</strong>vece <strong>un</strong>'istanza del movieclip freccia, alla quale diamo freccia come nome di istanza.


Al movieclip base associamo il seguente script (ci tornerà utile più tardi):<br />

onClipEvent (load) {<br />

coloreRettangolo = new Color(rettangolo);<br />

coloreCornice = new Color(cornice);<br />

}<br />

Avremo così <strong>in</strong>izializzato due istanze dell'oggetto Color, relative ai contenuti del movieclip base, cioè rettangolo e<br />

cornice.<br />

Scroller<br />

Aggi<strong>un</strong>giamo <strong>un</strong> ultimo movieclip, al quale diamo come nome scroller. Nell'<strong>un</strong>ico frame, trasc<strong>in</strong>iamo dalla libreria<br />

<strong>un</strong>'istanza del movieclip pulsante, e la posizioniamo con il vertice su<strong>per</strong>iore s<strong>in</strong>istro sul centro del movieclip. Come<br />

nome di istanza diamo pulsante.<br />

Unione<br />

Adesso abbiamo tutti gli elementi che ci servono. Doppio click, nella libreria, sul movieclip scorrimento. Andiamo al<br />

secondo frame del layer barra, e trasc<strong>in</strong>iamo dalla libreria <strong>un</strong>'istanza del movieclip barraScroll. Diamole come nome di<br />

istanza barra, e posizioniamo il vertice su<strong>per</strong>iore s<strong>in</strong>istro sul centro del movieclip. Tramite il pannello Effect, diamo<br />

come t<strong>in</strong>ta il colore #999999.<br />

Nel secondo frame del layer pulsanti, posizioniamo due istanze del movieclip pulsante, sopra la barra, <strong>un</strong>a con il lato<br />

<strong>in</strong>feriore co<strong>in</strong>cidente con quello su<strong>per</strong>iore della barra (e qu<strong>in</strong>di a coord<strong>in</strong>ate 0,-10), e <strong>un</strong>o con quello <strong>in</strong>feriore,<br />

co<strong>in</strong>cidente con il fondo della barra. Al movieclip di sopra diamo come nome di istanza su, a quello di sotto giu.<br />

Inf<strong>in</strong>e, nel secondo frame del layer scroller, trasc<strong>in</strong>iamo <strong>un</strong>'istanza del movieclip omonimo, e la posizioniamo alle<br />

coord<strong>in</strong>ate 0,0. L'<strong>in</strong>terno del movieclip scorrimento dovrebbe apparire così:<br />

Adesso nel secondo frame del layer "sfondo", trasc<strong>in</strong>iamo <strong>un</strong>'istanza del movieclip base, diamo le dimensioni volute<br />

<strong>per</strong> il campo di testo (nel nostro caso, 330x140), e posizioniamola a s<strong>in</strong>istra della barra, e all'altezza del pulsante su. Nel<br />

layer ombra, posizioniamo due istanze del movieclip ombra, che coprano il lato su<strong>per</strong>iore e s<strong>in</strong>istro del movieclip base,<br />

con il gradiente verso destra e verso il basso. Inf<strong>in</strong>e, nel layer testo, disegniamo la casella vera e propria, le cui<br />

impostazioni saranno:


Graficamente, l'<strong>in</strong>terno del movieclip apparirà così:<br />

I pulsanti<br />

Andiamo alla timel<strong>in</strong>e pr<strong>in</strong>cipale, e creiamo tre livelli. In quello più <strong>in</strong> basso, trasc<strong>in</strong>iamo <strong>un</strong>'istanza del movieclip<br />

scorrimento, alla quale associamo:<br />

onClipEvent (load) {<br />

fscommand ("allowscale", "false");<br />

stop();<br />

loadVariables ("flash.txt", this);<br />

}<br />

onClipEvent (data) {<br />

nextFrame ();<br />

}<br />

codice di cui abbiamo già visto il significato, <strong>per</strong> il caricamento del file di testo esterno.<br />

Nel secondo layer, che chiameremo "pulsanti", scriviamo, <strong>in</strong> due dist<strong>in</strong>te caselle di testo statico, "Introduzione a <strong>Flash</strong><br />

5", e "Introduzione ad Actionscript". Selezioniamo le s<strong>in</strong>gole caselle di testo, prima <strong>un</strong>a poi l'altra, e convertiamole <strong>in</strong><br />

due dist<strong>in</strong>ti movieclip. Al primo diamo come nome di istanza flash, al secondo actionscript (flash.txt e actionscript.txt<br />

saranno i nomi dei due file di testo esterni).<br />

Al primo associamo:<br />

onClipEvent(load){<br />

colore = new Color(this);<br />

colore.setRGB( 0xFFCC33 );<br />

}<br />

onClipEvent(mouseDown){<br />

if(this.hitTest(_root._xmouse,_root._ymouse,false)){


_parent.cambiatesto(_name);<br />

}<br />

}<br />

al secondo:<br />

onClipEvent(load){<br />

colore = new Color(this);<br />

colore.setRGB( 0xCCCCCC );<br />

}<br />

onClipEvent(mouseDown){<br />

if(this.hitTest(_root._xmouse,_root._ymouse,false)){<br />

_parent.cambiatesto(_name);<br />

}<br />

}<br />

I due codici sono <strong>per</strong>fettamente identici, tranne che <strong>per</strong> <strong>un</strong> particolare: il primo imposta il colore del movieclip come<br />

arancione (attivo), il secondo come grigio (non attivo). Quello che fa lo script è, alla pressione del tasto s<strong>in</strong>istro del<br />

mouse sul movieclip, richiamare <strong>un</strong>a f<strong>un</strong>zione sulla _root, passando come variabile il nome di istanza del movieclip che<br />

l'ha chiamata.<br />

Barra di scorrimento testo: azioni<br />

Codici dello scorrimento<br />

Prima di vedere come f<strong>un</strong>zionerà questo scorrimento, vediamo la f<strong>un</strong>zione che è richiamata dai due pulsanti nella _root.<br />

testo = "flash";<br />

f<strong>un</strong>ction cambiatesto(nome){<br />

if(nome != testo){<br />

loadVariables(nome + ".txt", scorrimento);<br />

scorrimento.gotoAndStop(1);<br />

_root[nome].colore.setRGB( 0xFFCC33 );<br />

_root[testo].colore.setRGB( 0xCCCCCC );<br />

testo = nome;<br />

}<br />

}<br />

I due pulsanti, quando richiamano la f<strong>un</strong>zione, passano come parametro il proprio nome di istanza. La f<strong>un</strong>zione riceve<br />

questo parametro, e controlla che non sia già presente (evitando qu<strong>in</strong>di di poter caricare più volte di seguito lo stesso<br />

testo, effetto non gradevole). Se il pulsante non era già stato premuto, carica il file il cui nome è formato dal parametro<br />

più la str<strong>in</strong>ga ".txt" all'<strong>in</strong>terno del movieclip scorrimento (che contiene la casella di testo), e cambia colore ai due<br />

pulsanti, rendendo <strong>un</strong>o attivo e l'altro non attivo. In partenza, il pulsante premuto è "Introduzione a <strong>Flash</strong>5": <strong>in</strong>fatti il<br />

colore era arancione, e il file di testo caricato è flash.txt.<br />

Vediamo passo passo <strong>un</strong> caso:<br />

- viene premuto il tasto "Introduzione a <strong>Flash</strong>5", il cui nome di istanza è flash. Il pulsante richiama la f<strong>un</strong>zione


cambiatesto, a cui passa il parametro "flash" nella variabile nome. La f<strong>un</strong>zione vede che attualmente la variabile nome<br />

è uguale a testo (impostato su flash all'avvio), e non fa niente.<br />

- viene premuto il tasto "Introduzione a Actionscript": nome e testo sono diversi. Il movieclip scorrimento viene<br />

mandato al frame 1, dove c'è il movieclip lampeggiante con la scritta "caricamento dati..", e viene caricato il file esterno<br />

actionscript.txt (loadVariables(nome + ".txt", scorrimento);, se nome è uguale a "actionscript", vorrà dire:<br />

loadVariables("actionscript" + ".txt", scorrimento);). Quando il file esterno sarà stato caricato, il movieclip scorrimento<br />

passerà al frame 2.<br />

A questo p<strong>un</strong>to, vengono cambiati i colori dei pulsanti (servendosi del nome delle variabili tra parentesi quadre), e viene<br />

impostato come "testo", il nome dell'ultimo parametro passato. In questo modo, adesso solo premendo "Introduzione a<br />

<strong>Flash</strong>5", succederà qualcosa.<br />

Codice dei pulsanti<br />

Editiamo il movieclip scorrimento, facendo doppio click sul movieclip nella libreria. Andiamo al livello pulsanti,<br />

secondo frame, e com<strong>in</strong>ciamo con il pulsante su. A questo movieclip associamo:<br />

onClipEvent (mouseDown) {<br />

if (this.hitTest(_root._xmouse,_root._ymouse,false)) {<br />

premuto = true;<br />

base.coloreRettangolo.setRGB( 0xBBBBBB );<br />

}<br />

}<br />

onClipEvent (mouseUp) {<br />

base.coloreRettangolo.setRGB( 0xCCCCCC );<br />

premuto = false;<br />

}<br />

Ricordo che all'<strong>in</strong>terno dei due pulsanti, al movieclip base, avevamo associato <strong>un</strong>o script, che <strong>in</strong>izializzava <strong>un</strong>'istanza<br />

dell'oggetto Color. Questa ci serve <strong>per</strong> modificare i colori dei pulsanti, quando vengono premuti con il tasto s<strong>in</strong>istro del<br />

mouse. Nel dettaglio:<br />

// alla pressione del tasto s<strong>in</strong>istro del mouse<br />

onClipEvent (mouseDown) {<br />

// se il p<strong>un</strong>tatore del mouse è sul movieclip<br />

if (this.hitTest(_root._xmouse,_root._ymouse,false)) {<br />

// setta la variabile "premuto" come vera<br />

premuto = true;<br />

// cambia il colore del pulsante<br />

base.coloreRettangolo.setRGB( 0xBBBBBB );<br />

}<br />

}<br />

// al rilascio del tasto s<strong>in</strong>istro del mouse<br />

onClipEvent (mouseUp) {<br />

// riprist<strong>in</strong>a il colore del pulsante<br />

base.coloreRettangolo.setRGB( 0xCCCCCC );


setta la variabile "premuto" come falsa<br />

premuto = false;<br />

}<br />

Il codice del pulsante giu è <strong>per</strong>fettamente identico, solo con <strong>un</strong> pezzetto <strong>in</strong> più all'<strong>in</strong>izio:<br />

onClipEvent (load) {<br />

freccia._rotation = 180;<br />

freccia._x = 8;<br />

freccia._y = 7;<br />

}<br />

onClipEvent (mouseDown) {<br />

if (this.hitTest(_root._xmouse,_root._ymouse,false)) {<br />

premuto = true;<br />

base.coloreRettangolo.setRGB( 0xBBBBBB );<br />

}<br />

}<br />

onClipEvent (mouseUp) {<br />

base.coloreRettangolo.setRGB( 0xCCCCCC );<br />

premuto = false;<br />

}<br />

Questo serve semplicemente a ruotare la freccia di 180 gradi (altrimenti p<strong>un</strong>terebbe verso l'alto anche nel pulsante giu),<br />

e a posizionarla più efficacemente. F<strong>in</strong>o ad adesso i pulsanti non fanno niente, se non rendere vera <strong>un</strong>a variabile quando<br />

premuti, e falsa quando non premuti.<br />

Il codice dello scroller<br />

Selezioniamo il movieclip scroller, e associamogli:<br />

// ***** prima parte *****<br />

onClipEvent(load){<br />

pulsante.freccia._visible = 0;<br />

hBarra = _parent.barra._height;<br />

max = Math.ro<strong>un</strong>d(hBarra-_height);<br />

spazio = max/(_parent.testo.maxscroll);<br />

f<strong>un</strong>ction scorri(){<br />

_parent.testo.scroll = (_y/spazio)+1;<br />

updateAfterEvent();<br />

}<br />

}<br />

// ***** seconda parte *****<br />

onClipEvent (mouseMove) {<br />

if (premuto) {<br />

scorri();


}<br />

updateAfterEvent();<br />

}<br />

// ***** terza parte *****<br />

onClipEvent (mouseDown) {<br />

if (this.hitTest(_root._xmouse,_root._ymouse,false)) {<br />

pulsante.base.coloreRettangolo.setRGB( 0xBBBBBB );<br />

premuto = true;<br />

this.startDrag(false, _x, 0, _x, max);<br />

}<br />

}<br />

// ***** quarta parte *****<br />

onClipEvent (mouseUp) {<br />

pulsante.base.coloreRettangolo.setRGB( 0xCCCCCC );<br />

premuto = false;<br />

stopDrag();<br />

}<br />

// ***** qu<strong>in</strong>ta parte *****<br />

onClipEvent (enterFrame) {<br />

if(_parent.su.premuto){<br />

_y -= spazio;<br />

if(_y < 0){<br />

_y = 0;<br />

}<br />

scorri();<br />

}<br />

if(_parent.giu.premuto){<br />

_y += spazio;<br />

if(_y > max){<br />

_y = max;<br />

}<br />

scorri();<br />

}<br />

}<br />

Il codice non è complicato come sembra, ma vediamolo lo stesso <strong>un</strong> passo alla volta.<br />

Nella prima parte, si dice che al caricamento del movieclip, la freccia dentro il movieclip pulsante, dentro il movieclip<br />

scroller, deve essere <strong>in</strong>visibile. Dopodiché si attribuiscono a delle variabili alc<strong>un</strong>i valori che rimarranno fissi nel corso<br />

della riproduzione.<br />

- hBarra è l'altezza del movieclip barra, presente nel livello su<strong>per</strong>iore.<br />

- max è la differenza tra l'altezza della barra, e l'altezza dello scroller<br />

- spazio è il quoto della divisione tra max e il numero di righe totali del testo (calcolato al momento)<br />

- la f<strong>un</strong>zione scorri, quando chiamata, attribuisce allo scroll della casella di testo con nome testo, il valore del quoto<br />

della divisione tra la posizione dello scroller sull'asse delle Y e spazio, il tutto aumentato di <strong>un</strong>o, con <strong>un</strong> forzato refresh


dello schermo.<br />

Ragioniamo su questi valori. Io devo capire quale valore dare allo scroll di testo, cioè che numero di riga deve essere<br />

quella che appare <strong>in</strong> cima al campo di testo, sulla base della posizione dello scroller. Più elevato è il valore della Y, più<br />

elevato sarà quello dello scroll. E' evidente che il rapporto tra questi due valori non possa essere fisso, dal momento che<br />

se ci sono più righe da far scorrere, più brevi <strong>per</strong>ché più numerosi dovranno essere gli spostamenti da fare, <strong>per</strong><br />

aumentare lo scroll di <strong>un</strong>a <strong>un</strong>ità. Questo mi impone di trovare <strong>un</strong>a formula generale, che valga <strong>per</strong> qualsiasi numero di<br />

righe.<br />

Consideriamo lo spazio che deve <strong>per</strong>correre lo scroller dal p<strong>un</strong>to di partenza f<strong>in</strong>o alla f<strong>in</strong>e della barra. Se lo spazio fosse<br />

quanto la barra, lo scroller coprirebbe, a f<strong>in</strong>e corsa, il pulsante giu. Invece, lo spazio da <strong>per</strong>correre è pari all'altezza della<br />

barra meno l'altezza dello scroller. In questo modo, lo scroller non coprirà mai il pulsante giu. Questo spazio è max:<br />

max = Math.ro<strong>un</strong>d(hBarra-_height);<br />

Se lo scroller deve scorrere dieci righe, nello spazio di 10 quadretti, ad ogni spostamento di <strong>un</strong> quadretto corrisponderà<br />

lo scroll di <strong>un</strong>a riga. Ma se <strong>in</strong> dieci quadretti deve scorrere 20 righe, lo spostamento sarà di 0,5 quadretti. Se le righe<br />

sono 40, lo spostamento sarà di 0.25 quadretti. Qu<strong>in</strong>di, lo spazio è dato dall'ampiezza dello spostamento fratto il numero<br />

di righe:<br />

spazio = max/(_parent.testo.maxscroll);<br />

In base a quanto visto, si deduce che il valore a cui corrisponderà testo.scroll sarà dato dalla posizione dello scroller<br />

sull'asse delle Y fratto spazio, cioè lo spostamento. Però, considerato che il valore di scroll <strong>in</strong>izia da 1 (il campo di testo<br />

<strong>in</strong>izia con <strong>un</strong>a riga piena, la numero 1), bisogna aumentare questo valore di <strong>un</strong>a <strong>un</strong>ità.<br />

Per questo motivo, quando richiameremo la f<strong>un</strong>zione scorri(), questa controllerà la posizione dello scroller e farà i giusti<br />

calcoli, scrollando il testo.<br />

Consideriamo la terza parte (alla seconda torniamo poi). Alla pressione del tasto s<strong>in</strong>istro del mouse (mouseDown), se il<br />

p<strong>un</strong>tatore del mouse è sul movieclip scroller (if (this.hitTest(_root._xmouse,_root._ymouse,false))), allora cambia il<br />

colore dello scroller, setta la variabile premuto come vera, e <strong>in</strong>izia a trasc<strong>in</strong>are lo scroller.


this.startDrag(false, _x, 0, _x, max);<br />

Questa espressione significa che il trasc<strong>in</strong>amento dello scroller, deve essere fatto nel p<strong>un</strong>to <strong>in</strong> cui si è premuto (false), e<br />

che i limiti del trasc<strong>in</strong>amento sono: a s<strong>in</strong>istra, la posizione della _x della barra, così come a destra, il che significa che lo<br />

scroller si muove solo <strong>in</strong> verticale. In alto, lo 0: <strong>in</strong>fatti la barra ha il vertice su<strong>per</strong>iore s<strong>in</strong>istro sul centro del movieclip<br />

scorrimento. In basso, max.<br />

Nella quarta parte: al rilascio del tasto s<strong>in</strong>istro del mouse, riprist<strong>in</strong>a il colore dello scroller, setta la variabile premuto<br />

come falsa, e smetti di trasc<strong>in</strong>are.<br />

Nella seconda parte, viene il p<strong>un</strong>to più importante. Allo spostamento del mouse, se premuto è vera (e qu<strong>in</strong>di abbiamo<br />

cliccato sullo scroller e lo stiamo trasc<strong>in</strong>ando), chiama la f<strong>un</strong>zione scorri(), e modifica lo scroll di conseguenza.<br />

Adesso, nella qu<strong>in</strong>ta parte, entrano <strong>in</strong> gioco le variabili che venivano impostate nei pulsanti. La posizione dello scroller,<br />

e qu<strong>in</strong>di lo scroll di testo, devono essere modificati anche da lì. Utilizzando la stessa formula, se è vera la variabile<br />

premuto <strong>in</strong> su, lo scroller viene spostato verso l'alto, se viene premuto il pulsante giu, ed è qu<strong>in</strong>di vera premuto <strong>in</strong> giù,<br />

lo scroller viene spostato verso il basso. Ad ogni spostamento nella riproduzione del frame, viene richiamata la f<strong>un</strong>zione<br />

scorri().<br />

Ultimo accorgimento da prendere: spostando su e giù lo scroller, si potrebbe farlo andare oltre i pulsanti. Allora, se<br />

stiamo premendo il pulsante su, e lo scroller su<strong>per</strong>a verso l'alto lo zero (siamo <strong>in</strong> cima alla barra), lo scroller viene<br />

portato sullo zero. Se stiamo scrollando verso il basso, e lo scroller su<strong>per</strong>a <strong>in</strong> basso la barra, lo scroller viene riportato al<br />

valore di max.<br />

Il codice della barra<br />

Andiamo al layer "barra" del movieclip scorrimento, e selezioniamo la barra stessa. A questa associamo:<br />

onClipEvent(mouseDown){<br />

hBarra = _height;<br />

hScroller = _parent.scroller._height;<br />

max = hBarra - hScroller;<br />

if(this.hitTest(_root._xmouse,_root._ymouse,false) && !_parent.scroller.premuto){<br />

if(_ymouse < max && _ymouse>hScroller){<br />

_parent.scroller._y = _ymouse;<br />

}else if(_ymouse >= max){<br />

_parent.scroller._y = max;<br />

}else if(_ymouse


assegna a hBarra il valore dell'altezza di barra<br />

hBarra = _height;<br />

// assegna a hScroller il valore dell'altezza di scroller<br />

hScroller = _parent.scroller._height;<br />

// assegna a max il valore dell'altezza della barra meno l'altezza dello scroller<br />

max = hBarra - hScroller;<br />

// se con il mouse siamo sulla barra, ma non sullo scroller<br />

if(this.hitTest(_root._xmouse,_root._ymouse,false) && !_parent.scroller.premuto){<br />

// se il p<strong>un</strong>to dove tocco la barra è m<strong>in</strong>ore di max e maggiore di hScroller<br />

if(_ymouse < max && _ymouse>hScroller){<br />

// posiziona lo scroller all'altezza di quel p<strong>un</strong>to<br />

_parent.scroller._y = _ymouse;<br />

// altrimenti, se il p<strong>un</strong>to dove tocco è maggiore o uguale a max<br />

}else if(_ymouse >= max){<br />

// posiziona lo scroller su max<br />

_parent.scroller._y = max;<br />

// altrimenti, se il p<strong>un</strong>to dove tocco è m<strong>in</strong>ore o uguale a hScroller<br />

}else if(_ymouse


Disegno<br />

Importazione delle immag<strong>in</strong>i<br />

Per <strong>creare</strong> questo slider, ho utilizzato delle immag<strong>in</strong>i dei pannelli del <strong>Flash</strong> 5, catturate con l'Hy<strong>per</strong>Snap DX: questo<br />

programma <strong>per</strong>mette di salvare come file immag<strong>in</strong>e tutto ciò che viene visualizzato sul monitor, con varie scelte sulle<br />

dimensioni dell'area catturata. Per questo scopo, si può anche ricorrere al com<strong>un</strong>e pulsante Stamp da tastiera, <strong>per</strong> poi<br />

<strong>in</strong>collare, dagli app<strong>un</strong>ti, l'immag<strong>in</strong>e <strong>in</strong> <strong>un</strong> editor appo<strong>sito</strong>.<br />

Dal momento che le dimensioni di <strong>un</strong> filmato <strong>in</strong> <strong>Flash</strong> devono essere le più ridotte possibili, f<strong>in</strong> dove lo <strong>per</strong>mette le<br />

qualità, è conveniente ottimizzarle prima dell'importazione. Qu<strong>in</strong>di le convertiamo <strong>in</strong> gif, riducendo al m<strong>in</strong>imo il<br />

numero di colori necessari.<br />

Apriamo il file slide.fla, e andiamo al menu File/Import. Troviamo la cartella contenente le immag<strong>in</strong>i (nel nostro caso 6),<br />

selezioniamole tutte e importiamole nella libreria.<br />

Selezioniamo <strong>un</strong>a a <strong>un</strong>a le immag<strong>in</strong>i, e convertiamole <strong>in</strong> movieclip: questo serve a evitare <strong>un</strong> probabile bug del <strong>Flash</strong>,<br />

che, <strong>in</strong> presenza di molte immag<strong>in</strong>i sullo stage, tende a nasconderle o a renderle sgranate.<br />

Il pulsante<br />

Apriamo, con doppio click nella libreria, il movieclip base. Nel layer <strong>in</strong>feriore, è presente il movieclip rettangolo. A<br />

questo associamo:<br />

onClipEvent (load) {<br />

colore = new Color(this);<br />

colore.setRGB(0x000000);<br />

_alpha = 50;<br />

}<br />

onClipEvent (enterFrame) {<br />

if (this.hitTest(_root._xmouse, _root._ymouse, true)) {<br />

sopra = true;<br />

if (_alpha>0) {<br />

_alpha -= 5;<br />

}<br />

} else {


sopra = false;<br />

if (_alpha


Creiamo nella libreria <strong>un</strong> nuovo movieclip che chiameremo out.All'<strong>in</strong>terno di questo movieclip, posizioneremo,<br />

<strong>in</strong>differentemente su due layer o <strong>un</strong>o solo, due campi di testo d<strong>in</strong>amici. Al di là della scelta di colore e Font, le<br />

impostazioni, e le variabili associate, dei due campi, saranno queste:<br />

Il primo campo di testo, a cui è associata la variabile titolo, conterrà il nome del pannello cliccato, mentre il secondo<br />

campo di testo, <strong>un</strong>a breve descrizione.<br />

Lo stage<br />

Andiamo alla timel<strong>in</strong>e pr<strong>in</strong>cipale del nostro filmato. Trasc<strong>in</strong>iamo sullo stage <strong>un</strong>'istanza del movieclip out, alla quale<br />

daremo out come nome di istanza. In <strong>un</strong> altro livello, trasc<strong>in</strong>iamo <strong>un</strong>a istanza del movieclip barra, alla quale daremo,<br />

come nome di istanza, barra1. Inf<strong>in</strong>e, posizioniamo sullo stage <strong>un</strong> movieclip vuoto, al quale assoceremo lo script:<br />

onClipEvent (load) {<br />

centro = _root.barra1._x;<br />

larghezza = _root.barra1._width;<br />

destra = centro + larghezza;<br />

s<strong>in</strong>istra = centro - larghezza;<br />

_root.barra1.duplicateMovieClip("barra2", 2);<br />

_root.barra2._x = destra;<br />

}<br />

onClipEvent (mouseMove) {<br />

_x = _root._xmouse;<br />

}<br />

onClipEvent (enterFrame) {<br />

mouseX = Math.ro<strong>un</strong>d(_x-centro)*-1;<br />

mouseX = Math.ro<strong>un</strong>d(mouseX/15);<br />

_root.barra1._x += mouseX;<br />

_root.barra2._x += mouseX;<br />

barra1X = _root.barra1._x;


arra2X = _root.barra2._x;<br />

if (barra1X < s<strong>in</strong>istra) {<br />

_root.barra1._x = barra2X + larghezza;<br />

}<br />

if (barra2X < s<strong>in</strong>istra) {<br />

_root.barra2._x = barra1X + larghezza;<br />

}<br />

if (barra1X > destra) {<br />

_root.barra1._x = barra2X - larghezza;<br />

}<br />

if (barra2X > destra) {<br />

_root.barra2._x = barra1X - larghezza;<br />

}<br />

}<br />

La disposizione f<strong>in</strong>ale degli oggetti sullo stage sarà questa:<br />

Il movieclip barra1 va posizionato al centro dello stage. E' da notare che la barra contenente le immag<strong>in</strong>i, <strong>per</strong> questo<br />

tipo di slider, deve essere più larga dell'area visibile nel filmato. In questo caso, qu<strong>in</strong>di, è più larga dello stage, ma<br />

laddove ci fosse <strong>un</strong>a maschera, basterebbe che fosse più larga della maschera stessa.<br />

La f<strong>un</strong>zione<br />

Nel primo frame del filmato, nella timel<strong>in</strong>e pr<strong>in</strong>cipale, <strong>in</strong>seriamo questo script:<br />

fscommand ("allowscale", "false");<br />

titoli = new Array(contenuto1);<br />

sottotitoli = new Array(contenuto2);<br />

f<strong>un</strong>ction comandi (num) {<br />

out.titolo = "Pannello " + titoli[num];<br />

out.sottotitolo = sottotitoli[num];<br />

}<br />

Per questioni di spazio non riporto ciò che è al posto di contenuto1 e contenuto2. In s<strong>in</strong>tesi, ci sono <strong>in</strong> sequenza i titoli<br />

associati ai movieclip <strong>in</strong> questo formato:<br />

"0","titolo1","titolo2","titolo3","titolo4","titolo5","titolo6"<br />

e i sottotitoli allo stesso modo. Qu<strong>in</strong>di, all'avvio del filmato, creo <strong>un</strong>a sequenza di titoli e di sottotitoli a coppie,<br />

identificabili attraverso la loro posizione negli array.<br />

Slide di immag<strong>in</strong>i: azioni


L'actionscript<br />

Pulsanti<br />

Partiamo dall'<strong>in</strong>terno delle barre. Abbiamo 6 movieclip contenenti le immag<strong>in</strong>i, co<strong>per</strong>ti da 6 movieclip base. Ogni<br />

movieclip base ha <strong>un</strong> nome di istanza, clip001, clip002 eccetera. Dentro ogni movieclip, c'è lo stesso rettangolo a cui è<br />

associato il primo script che abbiamo visto. Vediamo la prima parte:<br />

onClipEvent (load) {<br />

colore = new Color(this);<br />

colore.setRGB(0x000000);<br />

_alpha = 50;<br />

}<br />

Al caricamento del movieclip (e vale <strong>per</strong> tutti i movieclip), il colore verrà settato sul nero, e l'alpha al 50%. Qu<strong>in</strong>di noi<br />

vedremo le immag<strong>in</strong>i attraverso <strong>un</strong> "velo" scuro.<br />

Nel secondo pezzo:<br />

onClipEvent (load) {<br />

colore = new Color(this);<br />

colore.setRGB(0x000000);<br />

_alpha = 50;<br />

}<br />

onClipEvent (enterFrame) {<br />

if (this.hitTest(_root._xmouse, _root._ymouse, true)) {<br />

sopra = true;<br />

if (_alpha>0) {<br />

_alpha -= 5;<br />

}<br />

} else {<br />

sopra = false;<br />

if (_alpha


Inoltre, quando il mouse è sopra il movieclip, la variabile sopra è vera, altrimenti è falsa. Il sa<strong>per</strong>e se siamo sopra il<br />

movieclip, <strong>in</strong>fatti, ci serve <strong>per</strong> l'ultimo pezzo del codice:<br />

onClipEvent (mouseDown) {<br />

if (sopra) {<br />

_root.comandi(substr<strong>in</strong>g(_parent._name,7,1));<br />

}<br />

}<br />

Se sopra è vera, quando clicchiamo con il pulsante s<strong>in</strong>istro del mouse, viene richiamata la f<strong>un</strong>zione comandi che sta<br />

nella root, alla quale viene passato <strong>un</strong> parametro particolare: <strong>un</strong>a sottostr<strong>in</strong>ga, della l<strong>un</strong>ghezza di <strong>un</strong> carattere, che<br />

rappresenta la settima lettera del nome di istanza del movieclip che contiene il rettangolo.<br />

Ora, ogni movieclip rettangolo è contenuto nel movieclip base, che ha rispettivamente nome di istanza, dentro barra,<br />

clip001, clip002, clip003... Quando clicchiamo su <strong>un</strong> rettangolo, viene preso il nome di istanza, viene tolto "clip00" e<br />

rimane la settima lettera, cioè <strong>un</strong> numero da 1 a 6. E' questo numero, che viene <strong>in</strong>viato come parametro alla f<strong>un</strong>zione<br />

della root. In pratica, se clicco sopra la seconda immag<strong>in</strong>e, che sta sotto il movieclip clip002, alla f<strong>un</strong>zione comandi<br />

viene <strong>in</strong>viato il parametro 2.<br />

F<strong>un</strong>zione<br />

Cosa fa la f<strong>un</strong>zione, quando riceve il parametro? (facciamo l'esempio con il 2). Prende l'array titoli e ne considera<br />

l'elemento [2]. Questo elemento non sarebbe il secondo dell'array, ma il terzo, poiché la numerazione dell'array parte da<br />

zero: <strong>per</strong> questo motivo, il primo elemento dell'array è <strong>un</strong>o "0", che serve a spostare <strong>in</strong> avanti tutti gli elementi.<br />

Considerato allora questo elemento, lo scrive nella casella titolo nel movieclip out, poi prende l'elemento [2] dell'array<br />

sottotitoli, e lo scrive nella casella sottotitoli. In questo modo, ogni volta che viene cliccato su <strong>un</strong> movieclip, vengono<br />

scritte nelle caselle, le <strong>in</strong>formazioni corrispondenti.<br />

Lo slider<br />

Adesso il codice più difficile da comprendere, quello che <strong>per</strong>mette alle due barre di scorrere. Il codice sta tutto nel<br />

movieclip vuoto presente sullo stage, al quale ho dato il nome di istanza cursore <strong>per</strong> renderlo identificabile nel<br />

Debugger e nel Movie Explorer.<br />

onClipEvent (load) {<br />

centro = _root.barra1._x;<br />

larghezza = _root.barra1._width;<br />

destra = centro + larghezza;<br />

s<strong>in</strong>istra = centro - larghezza;<br />

_root.barra1.duplicateMovieClip("barra2", 2);<br />

_root.barra2._x = destra;<br />

}<br />

onClipEvent (mouseMove) {<br />

_x = _root._xmouse;<br />

}<br />

onClipEvent (enterFrame) {<br />

mouseX = Math.ro<strong>un</strong>d(_x-centro)*-1;


mouseX = Math.ro<strong>un</strong>d(mouseX/15);<br />

_root.barra1._x += mouseX;<br />

_root.barra2._x += mouseX;<br />

barra1X = _root.barra1._x;<br />

barra2X = _root.barra2._x;<br />

if (barra1X < s<strong>in</strong>istra) {<br />

_root.barra1._x = barra2X + larghezza;<br />

}<br />

if (barra2X < s<strong>in</strong>istra) {<br />

_root.barra2._x = barra1X + larghezza;<br />

}<br />

if (barra1X > destra) {<br />

_root.barra1._x = barra2X - larghezza;<br />

}<br />

if (barra2X > destra) {<br />

_root.barra2._x = barra1X - larghezza;<br />

}<br />

}<br />

Vediamolo <strong>un</strong> pezzo alla volta.<br />

onClipEvent (load) {<br />

centro = _root.barra1._x;<br />

larghezza = _root.barra1._width;<br />

destra = centro + larghezza;<br />

s<strong>in</strong>istra = centro - larghezza;<br />

_root.barra1.duplicateMovieClip("barra2", 2);<br />

_root.barra2._x = destra;<br />

}<br />

Al caricamento del movieclip, vengono settate alc<strong>un</strong>e variabili:<br />

• Alla variabile centro viene assegnato il valore della posizione di barra1 sull'asse delle x (qu<strong>in</strong>di il centro del filmato,<br />

350).<br />

• Alla variabile larghezza viene assegnato il valore della larghezza di barra1.<br />

• Alla variabile destra viene assegnato il valore di centro più larghezza.<br />

• Alla variabile s<strong>in</strong>istra quello di centro meno larghezza.<br />

Qu<strong>in</strong>di, barra1 viene duplicata con il nome di barra2, e barra2 viene posizionata subito a destra di barra1. Questo è<br />

quello che otteniamo (molto rimpicciolito):<br />

Abbiamo preso il filmato, e ne abbiamo stabilito il centro: poi abbiamo stabilito la posizione di due limiti immag<strong>in</strong>ari, a<br />

destra e s<strong>in</strong>istra, distanti dal centro quanto la barra. Abbiamo qu<strong>in</strong>di duplicato la barra e messo la copia accanto alla<br />

prima.


onClipEvent (mouseMove) {<br />

_x = _root._xmouse;<br />

}<br />

Con queste righe stabiliamo che, al movimento del mouse, il cursore debba rimanere alla stessa altezza sull'asse delle X<br />

(segue il mouse <strong>in</strong> tutti i suoi spostamenti).<br />

onClipEvent (enterFrame) {<br />

mouseX = Math.ro<strong>un</strong>d(_x-centro)*-1;<br />

mouseX = Math.ro<strong>un</strong>d(mouseX/15);<br />

_root.barra1._x += mouseX;<br />

_root.barra2._x += mouseX;<br />

barra1X = _root.barra1._x;<br />

barra2X = _root.barra2._x;<br />

if (barra1X < s<strong>in</strong>istra) {<br />

_root.barra1._x = barra2X + larghezza;<br />

}<br />

if (barra2X < s<strong>in</strong>istra) {<br />

_root.barra2._x = barra1X + larghezza;<br />

}<br />

if (barra1X > destra) {<br />

_root.barra1._x = barra2X - larghezza;<br />

}<br />

if (barra2X > destra) {<br />

_root.barra2._x = barra1X - larghezza;<br />

}<br />

}<br />

Ad ogni riproduzione del movieclip, vengono fatti questi calcoli.<br />

mouseX = Math.ro<strong>un</strong>d(_x-centro)*-1;<br />

Viene stabilito, <strong>in</strong>nanzitutto, il fattore di accelerazione mouseX, cioè a che velocità devono muoversi le barre<br />

(l'ampiezza dello spostamento). Questo fattore è l'<strong>in</strong>verso della distanza del movieclip cursore (che segue il mouse) dal<br />

centro del filmato: qu<strong>in</strong>di, più vic<strong>in</strong>o sono al centro del filmato con il mouse, più lente si muoveranno (_x - centro tende<br />

a 0). E questo movimento, dal momento che moltiplico il fattore <strong>per</strong> -1, sarà <strong>in</strong>verso, come <strong>per</strong> <strong>un</strong>a cloche d'aereo: con<br />

il mouse a destra del filmato, le barre scorreranno verso s<strong>in</strong>istra.<br />

mouseX = Math.ro<strong>un</strong>d(mouseX/15);<br />

Il valore di mouseX viene diviso <strong>per</strong> 15: con questa espressione, determ<strong>in</strong>iamo effettivamente la velocità di movimento.<br />

Più è basso il numero che mettiamo al posto di 15, più veloci saranno le barre.<br />

_root.barra1._x += mouseX;<br />

_root.barra2._x += mouseX;


Stabilita l'entità degli spostamenti, spostiamo le barre sommando alla loro attuale posizione il valore di mouseX. Dal<br />

momento che mouseX uguale <strong>per</strong> entrambe, le barre si muoveranno sempre rimanendo <strong>un</strong>a accanto all'altra.<br />

onClipEvent (enterFrame) {<br />

mouseX = Math.ro<strong>un</strong>d(_x-centro)*-1;<br />

mouseX = Math.ro<strong>un</strong>d(mouseX/15);<br />

_root.barra1._x += mouseX;<br />

_root.barra2._x += mouseX;<br />

barra1X = _root.barra1._x;<br />

barra2X = _root.barra2._x;<br />

if (barra1X < s<strong>in</strong>istra) {<br />

_root.barra1._x = barra2X + larghezza;<br />

}<br />

if (barra2X < s<strong>in</strong>istra) {<br />

_root.barra2._x = barra1X + larghezza;<br />

}<br />

if (barra1X > destra) {<br />

_root.barra1._x = barra2X - larghezza;<br />

}<br />

if (barra2X > destra) {<br />

_root.barra2._x = barra1X - larghezza;<br />

}<br />

}<br />

Assegniamo a barra1X e barra2X i valori delle rispettive posizioni delle due barre. Dovremo qu<strong>in</strong>di considerare 4<br />

possibilità, grazie alle quali lo scorrimento diventa cont<strong>in</strong>uo. Prendiamo due dei casi <strong>in</strong> considerazione, il cui<br />

f<strong>un</strong>zionamento vale anche <strong>per</strong> gli altri:<br />

if (barra1X < s<strong>in</strong>istra) {<br />

_root.barra1._x = barra2X + larghezza;<br />

}<br />

Le barra1 si sta spostando verso s<strong>in</strong>istra: quando il suo centro ha su<strong>per</strong>ato la posizione del limite s<strong>in</strong>istra, la sua nuova<br />

posizione sarà a destra di barra2, <strong>per</strong> l'esattezza alla distanza della larghezza della barra dal suo centro. Con <strong>un</strong>a barra<br />

questo è quello che succede:<br />

La cosa importante, è che questo vale anche <strong>per</strong> l'altra barra, che dovrà spostarsi a destra di barra1. Se guardiamo le<br />

due barre assieme, vedremo che <strong>in</strong> ogni momento c'è <strong>un</strong>a barra sullo stage: se qu<strong>in</strong>di le barre sono uguali, avremo <strong>un</strong>o<br />

scorrimento cont<strong>in</strong>uo.<br />

Le f<strong>in</strong>estre<br />

Introduzione<br />

Passiamo alla terza sezione esterna: <strong>in</strong> questa creeremo delle f<strong>in</strong>estre trasc<strong>in</strong>abili e m<strong>in</strong>imizzabili, contenenti del testo.<br />

Le f<strong>in</strong>estre potranno essere portate <strong>in</strong> primo piano semplicemente cliccandoci sopra, come quelle di W<strong>in</strong>dows, <strong>per</strong>


<strong>in</strong>tenderci. Inoltre, nel nostro filmato, creeremo <strong>un</strong>'<strong>un</strong>ica f<strong>in</strong>estra: a decidere il numero e il contento, sarà <strong>un</strong> file di testo<br />

esterno.<br />

Come dalla f<strong>un</strong>zione del menu, il filmato dovrà chiamarsi f<strong>in</strong>estre.swf. Qu<strong>in</strong>di creiamo <strong>un</strong> nuovo progetto <strong>Flash</strong>, con le<br />

stesse caratteristiche dei precedenti, e anche <strong>in</strong> questo importiamo il movieclip base. Inf<strong>in</strong>e salviamo con il nome<br />

f<strong>in</strong>estre.fla<br />

Le f<strong>in</strong>estre<br />

Disegno<br />

Apriamo il file f<strong>in</strong>estre.fla: clicchiamo sul pulsante + nella libreria, e aggi<strong>un</strong>giamo <strong>un</strong> movieclip che chiameremo<br />

f<strong>in</strong>estra. All'<strong>in</strong>terno di questo movieclip, creiamo 7 layer di due frame ciasc<strong>un</strong>o, con i nomi come quelli <strong>in</strong> figura.<br />

Prima di tutto, <strong>in</strong> <strong>un</strong> layer qualsiasi, al primo frame mettiamo <strong>un</strong>o stop(). Nel layer "base", <strong>in</strong> basso, trasc<strong>in</strong>iamo dalla<br />

libreria <strong>un</strong>'istanza del movieclip base: come dimensioni assegniamo 200x130, lo posizioniamo con il lato su<strong>per</strong>iore al<br />

centro del movieclip, ruotato di 180 gradi, <strong>in</strong> modo che sembri <strong>in</strong> rilievo.<br />

Nel secondo frame dello stesso layer, posizioniamo <strong>un</strong>'altra istanza del movieclip base, sempre nella stessa posizione<br />

rispetto al movieclip, solo che questa volta le dimensioni saranno 200x22. Infatti, il secondo frame del movieclip<br />

f<strong>in</strong>estra, conterrà la grafica della f<strong>in</strong>estra ridotta.<br />

Andiamo al primo frame del layer "<strong>in</strong>terno". Trasc<strong>in</strong>iamo dalla libreria <strong>un</strong>'istanza del movieclip base, come dimensioni<br />

assegniamo 195x105, <strong>per</strong> poi posizionarla alle coord<strong>in</strong>ate -97.5,22. Associamo al movieclip:<br />

onClipEvent(load){<br />

colore = new Color(rettangolo);<br />

colore.setRGB(0xEEEEEE);<br />

}<br />

<strong>in</strong> modo che appaia (ma solo il rettangolo all'<strong>in</strong>terno, a cui si riferisce lo script), più scuro di quello di base. Il secondo<br />

frame lo lasciamo vuoto.


Andiamo al primo frame del layer "rettangolo", nel quale trasc<strong>in</strong>iamo dalla libreria <strong>un</strong>'istanza del movieclip rettangolo.<br />

Lo stesso contenuto (con F5), lo passiamo anche al secondo frame, e assegniamo come nome di istanza rettangolo.<br />

Allo stesso modo, nei due frame del layer cornice, <strong>in</strong>seriamo <strong>un</strong>'istanza del movieclip cornice, che t<strong>in</strong>geremo di nero<br />

tramite il pannello Effetti. Se esportiamo adesso, questo è quello che vediamo.<br />

Nell'<strong>un</strong>ico frame del layer "testo", <strong>in</strong>seriamo <strong>un</strong>a casella di testo della grandezza del rettangolo <strong>in</strong> "<strong>in</strong>terno": le opzioni<br />

saranno testo d<strong>in</strong>amico, multi-l<strong>in</strong>ea, html, variabile associata testo. Nel layer "titolo", <strong>in</strong>seriamo <strong>in</strong> entrambi i frame <strong>un</strong>a<br />

casella di testo delle dimensioni della barra alta, con queste opzioni: testo d<strong>in</strong>amico, l<strong>in</strong>ea s<strong>in</strong>gola, html, variabile<br />

associata titolo.<br />

Dal layer "rettangolo", copiamo il movieclip rettangolo, e <strong>in</strong>colliamolo nei due frame <strong>un</strong>iti del layer "pulsante".<br />

Selezioniamo il rettangolo, e premiamo F8. Nella f<strong>in</strong>estra di dialogo <strong>per</strong> convertire <strong>in</strong> simbolo, scegliamo button, e<br />

come nome diamo pulsante.<br />

Editiamo ora il pulsante, facendo doppio click su di esso: quello che vogliamo fare, è renderlo trasparente. La timel<strong>in</strong>e<br />

<strong>in</strong>terna del pulsante sarà come nella prima figura: noi clicchiamo sul primo frame, e trasc<strong>in</strong>iamo il contenuto nell'ultimo,<br />

come nella seconda figura.<br />

Â<br />

Adesso il pulsante non ha più niente nel frame Up, e qu<strong>in</strong>di non è visibile: tuttavia, ha il rettangolo nel frame Hit<br />

(rettangolo a cui togliamo il nome di istanza), qu<strong>in</strong>di è cliccabile. Usciamo dal pulsante e associamogli:<br />

on (press) {<br />

rettangolo.colore.setRGB( 0xFF9900 );<br />

_root.swap(_name);<br />

startDrag (this, false, _width/2, 0, 700-_width/2, 300-_height);<br />

if (!premuto) {<br />

if (getTimer()-click


stopDrag ();<br />

}<br />

Vediamo come f<strong>un</strong>ziona lo script: quando clicchiamo sul pulsante, questo richiama <strong>un</strong>a f<strong>un</strong>zione che sta nella root, e<br />

che si chiama swap. A questa f<strong>un</strong>zione, passa come parametro il nome di istanza del movieclip f<strong>in</strong>estra <strong>in</strong> cui è<br />

contenuto: questo servirà a far capire alla f<strong>un</strong>zione, da quale f<strong>in</strong>estra proviene la chiamata.<br />

Inoltre, f<strong>in</strong>tantoché il pulsante è cliccato, possiamo trasc<strong>in</strong>are il movieclip, entro dei limiti che sono quelli del filmato:<br />

non possiamo qu<strong>in</strong>di far uscire <strong>un</strong>a f<strong>in</strong>estra dall'area visibile.<br />

Un altro controllo, con il getTimer, viene effettuato <strong>per</strong> stabilire se l'ultimo click sia avvenuto meno di tre decimi di<br />

secondi prima: se la risposta è negativa, la f<strong>in</strong>estra non cambia aspetto, altrimenti, se a<strong>per</strong>ta si chiude, e se chiusa si apre.<br />

Questa è la simulazione di <strong>un</strong> doppio click, mentre l'a<strong>per</strong>tura e la chiusura della f<strong>in</strong>estra vengono effettuate mandando il<br />

movieclip avanti o <strong>in</strong>dietro di <strong>un</strong> frame.<br />

Inf<strong>in</strong>e, f<strong>in</strong>ché il pulsante è premuto, è di colore arancione; quando viene rilasciato, diventa giallo.<br />

// quando il mouse viene premuto<br />

on (press) {<br />

// setta colore <strong>in</strong> rettangolo come arancione<br />

rettangolo.colore.setRGB( 0xFF9900 );<br />

// chiama la f<strong>un</strong>zione "swap" passando come parametro il nome del<br />

// movieclip che contiene il pulsante<br />

_root.swap(_name);<br />

// trasc<strong>in</strong>a la f<strong>in</strong>estra entro i limiti del filmato<br />

startDrag (this, false, _width/2, 0, 700-_width/2, 300-_height);<br />

// se la variabile "premuto" è falsa<br />

if (!premuto) {<br />

// il click precedente è sato meno di tre decimi di secondo fa<br />

if (getTimer()-click


}<br />

// al rilascio<br />

on (release) {<br />

// setta colore <strong>in</strong> rettangolo come giallo<br />

rettangolo.colore.setRGB( 0xFFCC33 );<br />

// smetti di trasc<strong>in</strong>are il movieclip f<strong>in</strong>estra<br />

stopDrag ();<br />

}<br />

La f<strong>un</strong>zione che viene richiamata, e che sta nel primo frame del filmato, al livello della timel<strong>in</strong>e pr<strong>in</strong>cipale, è questa:<<br />

f<strong>un</strong>ction swap (nome) {<br />

if (alto != nome) {<br />

_root[nome].swapDepths(++num);<br />

_root[alto].rettangolo.colore.setRGB( 0x999999 );<br />

alto = nome;<br />

}<br />

}<br />

La f<strong>un</strong>zione riceve il nome del movieclip contenente il pulsante da cui arriva la chiamata: se questo nome è diverso da<br />

quello contenuto nella variabile alto, (e qu<strong>in</strong>di lo stesso pulsante non esegue questa azione due volte di seguito), allora<br />

mette il movieclip f<strong>in</strong>estra <strong>in</strong> cima alla lista dei livelli dei duplicati, mentre cambia <strong>in</strong> grigio il colore del rettangolo <strong>in</strong><br />

quello precedente.<br />

Piccola digressione: i duplicati di <strong>un</strong> movieclip, vengono posizionati <strong>in</strong> livelli assimilabili ai level dei filmati. Ogni<br />

duplicato deve stare <strong>in</strong> <strong>un</strong> livello diverso dagli altri: se <strong>un</strong> duplicato viene posizionato <strong>in</strong> <strong>un</strong> livello dove ne è già<br />

presente <strong>un</strong> altro, quest'ultimo lascia il posto al nuovo arrivato. Inoltre, come nei level, il livello con il valore più elevato<br />

copre quelli con il valore <strong>in</strong>feriore.<br />

La sequenza di numeri che rappresentano i livelli <strong>in</strong> cui sono posizionati i movieclip, determ<strong>in</strong>a l'ord<strong>in</strong>e di<br />

"impilamento", e il livello determ<strong>in</strong>a la profondità del movieclip. Con lo swapDepths(), alla base della f<strong>un</strong>zione, si<br />

possono scambiare due movieclip di livello: se lo eseguo su <strong>un</strong> movieclip sul livello 3, e su <strong>un</strong>o sul livello 10, il primo<br />

andrà al livello 10, e il secondo al livello 3. Non solo, è possibile anche assegnare ad <strong>un</strong> movieclip il livello su cui<br />

posizionarsi, senza dover prendere il posto di <strong>un</strong> altro.<br />

La variabile num, presente nella f<strong>un</strong>zione, contiene proprio il numero dei livelli <strong>in</strong>iziali: se all'a<strong>per</strong>tura del filmato ho<br />

stabilito di avere 3 f<strong>in</strong>estre, num sarà uguale a 3. Quando richiamo la f<strong>un</strong>zione swap dal movieclip presente nel livello<br />

1, il valore di num viene aumentato di <strong>un</strong>a <strong>un</strong>ità, e diventa 4: allora il movieclip da cui viene la chiamata, viene<br />

posizionato nel livello 4, sopra tutti gli altri (il più alto stava nel 3). La volta dopo, il movieclip chiamante verrà<br />

posizionato nel livello 5, poi <strong>in</strong> quello 6, e così via.<br />

Questo sistema presenta dei vantaggi e degli svantaggi. E' il più semplice <strong>in</strong> assoluto, ed è efficace, non presentando il<br />

bug proprio dello swap depth tra due movieclip (se ho tre movieclip, dal basso verso l'alto l'<strong>un</strong>o, il due, e il tre, e<br />

scambio di profondità il primo con il terzo, il primo andrà <strong>in</strong> cima, ma il terzo andrà <strong>in</strong> fondo: <strong>in</strong> W<strong>in</strong>dows non è così,<br />

poiché la f<strong>in</strong>estra cliccata va <strong>in</strong> cima, ma la sequenza di tutte quelle dietro resta <strong>in</strong>alterata).


Lo svantaggio, <strong>in</strong> via teorica, ci sarebbe con <strong>un</strong> gran numero di f<strong>in</strong>estre, o con <strong>un</strong> gran movimento delle stesse.<br />

Aumentando sempre di più il valore dell'impilamento massimo, si potrebbe gi<strong>un</strong>gere al limite del lettore. Magari dovrei<br />

cliccare 16.000 volte le f<strong>in</strong>estre, <strong>per</strong> arrivarci: improbabile ma possibile. D'altronde, <strong>per</strong> evitare questo problema, dovrei<br />

utilizzare <strong>un</strong> sistema che ad ogni cambio di profondità, sposti tutte le f<strong>in</strong>estre <strong>per</strong> compattarle nel m<strong>in</strong>or numero di<br />

livelli possibili, senza buchi, spostandole tutte verso il basso.<br />

Per i nostri scopi, decisamente eccessivo.<br />

Stage<br />

Andiamo alla timel<strong>in</strong>e pr<strong>in</strong>cipale: trasc<strong>in</strong>iamo sullo stage, dalla libreria, <strong>un</strong>'istanza del movieclip f<strong>in</strong>estra, e<br />

assegniamogli, come nome di istanza, mc. In <strong>un</strong> qualsiasi p<strong>un</strong>to dello stage, trasc<strong>in</strong>iamo <strong>un</strong> qualsiasi movieclip dalla<br />

libreria: lo rimpiccioliamo, e lo portiamo fuori dall'area visibile. A questo movieclip associamo:<br />

onClipEvent (load) {<br />

loadVariables ("f<strong>in</strong>estre.txt", this);<br />

_root.mc._visible = 0;<br />

}<br />

onClipEvent (data) {<br />

num = _root.num = Number(num);<br />

for (i = 1; i < num + 1; ++i) {<br />

nuovo = "f<strong>in</strong>estra"+i;<br />

duplicateMovieClip ("_root.mc", nuovo, i);<br />

with (_root[nuovo]) {<br />

rettangolo.colore = new Color(rettangolo);<br />

rettangolo.colore.setRGB(0x999999);<br />

titolo = this["titolo"+i];<br />

testo = this["testo"+i];<br />

_x = _root.mc._x+(100*i);<br />

_y = _root.mc._y+(20*i);<br />

}<br />

_root[nuovo].swapDepths(i);<br />

}<br />

_root["f<strong>in</strong>estra"+num].rettangolo.colore.setRGB(0xFFCC33);<br />

_root.alto = _root["f<strong>in</strong>estra"+num]._name;<br />

}<br />

Questo codice, f<strong>in</strong>almente, è quello che carica il file di testo esterno e crea le f<strong>in</strong>estre. Per posizionare le f<strong>in</strong>estre<br />

duplicate, ci sono mille modi: io ne ho scelto <strong>un</strong>o semplice <strong>per</strong> questioni di coerenza grafica, argomento che <strong>in</strong> altre<br />

situazioni può non essere il più opport<strong>un</strong>o.<br />

Il file di testo esterno che viene caricato, si chiama f<strong>in</strong>estre.txt. Durante la costruzione del movieclip f<strong>in</strong>estra, abbiamo<br />

visto come al suo <strong>in</strong>terno fossero presenti due campi di testo, titolo e testo. Queste saranno le variabili presenti, <strong>per</strong><br />

ogni f<strong>in</strong>estra. Il numero totale è scritto all'<strong>in</strong>izio.<br />

num=3&titolo1=SIMBOLI GRAFICI&testo1=Usare i simboli grafici....bla.....&titolo2=PULSANTI&testo2=Usare i<br />

simboli di pulsanti....bla..... &titolo3=CLIP FILMATO&testo3=Un clip filmato è <strong>un</strong> ....bla.....


Questo è il contenuto di f<strong>in</strong>estre.txt: la prima variabile rappresenta il numero di duplicati ( e anche il massimo livello di<br />

impilamento <strong>in</strong>iziale), le altre sono <strong>in</strong> sequenza i valori di titolo e testo <strong>per</strong> ogni movieclip.<br />

// al caricamento del movieclip (<strong>un</strong>a volta sola)<br />

onClipEvent (load) {<br />

// carica <strong>in</strong> questo movieclip il file di testo<br />

// esterno f<strong>in</strong>estre.txt<br />

loadVariables ("f<strong>in</strong>estre.txt", this);<br />

// nascondi il movieclip "mc"<br />

_root.mc._visible = 0;<br />

}<br />

// Quando i dati sono stati tutti caricati<br />

onClipEvent (data) {<br />

// setta il valore di num come il numero corrispondente<br />

// alla str<strong>in</strong>ga Num (le variabili dal testo esterno sono sempre str<strong>in</strong>ghe)<br />

num = _root.num = Number(num);<br />

// <strong>per</strong> tutti i valori di i che vanno da 1 a num<br />

for (i = 1; i < num + 1; ++i) {<br />

// assegna alla variabile "nuovo", il valore di "f<strong>in</strong>estra"+1<br />

nuovo = "f<strong>in</strong>estra"+i;<br />

// duplica il movieclip mc sullo stage, dopo averlo reso <strong>in</strong>visibile<br />

duplicateMovieClip ("_root.mc", nuovo, i);<br />

// del movieclip duplicato, settiamo i colori;<br />

// <strong>in</strong>seriamo nelle due caselle di testo il corrispondente <strong>per</strong> ogni<br />

// movieclip; ne settiamo la posizione a scalare partendo da quella di mc<br />

with (_root[nuovo]) {<br />

rettangolo.colore = new Color(rettangolo);<br />

rettangolo.colore.setRGB(0x999999);<br />

titolo = this["titolo"+i];<br />

testo = this["testo"+i];<br />

_x = _root.mc._x+(100*i);<br />

_y = _root.mc._y+(20*i);<br />

}<br />

// scambiamo ogni volta l'ord<strong>in</strong>e di impilamento, <strong>in</strong> modo che<br />

// l'ultimo duplicato sia <strong>in</strong> cima<br />

_root[nuovo].swapDepths(i);<br />

}<br />

// l'ultima f<strong>in</strong>estra duplicata sta <strong>in</strong> cima, e ha il colore giallo<br />

// <strong>in</strong>oltre, il nome del primo movieclip, è anche quello<br />

// che la f<strong>un</strong>zione considera come l'ultimo chiamato, all'avvio.<br />

_root["f<strong>in</strong>estra"+num].rettangolo.colore.setRGB(0xFFCC33);<br />

_root.alto = _root["f<strong>in</strong>estra"+num]._name;<br />

}


Brevemente:<br />

viene caricato il file di testo e duplicate le f<strong>in</strong>estre<br />

ogni f<strong>in</strong>estra viene riempita con i valori corrispondenti<br />

l'ultima f<strong>in</strong>estra è quella attiva<br />

Scroll di immag<strong>in</strong>i<br />

In questa nuova sezione tratteremo il secondo tipo di scroll di immag<strong>in</strong>i. Rispetto al primo, questo non avviene da solo,<br />

ma è soggetto alla pressione di due diversi pulsanti <strong>per</strong> l'avanzamento nell'<strong>un</strong>a o nell'altra direzione.<br />

Come previsto dalla f<strong>un</strong>zione del menu, questo filmato dovrà chiamarsi scroll.swf. Per cui creiamo <strong>un</strong> nuovo<br />

documento <strong>Flash</strong>, 700x300, 24fps di frame rate, e salviamo con il nome scroll.fla<br />

Creazione<br />

Importazione<br />

Come nel primo caso, importiamo nel nostro documento <strong>un</strong>a serie di immag<strong>in</strong>i già ottimizzate <strong>in</strong> editor esterni. Il<br />

numero di queste immag<strong>in</strong>i è <strong>in</strong>differente, l'importante è che siano più di <strong>un</strong>a: <strong>in</strong>oltre, non ci sono limitazioni <strong>in</strong><br />

relazione alle dimensioni, dal momento che non è presente alc<strong>un</strong> DuplicateMovieClip.<br />

Lo scopo di questo scroll sarà quello di collegare il visitatore, tramite la pressione di <strong>un</strong> tasto, ad alc<strong>un</strong>e pag<strong>in</strong>e web di<br />

grande utilità. Per questo motivo, le immag<strong>in</strong>i saranno le catture delle pag<strong>in</strong>e pr<strong>in</strong>cipali di questi siti, <strong>in</strong> dimensioni<br />

ridotte. Una volta importate, le immag<strong>in</strong>i verranno <strong>in</strong>serite <strong>un</strong>a ad <strong>un</strong>a <strong>in</strong> movieclip, sempre <strong>per</strong> evitare eventuali errori<br />

del plug<strong>in</strong>.<br />

Il pulsante trasparente<br />

Prima di procedere alla creazione del movieclip da far scorrere, creiamo <strong>un</strong> pulsante trasparente: sulla timel<strong>in</strong>e<br />

pr<strong>in</strong>cipale, disegniamo <strong>un</strong> rettangolo largo 30 pixel e alto 130. Lo selezioniamo, premiamo il tasto F8, e lo convertiamo<br />

<strong>in</strong> pulsante con il nome pulsante. Editiamo il pulsante, cliccandolo due volte, e trasc<strong>in</strong>iamo il contenuto dal frame "Up"<br />

nel frame "Hit".<br />

Torniamo alla timel<strong>in</strong>e pr<strong>in</strong>cipale, e cancelliamo il pulsante (che rimarrà nella libreria).<br />

I movieclip<br />

Spiegherò la procedura di creazione di <strong>un</strong>o solo dei movieclip, dal momento che sono tutti uguali tranne pochi<br />

particolari.<br />

Cliccando sul pulsante + <strong>in</strong> basso a s<strong>in</strong>istra nella libreria, aggi<strong>un</strong>giamo <strong>un</strong> movieclip che chiameremo clip001.<br />

All'<strong>in</strong>terno di questo movieclip, <strong>in</strong> <strong>un</strong> layer con nome "immag<strong>in</strong>e", trasc<strong>in</strong>iamo dalla libreria la prima delle immag<strong>in</strong>i<br />

importate, e la posizioniamo con l'angolo su<strong>per</strong>iore s<strong>in</strong>istro al centro del movieclip.<br />

Aggi<strong>un</strong>giamo <strong>un</strong> altro layer, che chiameremo "scritta", sotto quello "immag<strong>in</strong>e". In questo layer, alla distanza di 5 pixel


dalla destra dell'immag<strong>in</strong>e, disegniamo <strong>un</strong> rettangolo colorato, con colore diverso <strong>per</strong> ogni movieclip. Sopra questo<br />

rettangolo, posizioniamo, ruotata di 270 gradi, <strong>un</strong>a scritta con il nome del <strong>sito</strong>.<br />

Aggi<strong>un</strong>giamo <strong>un</strong> altro layer, nome "pulsante", nel quale trasc<strong>in</strong>iamo dalla libreria <strong>un</strong>'istanza di pulsante. Posizioniamo<br />

il pulsante sopra il rettangolo colorato, e gli associamo lo script:<br />

on (release) {<br />

_root.<strong>in</strong>dirizzo();<br />

}<br />

Con questo script, alla pressione sul pulsante, non faremo altro che richiamare la f<strong>un</strong>zione <strong>in</strong>dirizzo presente a livello<br />

della _root. Per dist<strong>in</strong>guere poi <strong>un</strong> pulsante dall'altro, ci serviremo di altri parametri.<br />

Tutti i movieclip avranno questa impostazione: le cose da cambiare sono le immag<strong>in</strong>i, il colore del rettangolo, e la<br />

scritta. I nomi dei movieclip non hanno importanza: <strong>per</strong> comodità, <strong>per</strong>ò, conviene chiamarli clip001, clip002, clip003,...,<br />

clip007 (il numero delle immag<strong>in</strong>i).<br />

Il moveclip "scorrimento"<br />

Aggi<strong>un</strong>giamo <strong>un</strong> movieclip nella libreria, e chiamiamolo scorrimento. All'<strong>in</strong>terno di questo, posizioniamo i 7<br />

movieclip contenenti le immag<strong>in</strong>i. I movieclip andranno posizionati <strong>un</strong>o accanto all'altro, a distanza di 5 pixel, partendo<br />

a s<strong>in</strong>istra con clip001: questo, il primo, avrà l'angolo su<strong>per</strong>iore s<strong>in</strong>istro al centro del movieclip pr<strong>in</strong>cipale.<br />

Pulsanti di scorrimento<br />

Nella timel<strong>in</strong>e pr<strong>in</strong>cipale, aggi<strong>un</strong>giamo <strong>un</strong> layer di nome "scritte", e scriviamo due campi di testo statici come <strong>in</strong> figura:<br />

Selezioniamo le scritte <strong>un</strong>a alla volta, e convertiamole <strong>in</strong> movieclip.<br />

Lo stage<br />

Andiamo alla timel<strong>in</strong>e pr<strong>in</strong>cipale. Abbiamo già <strong>un</strong> layer contenente i pulsanti di scorrimento: nello stesso layer,<br />

aggi<strong>un</strong>giamo due campi di testo d<strong>in</strong>amici, chiamati rispettivamente titolo e sottotitolo, entrambi a l<strong>in</strong>ea s<strong>in</strong>gola e con<br />

opzione "html".<br />

Aggi<strong>un</strong>giamo <strong>un</strong> layer maschera, sul quale disegniamo <strong>un</strong> rettangolo di misure 235x130: attraverso questa maschera,


vedremo scorrere le immag<strong>in</strong>i. Nel layer sotto, che setteremo come mascherato, trasc<strong>in</strong>iamo <strong>un</strong>'istanza del movieclip<br />

scorrimento, alla quale diamo scorrimento come nome di istanza, e associamo:<br />

onClipEvent (load) {<br />

f<strong>in</strong>e = _x;<br />

frame = 3;<br />

}<br />

onClipEvent (enterFrame) {<br />

<strong>in</strong>izio = _x;<br />

spostamento = (f<strong>in</strong>e-<strong>in</strong>izio)/frame;<br />

_x += spostamento;<br />

}<br />

Questo script, si basa sulla trasposizione della formula fisica del moto <strong>un</strong>iformemente decelerato. Senza spiegare troppo<br />

approfonditamente: abbiamo <strong>un</strong>a posizione <strong>in</strong>iziale <strong>per</strong> il movieclip. Assegniamo <strong>un</strong>a posizione f<strong>in</strong>ale, e dato <strong>un</strong><br />

numero di frame fissi, calcoliamo qual'è lo spostamento che deve effettuare il movieclip <strong>per</strong> ogni frame.<br />

Se il p<strong>un</strong>to <strong>in</strong>iziale è fisso, cioè non varia durante lo spostamento, l'effetto è questo:<br />

Se <strong>in</strong>vece il p<strong>un</strong>to di <strong>in</strong>izio varia con lo spostamento, e co<strong>in</strong>cide di volta <strong>in</strong> volta con la posizione attuale del movieclip,<br />

l'effetto sarà molto diverso:<br />

Esempio pratico: dobbiamo far fare al movieclip <strong>un</strong>o spostamento di 100 pixel <strong>in</strong> dieci frame. 100 diviso 10 è uguale a<br />

10: ad ogni frame, aggi<strong>un</strong>giamo alla posizione del movieclip, 10 pixel, e otteniamo il primo effetto. Questo <strong>per</strong>chè<br />

attraverso tutto il processo, la posizione <strong>in</strong>iziale rimane fissa.<br />

Se <strong>in</strong>vece, ad ogni frame, calcoliamo il tutto rispetto ad <strong>un</strong>a nuova posizione <strong>in</strong>iziale, al primo spostamento il passo sarà<br />

di dieci pixel, mentre al secondo sarà di 90/10, cioè 9: al terzo 80/10, cioè 8, e così via. In questo modo, man mano che<br />

avanza il movieclip, gli spostamenti saranno sempre più brevi, dando l'effetto di decelerazione.<br />

Abbiamo il nostro movieclip fermo <strong>in</strong> <strong>un</strong>a posizione. Tramite i pulsanti di scorrimento, daremo al movieclip <strong>un</strong>a nuova<br />

posizione f<strong>in</strong>ale, che questo raggi<strong>un</strong>gerà tramite la formula descritta:<br />

// al caricamento del movieclip<br />

onClipEvent (load) {<br />

// setta come posizione <strong>in</strong>iziale quella attuale<br />

f<strong>in</strong>e = _x;<br />

// setta la variabile "f<strong>in</strong>e" come 3<br />

frame = 3;<br />

}<br />

// ad ogni riproduzione del movieclip<br />

onClipEvent (enterFrame) {<br />

// considera come <strong>in</strong>izio la posizione attuale del movieclip<br />

<strong>in</strong>izio = _x;<br />

// valuta come "spostamento" il valore di f<strong>in</strong>e-<strong>in</strong>izio<br />

// fratto frame (valore sempre m<strong>in</strong>ore)<br />

spostamento = (f<strong>in</strong>e-<strong>in</strong>izio)/frame;<br />

// somma al valore della _x del movieclip, quello di spostamento


_x += spostamento;<br />

}<br />

Posizioniamo il movieclip <strong>in</strong> modo che il primo clip <strong>in</strong>terno sia sotto la maschera: questo sarà il p<strong>un</strong>to massimo <strong>in</strong> cui<br />

potrà arrivare scorrendo verso destra. Viceversa, posizionando il movieclip con l'ultimo clip sotto la maschera, potremo<br />

vedere il valore che dovrà assumere quando sarà spostato al massimo a s<strong>in</strong>istra.<br />

Al pulsante <strong>per</strong> scorrere verso destra assegneremo:<br />

onClipEvent (mouseDown) {<br />

if(this.hitTest(_root._xmouse,_root._ymouse,false)){<br />

_parent.scorrimento.f<strong>in</strong>e -= 240;<br />

}<br />

}<br />

e a quello <strong>per</strong> scorrere verso s<strong>in</strong>istra:<br />

onClipEvent (mouseDown) {<br />

if(this.hitTest(_root._xmouse,_root._ymouse,false)){<br />

_parent.scorrimento.f<strong>in</strong>e += 240;<br />

}<br />

}<br />

L'<strong>un</strong>ica differenza sta nel fatto che con <strong>un</strong> pulsante il valore della _x aumenta, con l'altro dim<strong>in</strong>uisce (240 è la larghezza<br />

di ciasc<strong>un</strong>o dei movieclip <strong>in</strong>terni: qu<strong>in</strong>di lo spostamento <strong>per</strong>ché <strong>un</strong> nuovo movieclip si possa trovare sotto la maschera<br />

ed essere visibile).<br />

Il problema, ora, è di fare <strong>in</strong> modo che scorrendo <strong>in</strong> <strong>un</strong> lato o nell'altro, non si arrivi al p<strong>un</strong>to <strong>in</strong> cui sotto la maschera<br />

non c'è più niente. Sapendo qu<strong>in</strong>di che gli spostamenti da fare sono 7 (quanti i movieclip <strong>in</strong>terni), settiamo nel primo<br />

frame della timel<strong>in</strong>e pr<strong>in</strong>cipale:<br />

i = 1;<br />

e aggi<strong>un</strong>giamo al codice dei due pulsanti:<br />

onClipEvent (mouseDown) {<br />

if(this.hitTest(_root._xmouse,_root._ymouse,false)){<br />

if (_parent.i < 7) {<br />

_parent.scorrimento.f<strong>in</strong>e += 240;<br />

_parent.i++;<br />

}<br />

}<br />

}<br />

onClipEvent (mouseDown) {<br />

if(this.hitTest(_root._xmouse,_root._ymouse,false)){<br />

if(_parent.i > 1) {<br />

_parent.scorrimento.f<strong>in</strong>e += 240;<br />

_parent.i--;


}<br />

}<br />

}<br />

Man mano, qu<strong>in</strong>di, che scorriamo il movieclip, tramite i pulsanti variamo anche il valore di i, aumentandolo o<br />

dim<strong>in</strong>uendolo a seconda della direzione. Se il valore di i è compreso tra 1 e 7, lo spostamento avverrà.<br />

Inf<strong>in</strong>e, al codice dei due pulsanti, assegniamo anche <strong>un</strong>'ultima riga:<br />

onClipEvent (mouseDown) {<br />

if(this.hitTest(_root._xmouse,_root._ymouse,false)){<br />

if(_parent.i > 1) {<br />

_parent.scorrimento.f<strong>in</strong>e += 240;<br />

_parent.i--;<br />

_parent.scritta();<br />

}<br />

}<br />

}<br />

con la quale, ogni volta che avviene <strong>un</strong>o spostamento, richiamiamo la f<strong>un</strong>zione scritta presente nella _root.<br />

Le due f<strong>un</strong>zioni<br />

Abbiamo visto i richiami a due f<strong>un</strong>zioni dist<strong>in</strong>te, <strong>in</strong>dirizzo e scritta. Vediamo entrambe, a partire dall'ultima citata, e<br />

richiamata dai pulsanti di scorrimento. Nel primo frame della timel<strong>in</strong>e, scriviamo:<br />

l<strong>in</strong>k = new Array(contenuto1);<br />

sottotitoli = new Array(contenuto2);<br />

f<strong>un</strong>ction scritta () {<br />

titolo = "" + l<strong>in</strong>k[i-1] + "";<br />

sottotitolo = sottotitoli[i-1];<br />

}<br />

Per ragioni di spazio non posso scrivere ciò che è al posto di contenuto1 e contenuto2, ma spiego cos'è. Nel primo caso,<br />

abbiamo <strong>un</strong>a lista di <strong>in</strong>dirizzi relativi ai siti di cui trattiamo, e le cui pag<strong>in</strong>e pr<strong>in</strong>cipali sono raffigurate nelle immag<strong>in</strong>i<br />

importate. La forma <strong>in</strong> cui sono scritti, è questa:<br />

"<strong>in</strong>dirizzo1", "<strong>in</strong>dirizzo2", "<strong>in</strong>dirizzo3", .... eccetera.<br />

Nell'altro array, <strong>in</strong>vece, sono contenuti dei sottotitoli descrittivi dei siti, sempre nella stessa forma:<br />

"sottotitolo1", "sottotitolo2", "sottotitolo3", .... eccetera.<br />

Quando si clicca su <strong>un</strong> pulsante, viene richiamata la f<strong>un</strong>zione. La f<strong>un</strong>zione valuta il valore di i, compreso tra 1 e 7 (e che<br />

qu<strong>in</strong>di ci da la posizione del movieclip scorrimento, <strong>in</strong>dicando quale clip <strong>in</strong>terno è sotto la maschera), ed estrapola dai<br />

due array i valori corrispondenti all'<strong>in</strong>dirizzo e al sottotitolo del <strong>sito</strong> visualizzato. Qu<strong>in</strong>di li scrive nei due campi di testo<br />

d<strong>in</strong>amici creati <strong>in</strong> precedenza. In quello "sottotitoli", si limita a mettere l'elemento i-1 dell'array sottotitoli (la<br />

numerazione dell'array parte con lo 0, e qu<strong>in</strong>di gli elementi vanno dallo 0 al 6): nel campo titoli, <strong>in</strong>vece, sfrutta<br />

l'opzione html creando <strong>un</strong> testo cliccabile.<br />

La str<strong>in</strong>ga creata, sarà del tipo: <strong>in</strong>dirizzo, solo che al posto di <strong>in</strong>dirizzo andrà


il valore dell'elemento i-1 dell'array l<strong>in</strong>k.<br />

La seconda f<strong>un</strong>zione è questa:<br />

f<strong>un</strong>ction <strong>in</strong>dirizzo () {<br />

getURL (l<strong>in</strong>k[i-1], "_blank");<br />

}<br />

Molto semplicemente, quando si preme <strong>un</strong>o dei pulsanti dei clip <strong>in</strong>terni, la f<strong>un</strong>zione controllo il valore corrispondente a<br />

i-1 dell'array l<strong>in</strong>k (<strong>un</strong> URL), e lo apre <strong>in</strong> <strong>un</strong>a nuova f<strong>in</strong>estra.<br />

Form mail<br />

Quello che faremo, <strong>in</strong> questa sezione, è costruire <strong>un</strong> modulo <strong>per</strong> l'<strong>in</strong>vio di <strong>un</strong>'email dal <strong>sito</strong>: questo modulo non fa uso di<br />

l<strong>in</strong>guaggi esterni, ma <strong>in</strong>via i dati al client di posta dell'utente, client che poi <strong>in</strong>vierà il messaggio.<br />

Questa soluzione prevede <strong>un</strong>a serie di svantaggi e di vantaggi, che elencherò alla f<strong>in</strong>e: ma rientra <strong>in</strong> quello che era lo<br />

scopo del <strong>sito</strong>, l'utlizzo (quasi) esclusivo del <strong>Flash</strong>.<br />

Creiamo <strong>un</strong> nuovo documento <strong>Flash</strong>, 700x300, 24 fps: andiamo al menu File/Open As Library, e apriamo come libreria<br />

il file flash5.fla. Da questo, trasc<strong>in</strong>iamo nella libreria del nuovo filmato, il movieclip base. Allo stesso modo, apriamo<br />

come libreria il filmato testo.fla, dal quale prendiamo il movieclip ombra. Salviamo qu<strong>in</strong>di con il nome contatti.fla<br />

Costruzione<br />

F<strong>un</strong>zionalità<br />

Il nostro semplice form sarà composto da 4 campi, tutti obbligatori: nome del visitatore, <strong>in</strong>dirizzo email, città di<br />

provenienza, corpo del messaggio. Inoltre, avremo due checkbox <strong>in</strong>dipendenti, che serviranno a determ<strong>in</strong>are due<br />

opzioni diverse nella risposta. Il riempimento corretto dei campi, sarà verificato da <strong>un</strong> controllo sui s<strong>in</strong>goli <strong>in</strong>serimenti.<br />

Struttura<br />

In <strong>Flash</strong>, tramite il pannello Text Options, si può assegnare ad <strong>un</strong> campo di testo, sfondo e contorni. Purtroppo questi<br />

non possono essere modificati, nel senso che ne esiste <strong>un</strong>'<strong>un</strong>ica versione: sfondo bianco e contorni neri.<br />

Se qu<strong>in</strong>di vogliamo dare sfondo e contorni differenti, dobbiamo <strong>in</strong>serire <strong>un</strong> campo di testo normale <strong>in</strong> <strong>un</strong> layer, e nel<br />

layer sotto, disegnare <strong>un</strong> rettangolo con i colori voluti. A questo scopo, noi utilizzeremo il movieclip base.<br />

Innanzitutto, apriamo il file contatti.fla, e creiamo i layer secondo lo schema della figura:<br />

Andiamo al layer "sfondi", e posizioniamo sullo stage 4 istanze del movieclip base, con dimensioni e posizioni<br />

differenti:


Andiamo ora al layer "ombre", e trasc<strong>in</strong>iamo sullo stage due istanze del movieclip ombra <strong>per</strong> ogni sfondo,<br />

posizionandole nei lati su<strong>per</strong>iore e s<strong>in</strong>istro:<br />

Nel layer "titoli" <strong>in</strong>seriamo, accanto a ciasc<strong>un</strong>o sfondo, il titolo del campo del form, e qu<strong>in</strong>di: "nome", "email", "città",<br />

"testo".<br />

Nel layer pulsanti, <strong>in</strong>seriamo due campi di testo statici, che selezioneremo <strong>un</strong>o alla volta, e convertiremo, tramite il tasto<br />

F8, <strong>in</strong> movieclip:<br />

Inf<strong>in</strong>e, sempre nello stesso layer, <strong>in</strong>seriremo accanto allo sfondo che conterrà il corpo del messaggio, due istanze dello<br />

stesso movieclip, contenente <strong>un</strong>a freccia.<br />

Alle due frecce <strong>per</strong> lo scorrimento, assegniamo <strong>un</strong>o script già visto:<br />

onClipEvent (load) {<br />

colore = new Color(this);<br />

}<br />

onClipEvent (mouseDown) {<br />

if (this.hitTest(_root._xmouse,_root._ymouse,false)) {<br />

colore.setRGB( 0xFFFFFF );<br />

premuto = true;<br />

}


}<br />

onClipEvent (mouseUp) {<br />

colore.setRGB( 0xFFCC33 );<br />

premuto = false;<br />

}<br />

onClipEvent (enterFrame) {<br />

if (premuto) {<br />

_parent.testo.scroll--;<br />

}<br />

}<br />

nel pulsante <strong>per</strong> scorrere verso l'alto, e<br />

onClipEvent (load) {<br />

colore = new Color(this);<br />

}<br />

onClipEvent (mouseDown) {<br />

if (this.hitTest(_root._xmouse,_root._ymouse,false)) {<br />

colore.setRGB( 0xFFFFFF );<br />

premuto = true;<br />

}<br />

}<br />

onClipEvent (mouseUp) {<br />

colore.setRGB( 0xFFCC33 );<br />

premuto = false;<br />

}<br />

onClipEvent (enterFrame) {<br />

if (premuto) {<br />

_parent.testo.scroll++;<br />

}<br />

}<br />

<strong>per</strong> scorrere verso il basso. Quella che viene modificata è la proprietà scroll del campo di testo di <strong>in</strong>put testo, che<br />

conterrà il corpo del messaggio <strong>in</strong>serito dal visitatore. I restanti comandi sono <strong>per</strong> cambiare il colore della freccia alla<br />

pressione del tasto s<strong>in</strong>istro del mouse (naturalmente, la pressione <strong>in</strong> assenza di testo, o di testo con <strong>un</strong> numero di righe<br />

<strong>in</strong>feriore a quelle visibili, non sortirà alc<strong>un</strong> effetto).<br />

Campi di testo<br />

Nel layer "caselle", <strong>in</strong>seriamo 4 campi di testi. Questi campi, dovranno essere sovrapposti agli sfondi del layer<br />

sottostante, e avere le stesse rispettive dimensioni. Vediamo le caratteristiche di ogni campo:<br />

Tutti e quattro i campi di testo hanno le stesse impostazioni <strong>in</strong> relazione ai caratteri. Come Font, scegliamo il _sans<br />

(ness<strong>un</strong> peso aggi<strong>un</strong>tivo <strong>per</strong>chè carattere dispositivo), come dimensioni 10, e come colore il nero.


Per quanto riguarda l'all<strong>in</strong>eamento, i quattro campi sono uguali: a s<strong>in</strong>istra.<br />

Nel pannello "Opzioni del Testo", scegliamo Input Text dal menu. I primi tre campi (nome, email, città), saranno<br />

impostati come l<strong>in</strong>ea s<strong>in</strong>gola, mentre il campo testo come Multil<strong>in</strong>ea. Nel campo variabile, a seconda dei casi,<br />

<strong>in</strong>seriremo le variabili già elencate. Nel campo Max Chars, il numero massimo di caratteri: <strong>per</strong> i primi tre, <strong>un</strong>a trent<strong>in</strong>a<br />

al massimo. Per il testo, anche <strong>un</strong> migliaio.<br />

Oltre a questi quattro campi, ne <strong>in</strong>seriamo <strong>un</strong> altro appena sotto i pulsanti <strong>per</strong> l'<strong>in</strong>vio. Questa volta si tratterà di <strong>un</strong><br />

campo di testo d<strong>in</strong>amico, e non di <strong>in</strong>put: la variabile associata sarà out.<br />

I checkbox<br />

Costruiamo adesso il movieclip che f<strong>un</strong>gerà da checkbox, e che useremo due volte all'<strong>in</strong>terno del form.<br />

Clicchiamo sul + <strong>in</strong> basso a s<strong>in</strong>istra nel pannello libreria, e aggi<strong>un</strong>giamo <strong>un</strong> movieclip che chiameremo checkbox<strong>in</strong>.<br />

All'<strong>in</strong>terno di questo movieclip, creiamo tre layer: il primo <strong>in</strong> alto lo chiameremo "tick", il secondo "testo", il terzo<br />

"casella". Nel layer "casella", trasc<strong>in</strong>iamo dalla libreria <strong>un</strong>'istanza del movieclip base, che ridimensioniamo a 10 pixel<br />

<strong>per</strong> 10, e che posizioniamo al centro dello stage. Nel layer "testo", <strong>in</strong>seriamo <strong>un</strong> campo di testo d<strong>in</strong>amico a s<strong>in</strong>gola l<strong>in</strong>ea:<br />

il colore del carattere è <strong>in</strong>differente, la variabile associata è _parent.scelta (cioè il nome di istanza del movieclip che<br />

conterrà checkbox<strong>in</strong>).<br />

Nel secondo frame del layer "tick" (il primo resterà vuoto), <strong>in</strong>seriamo <strong>un</strong>'istanza del movieclip tick, contenente il<br />

simbolo di sp<strong>un</strong>ta <strong>in</strong> grigio, e centrata sul movieclip base nel layer "casella". Nel terzo frame, <strong>un</strong>'altra istanza del<br />

movieclip tick, questa volta t<strong>in</strong>ta, tramite il pannello effetti, di nero. Quello che otterremo sarà questo:


Secondo frame del movieclip checkbox<strong>in</strong><br />

Terzo frame del movieclip checkbox<strong>in</strong><br />

Andiamo alla timel<strong>in</strong>e pr<strong>in</strong>cipale, e trasc<strong>in</strong>iamo <strong>un</strong>'istanza del movieclip checkbox<strong>in</strong> sullo stage. Le assegniamo come<br />

nome di istanza <strong>in</strong>terno, e associamo questo script:<br />

onClipEvent(load){<br />

_root[_parent._name+"1"] = _parent.scelta+": no"<br />

stop();<br />

}<br />

onClipEvent(mouseMove){<br />

if(this.hitTest(_root._xmouse,_root._ymouse,false)){<br />

sopra = true;<br />

}else{<br />

sopra = false;<br />

}<br />

}<br />

onClipEvent(mouseDown){<br />

if(sopra){<br />

premuto = true;<br />

this.gotoAndStop(2);<br />

}<br />

}<br />

onClipEvent(mouseUp){<br />

if(premuto){<br />

if(sopra){<br />

if (!a<strong>per</strong>to) {<br />

this.gotoAndStop (3);<br />

_root[_parent._name+"1"] = scelta + ": si";<br />

} else {<br />

this.gotoAndStop (1);<br />

_root[_parent._name+"1"] = scelta + ": no";<br />

}<br />

a<strong>per</strong>to = !a<strong>per</strong>to;<br />

}else{<br />

if (!a<strong>per</strong>to) {<br />

this.gotoAndStop (1);<br />

} else {<br />

this.gotoAndStop (3);<br />

}<br />

}


}<br />

premuto = false;<br />

}<br />

Selezioniamo il movieclip sullo stage, e premiamo F8: lo convertiamo <strong>in</strong> <strong>un</strong> altro movieclip, che chiameremo<br />

checkboxout.<br />

Trac<strong>in</strong>iamo sullo stage, dalla libreria, <strong>un</strong>'altra istanza di questo nuovo movieclip: alla prima, come nome di istanza,<br />

diamo messaggio, alla seconda, materiale.<br />

Alla prima associamo:<br />

onClipEvent (load) {<br />

scelta = "Messaggio di conferma";<br />

}<br />

alla seconda:<br />

onClipEvent (load) {<br />

scelta = "Invio del materiale";<br />

}<br />

Vediamo di fare <strong>un</strong> po' d'ord<strong>in</strong>e.<br />

Nei due movieclip che f<strong>un</strong>gono da checkbox, con quest'ultimo script, abbiamo settato la variabile scelta, diversa <strong>per</strong><br />

ogn<strong>un</strong>o.<br />

Con lo script associato al movieclip <strong>in</strong>terno, <strong>in</strong>vece, settiamo <strong>un</strong>a variabile sulla timel<strong>in</strong>e pr<strong>in</strong>cipale, che ci <strong>in</strong>dica se la<br />

scelta è <strong>per</strong> il si, o <strong>per</strong> il no (no di default). Vediamo i casi <strong>per</strong> <strong>un</strong>o dei due movieclip:<br />

// al caricamento del movieclip<br />

onClipEvent(load){<br />

// sulla root setta la variabile uguale al nome del<br />

// movieclip che contiene questo, più il numero 1, con<br />

// il valore di scelta , più ": no".<br />

// qu<strong>in</strong>di se il movieclip si chiama "messaggio", e<br />

// scelta è "messaggio di conferma", sulla root<br />

// troveremo: messaggio1 = "Messaggio di conferma: no"<br />

_root[_parent._name+"1"] = _parent.scelta+": no"<br />

stop();<br />

}<br />

// script già visto <strong>per</strong> stabilire se si è sopra il<br />

// movieclip con il p<strong>un</strong>tatore del mouse<br />

onClipEvent(mouseMove){<br />

if(this.hitTest(_root._xmouse,_root._ymouse,false)){<br />

sopra = true;<br />

}else{<br />

sopra = false;<br />

}


}<br />

// alla pressione sul movieclip, questo va al frame 2<br />

// di checkbox<strong>in</strong>, dove c'è il tick grigio<br />

onClipEvent(mouseDown){<br />

if(sopra){<br />

premuto = true;<br />

this.gotoAndStop(2);<br />

}<br />

}<br />

// al rilascio del pulsante s<strong>in</strong>istro del mouse<br />

onClipEvent(mouseUp){<br />

if(premuto){<br />

// se siamo ancora sul movieclip<br />

if(sopra){<br />

// se la casella era deticcata, la ticchiamo<br />

// andando al frame 3, dove c'è il tick nero<br />

if (!a<strong>per</strong>to) {<br />

this.gotoAndStop (3);<br />

// e settiamo: messaggio1="Messaggio di conferma: si"<br />

_root[_parent._name+"1"] = scelta + ": si";<br />

// altrimenti<br />

} else {<br />

// deticchiamo la casella andando al frame 1<br />

this.gotoAndStop (1);<br />

// e settiamo: messaggio1="Messaggio di conferma: no"<br />

_root[_parent._name+"1"] = scelta + ": no";<br />

}<br />

a<strong>per</strong>to = !a<strong>per</strong>to;<br />

// altrimenti (abbiamo rilasciato fuori dal moveiclip)<br />

}else{<br />

if (!a<strong>per</strong>to) {<br />

// se il pulsante era a<strong>per</strong>to, vai al frame 1<br />

this.gotoAndStop (1);<br />

// altrimenti vai al frame 2<br />

} else {<br />

this.gotoAndStop (3);<br />

}<br />

}<br />

}<br />

premuto = false;<br />

}<br />

Gran parte di questo script potrebbe sembrare, <strong>per</strong> così dire, <strong>in</strong>utile. A parte il codice <strong>per</strong> settare la variabile sulla root<br />

che ci dice se <strong>in</strong>viare o no il messaggio di conferma, tutto il resto serve a far assomigliare il checkbox a quello di


W<strong>in</strong>dows. Infatti, <strong>in</strong> quello di W<strong>in</strong>dows, il tick passa <strong>per</strong> <strong>un</strong> colore <strong>in</strong>termedio, prima di cambiare stato, e rimane di quel<br />

colore <strong>per</strong> tutta la durata della pressione. Inoltre, rilasciando fuori dal checkbox, questo ritorna allo stato precedente.<br />

Pulsante "riprist<strong>in</strong>a"<br />

Andiamo al layer dove è contenuto il movieclip con la scritta "riprist<strong>in</strong>a". Questo, <strong>un</strong>a volta premuto, dovrà resettare il<br />

contenuto di tutti i campi di testo. Gli associamo:<br />

onClipEvent (load) {<br />

colore = new Color(this);<br />

}<br />

onClipEvent(mouseMove){<br />

if(this.hitTest(_root._xmouse,_root._ymouse,false)) {<br />

colore.setRGB(0xFFCC33);<br />

sopra = true;<br />

}else{<br />

colore.setRGB(0xFFFFFF);<br />

sopra = false;<br />

}<br />

}<br />

onClipEvent (mouseDown) {<br />

if (sopra) {<br />

_parent.out = "";<br />

_parent.testo = "";<br />

_parent.nome = "";<br />

_parent.citta = "";<br />

_parent.mail = "";<br />

_parent.messaggio.<strong>in</strong>terno.a<strong>per</strong>to = false;<br />

_parent.materiale.<strong>in</strong>terno.a<strong>per</strong>to = false;<br />

_parent.messaggio.<strong>in</strong>terno.gotoAndStop(1);<br />

_parent.materiale.<strong>in</strong>terno.gotoAndStop(1);<br />

_parent.materiale1 = _parent.materiale.<strong>in</strong>terno.scelta + ": no";<br />

_parent.messaggio1 = _parent.messaggio.<strong>in</strong>terno.scelta + ": no";<br />

}<br />

}<br />

Quello che fa questo script, non è altro che svuotare i campi di testo presenti nella root. Per essere più precisi, con<br />

_parent.testo = ""; <strong>in</strong>seriamo nella casella testo, <strong>un</strong>a str<strong>in</strong>ga che non contiene alc<strong>un</strong> carattere.<br />

Inoltre, questo pulsante deve anche resettare i checkbox. Qu<strong>in</strong>di setta <strong>in</strong> entrambi la variabile a<strong>per</strong>to come falsa (serve a<br />

stabilire se siamo sul frame 1 o 3) , rimanda entrambi al frame 1 (dove non è presente il tick nella casella), e setta nella<br />

root entrambe le variabili d'opzione sul no.<br />

Pulsante "<strong>in</strong>via"<br />

Associamo al movieclip con la scritta "<strong>in</strong>via":


onClipEvent (load) {<br />

colore = new Color(this);<br />

}<br />

onClipEvent(mouseMove){<br />

if(this.hitTest(_root._xmouse,_root._ymouse,false)) {<br />

colore.setRGB(0xFFCC33);<br />

sopra = true;<br />

}else{<br />

colore.setRGB(0xFFFFFF);<br />

sopra = false;<br />

}<br />

}<br />

onClipEvent (mouseDown) {<br />

if (sopra) {<br />

_parent.convalida();<br />

}<br />

}<br />

Il contenuto importante dello script, è quello assoggettato al mouseDown. Se il p<strong>un</strong>tatore del mouse è sopra il movieclip,<br />

e viene premuto il tasto s<strong>in</strong>istro del mouse, allora viene richiamata la f<strong>un</strong>zione convalida, def<strong>in</strong>ita a livello della _root.<br />

La f<strong>un</strong>zione di convalida<br />

Il pulsante "<strong>in</strong>via", come abbiamo visto, richiama la f<strong>un</strong>zione convalida def<strong>in</strong>ita nella _root. Lo script <strong>per</strong> la convalida<br />

dei campi di <strong>in</strong>put, è <strong>un</strong> po' laborioso, ma necessario <strong>per</strong> evitare che si present<strong>in</strong>o problemi all'a<strong>per</strong>tura del client di<br />

posta. Ho graficamente diviso lo script <strong>in</strong> sezioni, <strong>per</strong> poter meglio dist<strong>in</strong>guere i vari passaggi: ogni volta che <strong>un</strong><br />

controllo viene su<strong>per</strong>ato, si passa al controllo successivo. Se <strong>in</strong>vece è presente <strong>un</strong> errore, questo viene scritto nel campo<br />

out.<br />

Per ragioni di spazio, non ho <strong>in</strong>cluso il contenuto degli array errori e caratteri. Nel primo sono elencati i possibili<br />

messaggi di errore, nel secondo, tutti i caratteri considerati <strong>in</strong>validi <strong>in</strong> <strong>un</strong> <strong>in</strong>dirizzo email.<br />

// prima parte<br />

email = "<strong>in</strong>dirizzo@host.it";<br />

dest<strong>in</strong>atario = "Staff del <strong>sito</strong>";<br />

soggetto = "Email da <strong>sito</strong>";<br />

spedisci = "mailto:" + dest<strong>in</strong>atario + "";<br />

f<strong>un</strong>ction convalida () {<br />

errori = new Array(contenuto1);<br />

err = 0;<br />

co<strong>un</strong>t = 0;<br />

errore = false;<br />

if (nome == "" || nome == <strong>un</strong>def<strong>in</strong>ed) {<br />

errore = true;<br />

err = 0;


}<br />

// seconda parte<br />

if (!errore) {<br />

caratteri = new Array(contenuto2);<br />

for (i=0; i=0) {<br />

errore = true;<br />

err = 1;<br />

}<br />

}<br />

}<br />

// terza parte<br />

if (!errore) {<br />

for (i=0; i


}<br />

// qu<strong>in</strong>ta parte<br />

if (!errore) {<br />

if (citta == "" || citta == <strong>un</strong>def<strong>in</strong>ed) {<br />

errore = true;<br />

err = 2;<br />

}<br />

}<br />

// sesta parte<br />

if (!errore) {<br />

if (testo == "" || testo == <strong>un</strong>def<strong>in</strong>ed) {<br />

errore = true;<br />

err = 3;<br />

}<br />

}<br />

// settima parte<br />

if (!errore) {<br />

getURL (spedisci+"?subject="+soggetto+"&body="+"Nome: "+nome+" E-mail:<br />

"+mail+" Città: "+citta+" "+messaggio1+" "+materiale1+" Testo: "+testo);<br />

out = "";<br />

} else {<br />

out = errori[err];<br />

k = err-1;<br />

}<br />

}<br />

Prima parte<br />

Nella prima parte, vengono def<strong>in</strong>ite la f<strong>un</strong>zione e alc<strong>un</strong>e variabili che serviranno nei vari controlli:<br />

• email: l'<strong>in</strong>dirizzo email a cui verrà <strong>in</strong>viato il messaggio<br />

• dest<strong>in</strong>atario: il nome che apparirà nel campo "dest<strong>in</strong>atario" del client di posta<br />

• soggetto: ciò che apparirà nel campo "soggetto" del client<br />

• spedisci: <strong>un</strong>a str<strong>in</strong>ga formata da "mailto:" più il dest<strong>in</strong>atario più l'email. In questo caso: "mailto:Staff del<br />

<strong>sito</strong>"<br />

• convalida: la f<strong>un</strong>zione, che non necessita del passaggio di parametri<br />

• errori: array contenente i possibili messaggi di errore<br />

• err: variabile che <strong>in</strong>dicherà eventualmente il numero identificativo dell'errore<br />

• co<strong>un</strong>t: <strong>un</strong> contatore, all'<strong>in</strong>izio settato sullo 0 (ogni volta che viene chiamata la f<strong>un</strong>zione, il contatore viene azzerato)<br />

• errore: booleano <strong>per</strong> stabilire se c'è <strong>un</strong> errore oppure no<br />

A questo p<strong>un</strong>to, avviene il primo controllo:<br />

if (nome == "" || nome == <strong>un</strong>def<strong>in</strong>ed) {<br />

errore = true;


err = 0;<br />

}<br />

Se il campo di testo associato al nome, è vuoto oppure non def<strong>in</strong>ito, la variabile errore viene settata su vero, e il<br />

messaggio di errore associato è lo 0 ("Scrivi il nome"). Qu<strong>in</strong>di, bisogna com<strong>un</strong>que scrivere qualcosa nel campo "nome".<br />

Seconda Parte<br />

if (!errore) {<br />

caratteri = new Array(contenuto2);<br />

for (i=0; i=0) {<br />

errore = true;<br />

err = 1;<br />

}<br />

}<br />

}<br />

Su<strong>per</strong>ato il primo controllo (if(!errore) significa se la variabile errore è ancora falsa), viene def<strong>in</strong>ito <strong>un</strong> array di caratteri<br />

che non possono essere contenuti <strong>in</strong> <strong>un</strong> <strong>in</strong>dirizzo email. Qu<strong>in</strong>di, <strong>per</strong> tutti i caratteri della l<strong>un</strong>ghezza dell'array (for (i=0;<br />

i


Quando il controllo è term<strong>in</strong>ato, se co<strong>un</strong>t non uguale a 1 (c'è <strong>un</strong>a chiocciola, ed è anche l'<strong>un</strong>ica), allora vuol dire che ce<br />

ne sono di più oppure che non ce n'è neanche <strong>un</strong>a: <strong>in</strong> ogni caso, errore diventa vera, e il messaggio di errore è lo stesso<br />

del precedente controllo.<br />

Quarta parte<br />

if (!errore) {<br />

dividi = mail.split("@");<br />

if (dividi[0].length


Qu<strong>in</strong>ta parte<br />

if (!errore) {<br />

if (citta == "" || citta == <strong>un</strong>def<strong>in</strong>ed) {<br />

errore = true;<br />

err = 2;<br />

}<br />

}<br />

Se non ci sono errori, viene verificato che nel campo "citta" (la città di provenienza), sia stato scritto qualcosa. Qu<strong>in</strong>di,<br />

se "citta" è vuota o <strong>in</strong>def<strong>in</strong>ita, c'è errore, e il messaggio <strong>in</strong> uscita sarà "Scrivi la tua città di provenienza".<br />

Sesta parte<br />

if (!errore) {<br />

if (testo == "" || testo == <strong>un</strong>def<strong>in</strong>ed) {<br />

errore = true;<br />

err = 3;<br />

}<br />

Come nel precedente, solo che viene verificato se è stato scritto qualcosa nel campo "testo". Il messaggio di errore, nel<br />

caso, è : "Scrivi il messaggio".<br />

Settima parte<br />

if (!errore) {<br />

getURL (spedisci+"?subject="+soggetto+"&body="+"Nome: "+nome+" E-mail:<br />

"+mail+" Città: "+citta+" "+messaggio1+" "+materiale1+" Testo: "+testo);<br />

out = "";<br />

} else {<br />

out = errori[err];<br />

k = err-1;<br />

}<br />

}<br />

Term<strong>in</strong>ati i controlli, se non c'è alc<strong>un</strong> errore, i dati vengono <strong>in</strong>viati al client di posta: l'argomento del getURL, è <strong>un</strong><br />

espressione somma di tutti i dati che vengono raccolti, e ord<strong>in</strong>ati <strong>in</strong> <strong>un</strong>a <strong>un</strong>ica str<strong>in</strong>ga. Per capire cosa significa,<br />

valutiamo <strong>un</strong> semplice caso, supponendo di avere questa situazione:<br />

nome = "Pippo"<br />

mail = "pippo@topol<strong>in</strong>ia.wd"<br />

citta = "topol<strong>in</strong>ia"<br />

testo = "complimenti!"<br />

e ticcato solo il primo dei checkbox. L'argomento del getURL sarà:<br />

mailto:Staff del <strong>sito</strong>?subject=Email da <strong>sito</strong>&body=Nome: pippo Email: pippo@topol<strong>in</strong>ia.wd Città:<br />

topol<strong>in</strong>ia Messaggio di conferma: sì Invio del materiale: no Testo: complimenti!


Se <strong>in</strong>vece c'è <strong>un</strong> errore, viene visualizzato, nel campo di testo d<strong>in</strong>amico out, il messaggio corrispondente all'errore, sulla<br />

base dell'array def<strong>in</strong>ito all'<strong>in</strong>izio.<br />

Il TAB<br />

Quando nel browser si ha <strong>un</strong> form <strong>in</strong> html, premendo il tasto TAB ci si sposta da <strong>un</strong> campo all'altro. La stessa cosa<br />

succede <strong>in</strong> <strong>Flash</strong>, solo che ci sono due problemi: <strong>in</strong>nanzitutto, il focus del documento deve essere sul filmato. Poi, il<br />

player segue <strong>un</strong> proprio ord<strong>in</strong>e, nello stabilire su quale campo focalizzare: ord<strong>in</strong>e che non sempre rispetta il <strong>per</strong>corso<br />

che vorremmo noi.<br />

How is the tab order for form fields <strong>in</strong> the <strong>Flash</strong> player determ<strong>in</strong>ed?<br />

Il primo problema è già risolto <strong>in</strong> partenza, dal momento che <strong>per</strong> accedere al form dobbiamo ciccare su <strong>un</strong> pulsante nel<br />

filmato: <strong>un</strong>a volta cliccato sul filmato, questo ha il focus.<br />

Per il secondo problema, <strong>in</strong>vece, dobbiamo <strong>creare</strong> <strong>un</strong> <strong>per</strong>corso tra i campi, e fare <strong>in</strong> modo che il TAB segua questo<br />

<strong>per</strong>corso: utilizzeremo qu<strong>in</strong>di il metodo setFocus, che ci <strong>per</strong>mette di spostare il cursore sul campo voluto.<br />

Array<br />

Andiamo alla timel<strong>in</strong>e pr<strong>in</strong>cipale, e nel primo frame, assieme alla f<strong>un</strong>zione convalida, scriviamo:<br />

campi = new Array("nome","mail","citta","testo");<br />

k = 0;<br />

Selection.setFocus(campi[k]);<br />

In questo modo abbiamo creato <strong>un</strong> array contenente le variabili associate ai campi di testo, nell'ord<strong>in</strong>e <strong>in</strong> cui vogliamo<br />

che vengano selezionati. Inoltre, abbiamo settato la variabile k uguale a 0, e focalizzato il campo a cui è associata la<br />

variabile <strong>in</strong>dicata nella posizione 0 dell'array campi.<br />

Il pulsante nascosto<br />

Nel layer "pulsanti", fuori dall'area visibile dello stage, creiamo <strong>un</strong> pulsante, il più leggero possibile e senza effetti:<br />

<strong>in</strong>fatti rimarrà nascosto, e servirà solo come appoggio <strong>per</strong> lo script. Gli associamo:<br />

on (keyPress "") {<br />

convalida();<br />

}<br />

on (keyPress "") {<br />

if (Key.isDown(Key.TAB) && !Key.isDown(Key.SHIFT)) {<br />

if (k == campi.length-1) {<br />

k = 0;<br />

} else {<br />

k++;<br />

}<br />

}<br />

if (Key.isDown(Key.TAB) && Key.isDown(Key.SHIFT)) {<br />

if (k == 0) {<br />

k = campi.length-1;


} else {<br />

k--;<br />

}<br />

}<br />

Selection.setFocus(campi[k]);<br />

}<br />

Le prime tre righe servono semplicemente a richiamare la f<strong>un</strong>zione convalida quando viene premuto il tasto Invio. Le<br />

altre <strong>in</strong>vece servono <strong>per</strong> il controllo del TAB.<br />

Innanzitutto stabiliamo se stiamo premendo il tasto TAB e basta, o anche lo SHIFT: questo ci serve <strong>per</strong> decidere <strong>in</strong><br />

quale direzione scorrere i campi.<br />

Nel primo caso, valutiamo se k è uguale al valore della l<strong>un</strong>ghezza dell'array campi meno 1 (e qu<strong>in</strong>di se il focus è sul<br />

campo "testo"), nel qual caso diamo a k il valore di 0. Se così non è, aumentiamo il valore di k di <strong>un</strong>a <strong>un</strong>ità.<br />

Nel caso vengano premuti TAB e SHIFT assieme, se k è uguale a 0 (siamo sul primo campo), assegniamo a k il valore<br />

della l<strong>un</strong>ghezza dell'array campi meno 1, altrimenti ne dim<strong>in</strong>uiamo il valore di <strong>un</strong>a <strong>un</strong>ità.<br />

A questo p<strong>un</strong>to, semplicemente settiamo il focus sul campo di testo corrispondente alla posizione k dell'array campi.<br />

Vantaggi e svantaggi<br />

I vantaggi di questo tipo di form mail sono presto detti:<br />

• non c'è bisogno che lo spazio web supporti qualche l<strong>in</strong>guaggio particolare<br />

• è molto facile da configurare<br />

Gli svantaggi:<br />

• non si può mandare a capo nell'<strong>in</strong>serimento dei dati nel client, se non <strong>in</strong> locale<br />

• scrivendo nel corpo del messaggio, gli a capo non vengono mantenuti<br />

• se manca <strong>un</strong> client di posta (tutti i p<strong>un</strong>ti <strong>in</strong>ternet pubblici), il form non serve a nulla<br />

Il pannello di controllo<br />

Introduzione<br />

A questo p<strong>un</strong>to, abbiamo term<strong>in</strong>ato la costruzione della pag<strong>in</strong>a pr<strong>in</strong>cipale del <strong>sito</strong> e delle sezioni esterne. Quello che<br />

manca è <strong>un</strong> ultimo filmato, da caricare con il loadMovieNum: conterrà il suono di sottofondo, e alc<strong>un</strong>i pannelli <strong>per</strong><br />

controllare le opzioni del <strong>sito</strong>.<br />

Da questo filmato, <strong>in</strong>fatti, potremo settare il <strong>sito</strong> come pag<strong>in</strong>a pr<strong>in</strong>cipale del browser, o aggi<strong>un</strong>gerlo ai preferiti; potremo<br />

cambiare il cursore del mouse, e modificare parte della grafica; potremo leggere l'ora e la data, e controllare i settaggi<br />

pr<strong>in</strong>cipali del suono; utilizzare i tooltip, e chiudere il <strong>sito</strong> stesso.<br />

Apriamo <strong>un</strong> nuovo documento <strong>Flash</strong>, 700x300, 24 fps di frame rate: importiamo dal file flash5.fla il movieclip base, e<br />

salviamo con il nome suono.fla<br />

La grafica<br />

Apriamo il documento suono.fla, e creiamo i layer secondo questo schema:


Nel layer "loghi", <strong>in</strong> alto, <strong>in</strong>seriamo la scritta <strong>Flash</strong>5.it e il logo del <strong>sito</strong>, presenti <strong>in</strong> libreria (non spiego la costruzione):<br />

nel layer "geometrie" <strong>in</strong>seriamo la grafica di sfondo, e nel layer "ombra", lo stesso movieclip, modificato <strong>in</strong> alpha e t<strong>in</strong>ta<br />

tramite il pannello Effect.<br />

Nel layer pulsanti, <strong>in</strong>seriamo due scritte: "chiudi" e "aiuto", che convertiremo s<strong>in</strong>golarmente <strong>in</strong> movieclip. Al pulsante<br />

chiudi, associamo:<br />

onClipEvent(load){<br />

colore = new Color(this);<br />

colore.setRGB(0xCCCCCC);<br />

}<br />

onClipEvent(mouseMove){<br />

if(this.hitTest(_root._xmouse,_root._ymouse,false)){<br />

if(!premuto){<br />

sopra = true;<br />

colore.setRGB( 0x000000 );<br />

}<br />

}else{<br />

sopra = false;<br />

if(!premuto){<br />

colore.setRGB( 0xCCCCCC );<br />

}<br />

}<br />

updateAfterEvent();<br />

}<br />

onClipEvent(mouseDown){<br />

if(this.hitTest(_root._xmouse,_root._ymouse,false)){<br />

premuto = true;<br />

colore.setRGB( 0xFFCC00 );<br />

}


updateAfterEvent();<br />

}<br />

onClipEvent(mouseUp){<br />

premuto = false;<br />

if(sopra){<br />

colore.setRGB( 0xFFFFFF );<br />

getURL("javascript:w<strong>in</strong>dow.parent.close()");<br />

}else{<br />

colore.setRGB( 0xCCCCCC );<br />

}<br />

updateAfterEvent();<br />

}<br />

Tutta la prima parte dello script serve a determ<strong>in</strong>are il cambio di colore della scritta <strong>in</strong> base alla posizione del mouse:<br />

sottoposto al mouseUp, <strong>in</strong>vece, quando avviene sul movieclip (corrispondente dell'on(release) dei pulsanti), abbiamo<br />

l'azione che chiuderà la pag<strong>in</strong>a contenente il filmato.<br />

// al caricamento del movieclip, crea <strong>un</strong>'istanza<br />

// dell'oggetto Color, associata al movieclip stesso<br />

// e assegna come colore il grigio<br />

onClipEvent(load){<br />

colore = new Color(this);<br />

colore.setRGB(0xCCCCCC);<br />

}<br />

// al movimento del mouse, se il p<strong>un</strong>tatore tocca il<br />

// movieclip<br />

onClipEvent(mouseMove){<br />

if(this.hitTest(_root._xmouse,_root._ymouse,false)){<br />

// se non stiamo cliccando, setta il colore sul nero<br />

// e la variabile sopra come vera<br />

if(!premuto){<br />

sopra = true;<br />

colore.setRGB( 0x000000 );<br />

}<br />

// altrimenti, se il p<strong>un</strong>tatore non è sul movieclip<br />

// se non abbiamo premuto, riprist<strong>in</strong>a il colore<br />

}else{<br />

sopra = false;<br />

if(!premuto){<br />

colore.setRGB( 0xCCCCCC );<br />

}<br />

}<br />

// aggiorna dopo ogni spostamento del mouse<br />

updateAfterEvent();


}<br />

// al click sul movieclip, setta il colore come<br />

// arancione, e la variabile "premuto" come vera<br />

onClipEvent(mouseDown){<br />

if(this.hitTest(_root._xmouse,_root._ymouse,false)){<br />

premuto = true;<br />

colore.setRGB( 0xFFCC00 );<br />

}<br />

updateAfterEvent();<br />

}<br />

// al rilascio del tasto s<strong>in</strong>istro del mouse<br />

onClipEvent(mouseUp){<br />

premuto = false;<br />

// se siamo sul movieclip<br />

if(sopra){<br />

// settiamo il colore sul bianco<br />

colore.setRGB( 0xFFFFFF );<br />

// richiamiamo il javascript che chiude la f<strong>in</strong>estra<br />

getURL("javascript:w<strong>in</strong>dow.parent.close()");<br />

}else{<br />

colore.setRGB( 0xCCCCCC );<br />

}<br />

updateAfterEvent();<br />

}<br />

Nel layer "quadrat<strong>in</strong>i", <strong>in</strong>seriremo <strong>in</strong>vece tre istanze del movieclip base, di dimensioni 5x5, <strong>in</strong> alto al centro dello stage,<br />

e le chiameremo rispettivamente quad1, quad2, quad3.<br />

Andiamo al menu File/Import, e importiamo <strong>un</strong>a gif preparata <strong>in</strong> precedenza, che rappresenta il p<strong>un</strong>tatore del mouse<br />

modificato, con il colore di fondo trasparente. Posizioniamo la gif nel layer "p<strong>un</strong>tatore", e tramite il pulsante F8, la<br />

convertiamo nel movieclip p<strong>un</strong>tatore. Diamo p<strong>un</strong>tatore come nome di istanza, e associamo questo script:<br />

// al caricamento del movieclip<br />

onClipEvent(load){<br />

// rendi il movieclip <strong>in</strong>visibile<br />

_visible = false;<br />

}<br />

// ad ogni movimento del mouse<br />

onClipEvent (mouseMove) {<br />

// se la variabile "vai" è vera<br />

if(vai){<br />

// assegna al movieclip le coord<strong>in</strong>ate<br />

// del p<strong>un</strong>tatore del mouse<br />

_x = _root._xmouse;<br />

_y = _root._ymouse;


}<br />

// forza <strong>un</strong> refresh del filmato<br />

updateAfterEvent();<br />

}<br />

Molto semplicemente, questo script determ<strong>in</strong>a il trasc<strong>in</strong>amento del p<strong>un</strong>tatore modificato, quando la variabile "vai" è<br />

vera: più avanti vedremo quando lo sarà.<br />

Importiamo nella libreria il suono "In the fly". Pulsante destro sul suono nella libreria, e scegliamo "L<strong>in</strong>kage".<br />

Nel pannello che si apre, scegliamo "Export this Symbol", nel campo <strong>in</strong> alto scriviamo "loop", e premiamo OK.<br />

Andiamo ora al primo frame della timel<strong>in</strong>e pr<strong>in</strong>cipale, nel layer "azioni", e scriviamo:<br />

fscommand ("allowscale", "false");<br />

stop();<br />

suono = new So<strong>un</strong>d(_root);<br />

suono.attachSo<strong>un</strong>d("loop");<br />

suono.start(0,999);<br />

riproduzione = true;<br />

In questo modo, stiamo utilizzando l'oggetto So<strong>un</strong>d <strong>per</strong> def<strong>in</strong>ire <strong>un</strong>'istanza di suono contenente il nostro loop.<br />

// non scalare il filmato<br />

fscommand ("allowscale", "false");<br />

// ferma la riproduzione su questo frame<br />

stop();<br />

// crea <strong>un</strong>a istanza dell'oggetto So<strong>un</strong>d, nome di<br />

// istanza "suono", associata alla _root


suono = new So<strong>un</strong>d(_root);<br />

// a questa istanza attacca il suono l<strong>in</strong>kato come "loop"<br />

suono.attachSo<strong>un</strong>d("loop");<br />

// <strong>in</strong>izia la riproduzione di "suono", <strong>per</strong> 999 volte<br />

suono.start(0,999);<br />

// setta la variabile riproduzione come vera<br />

riproduzione = true;<br />

Questo è quello che otteniamo.<br />

Il pannello di controllo<br />

Tooltip<br />

I tooltip sono quelle scritte che appaiono, nei nostri sistemi o<strong>per</strong>ativi, vic<strong>in</strong>o al p<strong>un</strong>tatore del mouse, quando ci<br />

soffermiamo <strong>per</strong> qualche secondo su <strong>un</strong> pulsante, o <strong>un</strong> menu. Generalmente f<strong>un</strong>zionano a tempo, e le scritte sono<br />

piuttosto corte.<br />

Noi <strong>in</strong>vece vogliamo <strong>creare</strong> dei tooltip che offrano <strong>un</strong> aiuto nella comprensione delle utilità presenti nel filmato: qu<strong>in</strong>di,<br />

se necessario, anche <strong>un</strong> po' dil<strong>un</strong>gandoci. Per questo motivo creeremo <strong>un</strong>a modalità di aiuto nella quale, <strong>un</strong>a volta<br />

attivata, i suggerimenti appariranno immediatamente, e rimarranno visibili f<strong>in</strong>che non saremo usciti dall'area sensibile.<br />

Disegno<br />

Aggi<strong>un</strong>giamo <strong>un</strong> movieclip, che chiameremo barraTooltip, alla nostra libreria, tramite il pulsante + <strong>in</strong> basso a s<strong>in</strong>istra<br />

nel pannello. In questo movieclip, disegniamo <strong>un</strong> rettangol<strong>in</strong>o di 60 pixel <strong>in</strong> larghezza e 10 <strong>in</strong> altezza, con l'angolo<br />

<strong>in</strong>feriore-destro sul centro del movieclip.<br />

Aggi<strong>un</strong>giamo alla libreria <strong>un</strong>'altro movieclip, che chiameremo tooltip. All'<strong>in</strong>terno di questo movieclip, <strong>in</strong> <strong>un</strong> layer<br />

chiamato "barra", posizioneremo <strong>un</strong>'istanza del movieclip barraTooltip, con l'angolo <strong>in</strong>feriore-destro nel p<strong>un</strong>to di<br />

registrazione: alla barra daremo come nome di istanza barra. In <strong>un</strong> layer sopra, chiamato "scritta", posizioneremo <strong>un</strong><br />

campo di testo d<strong>in</strong>amico, con associata la variabile testo.<br />

Particolare importante nella scelta del carattere: la barra sottostante la casella, dovrà essere ridimensionata <strong>in</strong> base alla<br />

l<strong>un</strong>ghezza della str<strong>in</strong>ga <strong>in</strong> essa contenuta. L'<strong>un</strong>ico modo <strong>per</strong> determ<strong>in</strong>are la l<strong>un</strong>ghezza della str<strong>in</strong>ga, è moltiplicare il<br />

numero di caratteri che la compongono <strong>per</strong> <strong>un</strong>a costante. La costante, naturalmente, è la larghezza di <strong>un</strong>a s<strong>in</strong>gola lettera.<br />

Com'è facilmente deducibile, la Font migliore <strong>per</strong> questo scopo è quella che ha tutte le lettere larghe uguali. Anche se<br />

questa Font non esiste (ci sarà sempre la lettera " i " a essere più stretta delle altre), la migliore approssimazione, anche<br />

considerando le ridotte dimensioni, l'ho trovata nella hooge 05_55. Le maiuscole di questa Font, <strong>in</strong>fatti, sono tutte<br />

larghe uguali. Inoltre, visto che questa è <strong>un</strong>a pixel Font, possiamo <strong>in</strong>corporare tutti i caratteri, posizionando la casella<br />

secondo le l<strong>in</strong>ee guide <strong>in</strong>dicate nell'appo<strong>sito</strong> articolo.<br />

Codice del tooltip


Andiamo adesso alla timel<strong>in</strong>e pr<strong>in</strong>cipale, nel layer "tooltip", e trasc<strong>in</strong>iamo dalla libreria allo stage <strong>un</strong>'istanza del<br />

movieclip tooltip, al quale daremo, come nome di istanza, tooltip. Gli associamo:<br />

onClipEvent (load) {<br />

barra._visible = 0;<br />

testo = "";<br />

f<strong>un</strong>ction scrivi(tip){<br />

testo = tip.toUp<strong>per</strong>Case();<br />

if(tip != ""){<br />

barra._visible = 1;<br />

barra._width = (testo.length*4.7);<br />

}else{<br />

barra._visible = 0<br />

}<br />

}<br />

}<br />

onClipEvent (mouseMove) {<br />

_x = _root._xmouse;<br />

_y = _root._ymouse;<br />

updateAfterEvent();<br />

}<br />

Lo script è molto semplice: al caricamento del movieclip, la visibilità della barra è settata su 0, e il contenuto del<br />

campo di testo "testo" è <strong>un</strong>a str<strong>in</strong>ga vuota (qu<strong>in</strong>di non si vede niente). Quando viene richiamata la f<strong>un</strong>zione scrivi, alla<br />

quale viene passato come parametro <strong>un</strong>a str<strong>in</strong>ga, se la str<strong>in</strong>ga contiene qualcosa, nel campo di testo viene scritto il<br />

contenuto <strong>in</strong> lettere maiuscole, e la l<strong>un</strong>ghezza della barra, ora visibile, viene settata moltiplicando il numero di lettere<br />

della str<strong>in</strong>ga <strong>per</strong> 4.7 (la larghezza di ogni carattere con quella Font). Se la str<strong>in</strong>ga è vuota, <strong>in</strong>vece, la barra torna<br />

<strong>in</strong>visibile.<br />

Ultimo accorgimento, ad ogni movimento del mouse, il movieclip segue il p<strong>un</strong>tatore.<br />

// al caricamento del movieclip<br />

onClipEvent (load) {<br />

// rendi la barra <strong>in</strong>visibile<br />

barra._visible = 0;<br />

// svuota il campo di testo<br />

testo = "";<br />

// dichiara la f<strong>un</strong>zione "scrivi" che riceve<br />

// come parametro la str<strong>in</strong>ga "tip"<br />

f<strong>un</strong>ction scrivi(tip){<br />

// riempi il campo "testo" con la str<strong>in</strong>ga<br />

// tutta <strong>in</strong> maiuscolo<br />

testo = tip.toUp<strong>per</strong>Case();<br />

// se la str<strong>in</strong>ga non è vuota<br />

if(tip != ""){<br />

// rendi la barra visibile


arra._visible = 1;<br />

// dai alla barra, come larghezza, il numero<br />

// delle lettere di "testo" <strong>per</strong> 4.7<br />

barra._width = (testo.length*4.7);<br />

// altrimenti (la str<strong>in</strong>ga è vuota)<br />

}else{<br />

// rendi la barra <strong>in</strong>visibile<br />

barra._visible = 0<br />

}<br />

}<br />

}<br />

// ad ogni movimento del mouse<br />

onClipEvent (mouseMove) {<br />

// dai al movieclip le coord<strong>in</strong>ate del<br />

// p<strong>un</strong>tatore del mouse<br />

_x = _root._xmouse;<br />

_y = _root._ymouse;<br />

// forza <strong>un</strong> refresh dopo ogni spostamento<br />

updateAfterEvent();<br />

}<br />

Codice del pulsante<br />

Nel layer "pulsanti" della timel<strong>in</strong>e pr<strong>in</strong>cipale di suono.fla, avevamo lasciato <strong>un</strong> movieclip contenente la scritta "aiuto".<br />

A questo movieclip associamo:<br />

onClipEvent (load) {<br />

_root.aiuto = false;<br />

colore = new Color(this);<br />

colore.setRGB( 0xCCCCCC);<br />

}<br />

onClipEvent (mouseDown) {<br />

if (sopra) {<br />

_root.aiuto = !_root.aiuto;<br />

brilla = !brilla;<br />

_alpha = 100;<br />

}<br />

}<br />

onClipEvent (mouseMove) {<br />

if (this.hitTest(_root._xmouse,_root._ymouse,false)) {<br />

sopra = true;<br />

colore.setRGB( 0x000000 )<br />

} else {<br />

if(!_root.aiuto){<br />

colore.setRGB( 0xCCCCCC);


}<br />

sopra = false;<br />

}<br />

}<br />

onClipEvent(enterFrame){<br />

if(brilla){<br />

if(_alpha == 100){<br />

_alpha = 50;<br />

}else{<br />

_alpha = 100;<br />

}<br />

}<br />

}<br />

Al caricamento del movieclip, che f<strong>un</strong>gerà da pulsante, la variabile aiuto contenuta nella _root verrà settata come falsa.<br />

Cliccando sul pulsante, la variabile cambierà stato, diventando alternativamente vera o falsa: questo <strong>per</strong>chè solo quando<br />

la variabile sarà vera, si avrà la modalità di aiuto, e i tooltip saranno visibili. Il resto dello script serve a far lampeggiare<br />

la scritta durante la modalità di aiuto.<br />

// al caricamento del movieclip<br />

onClipEvent (load) {<br />

// setta "aiuto" sulla root come falsa<br />

_root.aiuto = false;<br />

// crea <strong>un</strong>'istanza dell'oggetto Color associata al<br />

// movieclip, e t<strong>in</strong>gila di grigio<br />

colore = new Color(this);<br />

colore.setRGB( 0xCCCCCC);<br />

}<br />

// cliccando col tasto s<strong>in</strong>istro del mouse<br />

onClipEvent (mouseDown) {<br />

// se il p<strong>un</strong>tatore del mouse è sul movieclip<br />

if (sopra) {<br />

// cambia lo stato di "aiuto" e di "brilla" da vero a<br />

// falso, alternativamente, e setta l'alpha = 100<br />

_root.aiuto = !_root.aiuto;<br />

brilla = !brilla;<br />

_alpha = 100;<br />

}<br />

}<br />

// al movimento del mouse<br />

onClipEvent (mouseMove) {<br />

// se il p<strong>un</strong>tatore tocca il movieclip<br />

if (this.hitTest(_root._xmouse,_root._ymouse,false)) {<br />

// setta la variabile "sopra" come vera


sopra = true;<br />

// colora il movieclip di nero<br />

colore.setRGB( 0x000000 )<br />

// altrimenti<br />

} else {<br />

// se aiuto sulla root è falsa<br />

if(!_root.aiuto){<br />

// colora il movieclip di grigio<br />

colore.setRGB( 0xCCCCCC);<br />

}<br />

// setta "sopra" come falsa<br />

sopra = false;<br />

}<br />

}<br />

// ad ogni riproduzione del movieclip<br />

onClipEvent(enterFrame){<br />

// se "brilla" è vera<br />

if(brilla){<br />

// se l'alpha è uguale a 100<br />

if(_alpha == 100){<br />

// settala su 50<br />

_alpha = 50;<br />

// altrimenti settala su 100<br />

}else{<br />

_alpha = 100;<br />

}<br />

}<br />

}<br />

Questo è il risultato dello script:<br />

Richiamo della f<strong>un</strong>zione<br />

Abbiamo visto come i tooltip possano apparire solo <strong>in</strong> modalità d'aiuto, e come f<strong>un</strong>zioni il movieclip con la barra e il<br />

testo. Ora dobbiamo solo associare ai p<strong>un</strong>ti "caldi", lo script che nelle giuste condizioni richiami la f<strong>un</strong>zione contenuta<br />

<strong>in</strong> tooltip. Un'<strong>un</strong>ica premessa: dal momento che la variabile aiuto è def<strong>in</strong>ita nella _root di questo filmato, e che questo<br />

filmato verrà caricato nel livello 10, i richiami da tutti gli altri filmati dovranno essere effettuati sotto il controllo di<br />

_level10.aiuto<br />

Consideriamo <strong>un</strong> movieclip qualsiasi, <strong>in</strong> <strong>un</strong> qual<strong>un</strong>que filmato e su qual<strong>un</strong>que livello. Per generare <strong>un</strong>a scritta, dovrà<br />

avere associato questo script:<br />

onClipEvent (enterFrame) {<br />

if (this.hitTest(_root._xmouse, _root._ymouse, false) && _level10.aiuto) {<br />

_level10.tooltip.scrivi("messaggio che deve apparire nel tooltip");<br />

tip = true;


} else {<br />

if (tip) {<br />

_level10.tooltip.scrivi("");<br />

tip = false;<br />

}<br />

}<br />

}<br />

Molto semplicemente, se il p<strong>un</strong>tatore del mouse tocca il movieclip, e la variabile aiuto sul livello 10 è vera, allora viene<br />

richiamata la f<strong>un</strong>zione scrivi def<strong>in</strong>ita <strong>in</strong> _level10.tooltip, e il parametro che viene passato (la str<strong>in</strong>ga), è il messaggio<br />

<strong>in</strong>cluso tra parentesi. Allo stesso modo, viene settata come vera la variabile tip. Quando <strong>in</strong>vece il p<strong>un</strong>tatore non tocca il<br />

movieclip, se la variabile tip è vera, viene richiamata la f<strong>un</strong>zione con la str<strong>in</strong>ga vuota, e tip diventa falsa.<br />

La variabile tip ha <strong>un</strong> compito importantissimo: se <strong>in</strong>fatti non ci fosse, ogni movieclip richiamerebbe cont<strong>in</strong>uamente la<br />

f<strong>un</strong>zione con la str<strong>in</strong>ga vuota, e i tooltip non si vedrebbero mai.<br />

Questo è l'effetto completo:<br />

Il pannello di controllo<br />

Introduzione<br />

In questa parte vedremo la costruzione del pannello degli strumenti: <strong>in</strong>izieremo dal contorno grafico, <strong>per</strong> poi arrivare al<br />

movieclip "cuore" del pannello stesso. Man mano che procederemo, ci riagganceremo ad alc<strong>un</strong>i movieclip già <strong>in</strong>seriti<br />

sullo stage, spiegandone f<strong>un</strong>zionamento e scopi.<br />

Disegno<br />

Apriamo suono.fla, e aggi<strong>un</strong>giamo alla libreria, tramite il pulsante +, <strong>un</strong> movieclip che chiameremo pannello.<br />

All'<strong>in</strong>terno di questo movieclip, creiamo e r<strong>in</strong>om<strong>in</strong>iamo layer secondo lo schema <strong>in</strong> figura.<br />

Nel layer "pulsante" <strong>in</strong>seriamo <strong>un</strong>'istanza del movieclip freccia, con l'angolo su<strong>per</strong>iore-s<strong>in</strong>istro nel p<strong>un</strong>to di<br />

registrazione. A questo movieclip associamo:<br />

onClipEvent (load) {<br />

<strong>in</strong>izio = _parent._x;<br />

}<br />

onClipEvent (mouseDown) {<br />

if (this.hitTest(_root._xmouse, _root._ymouse, false)) {<br />

if (!a<strong>per</strong>to) {<br />

_parent.f<strong>in</strong>e = 320;


} else {<br />

_parent.f<strong>in</strong>e = <strong>in</strong>izio;<br />

}<br />

a<strong>per</strong>to = !a<strong>per</strong>to;<br />

}<br />

}<br />

Con questo script, quando clicchiamo sul movieclip, alla variabile _parent.f<strong>in</strong>e viene assegnato <strong>un</strong>a volta il valore 320,<br />

l'altra il valore <strong>in</strong>izio, fermato al caricamento del movieclip: questo valore è la posizione del movieclip che contiene la<br />

freccia, all'avvio.<br />

// al caricamento del movieclip<br />

onClipEvent (load) {<br />

// assegna a "<strong>in</strong>izio" il valore della posizione <strong>in</strong>iziale<br />

// sull'asse delle x, del movieclip che contiene la freccia<br />

// (nel nostro caso si tratta del movieclip "pannello")<br />

<strong>in</strong>izio = _parent._x;<br />

}<br />

// al click del mouse<br />

onClipEvent (mouseDown) {<br />

// se il p<strong>un</strong>tatore è sul movieclip<br />

if (this.hitTest(_root._xmouse, _root._ymouse, false)) {<br />

// se la variabile "a<strong>per</strong>to" è vera<br />

if (!a<strong>per</strong>to) {<br />

// setta "f<strong>in</strong>e" uguale a 320<br />

_parent.f<strong>in</strong>e = 320;<br />

// altrimenti<br />

} else {<br />

// assegna a "f<strong>in</strong>e" il valore di "<strong>in</strong>izio"<br />

_parent.f<strong>in</strong>e = <strong>in</strong>izio;<br />

}<br />

// cambia "a<strong>per</strong>to" con il proprio opposto booleano<br />

a<strong>per</strong>to = !a<strong>per</strong>to;<br />

}<br />

}<br />

Torniamo alla timel<strong>in</strong>e pr<strong>in</strong>cipale: trasc<strong>in</strong>iamo nel layer "pannello", <strong>un</strong>'istanza del movieclip omonimo. A questo<br />

movieclip associamo:<br />

onClipEvent (load) {<br />

f<strong>in</strong>e = _x;<br />

accellerazione = 1.8;<br />

<strong>in</strong>erzia = 1.5;<br />

}<br />

onClipEvent (enterFrame) {


<strong>in</strong>izio = _x;<br />

spostamento = (spostamento+(f<strong>in</strong>e-<strong>in</strong>izio)/accellerazione)/<strong>in</strong>erzia;<br />

_x += spostamento;<br />

}<br />

Ad ogni riproduzione di questo movieclip, la posizione sull'asse delle X viene settata <strong>in</strong> base alla formula assoggettata<br />

all'enterFrame. In base a questa formula, attribuiamo all'oggetto <strong>un</strong>a coord<strong>in</strong>ata f<strong>in</strong>ale, che raggi<strong>un</strong>gerà con l'andamento<br />

del moto elastico smorzato. All'avvio, questa coord<strong>in</strong>ata f<strong>in</strong>ale, cioè la variabile f<strong>in</strong>e, è la posizione stessa del movieclip,<br />

dimodoché questo è fermo. Quando poi dall'<strong>in</strong>terno del movieclip, il pulsante freccia ne cambia il valore, il movieclip<br />

pannello si sposta di conseguenza. Questo è quello che otteniamo:<br />

Torniamo all'<strong>in</strong>terno del movieclip pannello: nel layer"ombra", posizioniamo <strong>un</strong>'istanza del movieclip freccia<br />

leggermente spostato <strong>in</strong> basso e a destra, e modificato nella t<strong>in</strong>ta ed alpha tramite il pannello effetti.<br />

Adesso il pannello apparirà così:<br />

Nel terzo layer dal basso, quello chiamato "scritta", <strong>in</strong>seriamo <strong>un</strong> semplice campo di testo con la parola "strumenti". Nel<br />

layer "titoli", <strong>in</strong>seriamo quattro campi di testo statici, convertiti <strong>un</strong>o ad <strong>un</strong>o <strong>in</strong> movieclip, e nel layer "freccette", quattro<br />

istanze del movieclip freccia, rimpicciolite e ruotate.<br />

Ai quattro movieclip contenenti i titoli, associamo questo script:<br />

onClipEvent(load){<br />

colore = new Color(this);<br />

}<br />

onClipEvent(mouseMove){<br />

if(this.hitTest(_root._xmouse,_root._ymouse,false)){<br />

if(!premuto){<br />

sopra = true;<br />

colore.setRGB( 0xFFFFFF );<br />

}<br />

}else{<br />

sopra = false;<br />

if(!premuto){<br />

colore.setRGB( 0x000000 );<br />

}<br />

}<br />

updateAfterEvent();<br />

}


onClipEvent(mouseDown){<br />

if(this.hitTest(_root._xmouse,_root._ymouse,false)){<br />

premuto = true;<br />

colore.setRGB( 0xFFCC00 );<br />

}<br />

updateAfterEvent();<br />

}<br />

onClipEvent(mouseUp){<br />

premuto = false;<br />

if(sopra){<br />

colore.setRGB( 0xFFFFFF );<br />

// azione sottoposta al release<br />

}else{<br />

colore.setRGB( 0x000000 );<br />

}<br />

updateAfterEvent();<br />

}<br />

Lo script, identico <strong>per</strong> tutti e quattro, tranne nella riga che ora è commentata, serve a riprodurre approssimativamente il<br />

comportamento di <strong>un</strong> pulsante: l'azione viene assoggettata al rilascio del tasto s<strong>in</strong>istro del mouse sopra il movieclip,<br />

come nell'on(release). Il resto del codice, è <strong>per</strong> i colori.<br />

Andiamo al layer "barra", e disegniamo sotto i titoli e le freccette, <strong>un</strong>a semplice barra grigia contornata di nero: farà da<br />

sfondo al movieclip che conterrà gli strumenti veri e propri.<br />

Il pannello di controllo<br />

Il movieclip strumenti<br />

Apriamo il file suono.fla. Aggi<strong>un</strong>giamo alla libreria <strong>un</strong> nuovo movieclip, che chiameremo strumenti: questo movieclip<br />

dovrà essere composto da quattro layer, che si chiameranno "scritte", "cornice", "pulsanti" e "asset", di quattro frame<br />

ciasc<strong>un</strong>o.<br />

Data<br />

Aggi<strong>un</strong>giamo alla libreria <strong>un</strong> movieclip che chiameremo dataOra. All'<strong>in</strong>terno di questo movieclip, posizioniamo due<br />

campi di testo d<strong>in</strong>amici, <strong>un</strong>o accanto all'altro: ad <strong>un</strong>o associamo la variabile dat, all'altro la variabile ora.<br />

Andiamo al layer "asset" del movieclip strumenti, e trasc<strong>in</strong>iamo nel primo frame, dalla libreria, <strong>un</strong>'istanza del<br />

movieclip dataOra. A questo movieclip associamo:<br />

onClipEvent (load) {<br />

giorni = new Array(contenuto1);<br />

mesi = new Array(contenuto2);<br />

tempo = new Date();


}<br />

onClipEvent (enterFrame) {<br />

}<br />

ore = tempo.getHours();<br />

m<strong>in</strong>uti = tempo.getM<strong>in</strong>utes();<br />

secondi = tempo.getSeconds();<br />

oggi = tempo.getDate();<br />

giorno = tempo.getDay();<br />

nomegiorno = giorni[giorno];<br />

mese = tempo.getMonth();<br />

nomemese = mesi[mese];<br />

anno = tempo.getFullYear();<br />

ore = (ore


m<strong>in</strong>uti = tempo.getM<strong>in</strong>utes();<br />

// estrai da tempo i secondi (numero da 0 a 59)<br />

secondi = tempo.getSeconds();<br />

// estrai da tempo il giorno del mese (numero da 1 a 31) da associare all'array<br />

oggi = tempo.getDate();<br />

// estrai da tempo il giorno della settimana (numero da 0 a 6, da associare<br />

// all'elemento dell'array, che <strong>per</strong> questo <strong>in</strong>izia con la domenica)<br />

giorno = tempo.getDay();<br />

// associa a nomegiorno l'elemento "giorno" dell'array "giorni"<br />

nomegiorno = giorni[giorno];<br />

// estrai da tempo il mese (numero da 0 a 11)<br />

mese = tempo.getMonth();<br />

// associa a nomemese l'elemento "mese" dell'array "mesi"<br />

nomemese = mesi[mese];<br />

// estrai da tempo l'anno corrente<br />

anno = tempo.getFullYear();<br />

// se le ore sono <strong>in</strong>feriori a 10, "ore" è uguale a "0"+ore, altrimenti a "ore"<br />

ore = (ore


Impostazioni<br />

Andiamo al quarto frame del movieclip strumenti. Inseriamo al centro della barra, <strong>un</strong>a gif importata e convertita <strong>in</strong><br />

movieclip: ai lati, due campi di testo statici, che convertiamo <strong>in</strong> movieclip. Ad entrambi associamo lo stesso script che<br />

abbiamo già visto <strong>per</strong> i titoli, solo che al posto della riga commentata, metteremo i comandi corrispondenti.<br />

In quello di s<strong>in</strong>istra, scriviamo (ho <strong>in</strong>cluso solo il mouseUp):<br />

onClipEvent(mouseUp){<br />

premuto = false;<br />

if(sopra){<br />

colore.setRGB( 0xFFFFFF );<br />

getURL("javascript:pag<strong>in</strong>aIniziale()");<br />

}else{<br />

colore.setRGB( 0x000000 );<br />

}<br />

updateAfterEvent();<br />

}<br />

e <strong>in</strong> quello di destra:<br />

onClipEvent(mouseUp){<br />

premuto = false;<br />

if(sopra){<br />

colore.setRGB( 0xFFFFFF );<br />

getURL("javascript:preferiti()");<br />

}else{<br />

colore.setRGB( 0x000000 );<br />

}<br />

updateAfterEvent();<br />

}<br />

Come possiamo vedere, i comandi sono i richiami a due f<strong>un</strong>zioni Javascript che analizzeremo più avanti, e che ci<br />

<strong>per</strong>metteranno, <strong>per</strong> alc<strong>un</strong>i browser, di <strong>in</strong>serire il <strong>sito</strong> tra i preferiti, o di settarlo come pag<strong>in</strong>a <strong>in</strong>iziale.<br />

P<strong>un</strong>tatore<br />

Aggi<strong>un</strong>giamo alla libreria <strong>un</strong> movieclip nuovo, che chiameremo si-no. Questo movieclip sarà composto da due frame:<br />

<strong>in</strong> <strong>un</strong>o la scritta "si", nell'altro la scritta "no". Andiamo al terzo frame del movieclip strumenti. Inseriamo due campi di<br />

testo statici, come da figura, e accanto ad essi <strong>un</strong>'istanza del movieclip si-no, della gif p<strong>un</strong>tatore, e del movieclip base.<br />

Alle due istanze del movieclip si-no, abbiamo assegnato come script lo stesso usato <strong>per</strong> i titoli e <strong>per</strong> le impostazioni.<br />

Vediamo <strong>in</strong>vece cosa abbiamo assegnato (riporto solo il mouseUp), nella riga commentata, a quello del p<strong>un</strong>tatore:<br />

nClipEvent(mouseUp){<br />

premuto = false;<br />

if(sopra){<br />

colore.setRGB( 0xFFFFFF );


if (!p<strong>un</strong>tatore) {<br />

_root.p<strong>un</strong>tatore._visible = true;<br />

_root.p<strong>un</strong>tatore.vai = true;<br />

_root.p<strong>un</strong>tatore._x = _root._xmouse;<br />

_root.p<strong>un</strong>tatore._y = _root._ymouse;<br />

Mouse.hide();<br />

gotoAndStop(2);<br />

} else {<br />

_root.p<strong>un</strong>tatore._visible = false;<br />

_root.p<strong>un</strong>tatore.vai = false;<br />

Mouse.show();<br />

gotoAndStop(1);<br />

}<br />

p<strong>un</strong>tatore = !p<strong>un</strong>tatore;<br />

}else{<br />

colore.setRGB( 0x000000 );<br />

}<br />

updateAfterEvent();<br />

}<br />

Analizziamo prima questa parte: al rilascio del tasto del mouse, se la variabile p<strong>un</strong>tatore è falsa, il movieclip va al<br />

frame 2 (la scritta "no"), altrimenti va al frame 1 (la scritta "si"), e il valore di p<strong>un</strong>tatore viene <strong>in</strong>vertito.<br />

Abbiamo visto che al p<strong>un</strong>tatore modificato, è associato <strong>un</strong>o script che serve a seguire quello del mouse: <strong>in</strong>oltre, all'avvio<br />

del filmato, questo p<strong>un</strong>tatore è <strong>in</strong>visibile. Qu<strong>in</strong>di:<br />

onClipEvent(mouseUp){<br />

premuto = false;<br />

if(sopra){<br />

colore.setRGB( 0xFFFFFF );<br />

if (!p<strong>un</strong>tatore) {<br />

_root.p<strong>un</strong>tatore._visible = true;<br />

_root.p<strong>un</strong>tatore.vai = true;<br />

_root.p<strong>un</strong>tatore._x = _root._xmouse;<br />

_root.p<strong>un</strong>tatore._y = _root._ymouse;<br />

Mouse.hide();<br />

gotoAndStop(2);<br />

} else {<br />

_root.p<strong>un</strong>tatore._visible = false;<br />

_root.p<strong>un</strong>tatore.vai = false;<br />

Mouse.show();<br />

gotoAndStop(1);<br />

}<br />

p<strong>un</strong>tatore = !p<strong>un</strong>tatore;<br />

}else{


colore.setRGB( 0x000000 );<br />

}<br />

updateAfterEvent();<br />

}<br />

Quando clicchiamo sul movieclip, se la variabile p<strong>un</strong>tatore è falsa, rendiamo il p<strong>un</strong>tatore visibile e lo posizioniamo<br />

all'altezza di quello del mouse, settiamo la variabile vai come vera (e qu<strong>in</strong>di il p<strong>un</strong>tatore modificato segue quello del<br />

mouse), e nascondiamo il p<strong>un</strong>tatore orig<strong>in</strong>ale.<br />

Quando clicchiamo nuovamente sul movieclip, nascondiamo il p<strong>un</strong>tatore modificato, rendiamo visibile quello orig<strong>in</strong>ale,<br />

settiamo vai come falsa (il p<strong>un</strong>tatore non segue più il mouse). Il non seguire più il mouse, se non visibile, serve ad<br />

alleggerire il carico della CPU. Questo è quello che otteniamo:<br />

Il pannello di controllo<br />

Quadrat<strong>in</strong>i<br />

In <strong>un</strong>a delle sezioni precedenti, abbiamo <strong>in</strong>serito 3 istanze del movieclip base nel layer "quadrat<strong>in</strong>i" di suono.fla,<br />

chiamandole quad1, quad2, quad3. Associamo ai tre movieclip questo stesso script:<br />

onClipEvent (load) {<br />

coloreCornice = new Color(cornice);<br />

coloreRettangolo = new Color(rettangolo);<br />

coloreCornice.setRGB( 0x000000 );<br />

coloreRettangolo.setRGB( 0x666666 );<br />

meta = 660;<br />

frame = 10;<br />

}<br />

onClipEvent(enterFrame){<br />

if(!fermo){<br />

if (Math.abs(meta-_x) < 5) {<br />

meta = random(400) + 300;<br />

}<br />

}<br />

_x += (meta - _x)/frame;<br />

}<br />

Nella prima parte, sottoposta al load, settiamo il colore del quadrat<strong>in</strong>o: questo formato dal movieclip base, che al suo<br />

<strong>in</strong>terno contiene il movieclip rettangolo e il movieclip cornice. Creiamo <strong>un</strong>a istanza dell'oggetto Color associata a<br />

ciasc<strong>un</strong>o dei due, e t<strong>in</strong>giamo rispettivamente la prima di grigio, e la seconda di nero.<br />

Qu<strong>in</strong>di, settiamo la variabile meta uguale 660 (sarà il primo p<strong>un</strong>to <strong>in</strong> cui andranno i quadrat<strong>in</strong>i), e la variabile frame<br />

uguale a 10.<br />

Abbiamo già visto la formula seguente (qui <strong>in</strong> versione ridotta): si tratta del moto <strong>un</strong>iformemente decelerato. La meta, o<br />

p<strong>un</strong>to f<strong>in</strong>ale, viene deciso <strong>in</strong> maniera random (all'<strong>in</strong>terno di <strong>un</strong> determ<strong>in</strong>ato <strong>in</strong>tervallo). Quando si verifica la condizione<br />

dell'if, allora viene stabilita <strong>un</strong>a nuova meta. La condizione è verificata quando la posizione dell'oggetto a meno di 5


pixel dal p<strong>un</strong>to che era stato def<strong>in</strong>ito come meta nel richiamo precedente.<br />

Inoltre, tutto il processo di spostamento è soggetto alla variabile fermo, che deve essere falsa:<br />

// al caricamento del movieclip<br />

onClipEvent (load) {<br />

// crea <strong>un</strong>'istanza dell'oggetto Color associata a "cornice<br />

coloreCornice = new Color(cornice);<br />

// crea <strong>un</strong>'istanza dell'oggetto Color associata a "rettangolo"<br />

coloreRettangolo = new Color(rettangolo);<br />

// t<strong>in</strong>gi l'istanza (di nome coloreCornice) di nero<br />

coloreCornice.setRGB( 0x000000 );<br />

// t<strong>in</strong>gi l'istanza (di nome coloreRettangolo) di grigio scuro<br />

coloreRettangolo.setRGB( 0x666666 );<br />

// come prima meta setta 660<br />

meta = 660;<br />

// dai a "frame" il valore 10 (è il "tempo" di spostamento)<br />

frame = 10;<br />

}<br />

// ad ogni riproduzione del movieclip<br />

onClipEvent(enterFrame){<br />

// se la variabile "fermo" è falsa<br />

if(!fermo){<br />

// se il valore assoluto della distanza tra meta e la posizione<br />

// attuale del movieclip, è <strong>in</strong>feriore ai 5 pixel<br />

if (Math.abs(meta-_x) < 5) {<br />

// stabilisci <strong>un</strong>a nuova meta, con <strong>un</strong>a scelta random<br />

// all'<strong>in</strong>terno dell'<strong>in</strong>tervallo 300-700<br />

meta = random(400) + 300;<br />

}<br />

}<br />

// aggi<strong>un</strong>gi alla posizione del movieclip sull'asse delle X, il<br />

// valore di "meta" meno l'attuale posizione, fratto "frame"<br />

_x += (meta - _x)/frame;<br />

}<br />

Al movieclip si-no relativo ai quadrat<strong>in</strong>i, assegnamo come script (riporto solo il mouseUp), nella riga commentata:<br />

onClipEvent(mouseUp){<br />

premuto = false;<br />

if(sopra){<br />

colore.setRGB( 0xFFFFFF );<br />

if (!quadrati) {<br />

gotoAndStop (1);<br />

for (i = 1; i < 4; i++) {<br />

_root["quad" + i].fermo = true;


_root["quad" + i].meta = 650+(10*i);<br />

}<br />

} else {<br />

gotoAndStop (2);<br />

for (i = 1; i < 4; i++) {<br />

_root["quad" + i].fermo = false;<br />

}<br />

}<br />

quadrati = !quadrati;<br />

}else{<br />

colore.setRGB( 0x000000 );<br />

}<br />

updateAfterEvent();<br />

}<br />

Analizziamo prima questa parte: al rilascio del tasto del mouse, se la variabile quadrati è falsa, il movieclip va al frame<br />

1 (la scritta "si"), altrimenti va al frame 2 (la scritta "no"), e il valore di quadrati viene <strong>in</strong>vertito.<br />

onClipEvent(mouseUp){<br />

premuto = false;<br />

if(sopra){<br />

colore.setRGB( 0xFFFFFF );<br />

if (!quadrati) {<br />

gotoAndStop (1);<br />

for (i = 1; i < 4; i++) {<br />

_root["quad" + i].fermo = true;<br />

_root["quad" + i].meta = 650+(10*i);<br />

}<br />

} else {<br />

gotoAndStop (2);<br />

for (i = 1; i < 4; i++) {<br />

_root["quad" + i].fermo = false;<br />

}<br />

}<br />

quadrati = !quadrati;<br />

}else{<br />

colore.setRGB( 0x000000 );<br />

}<br />

updateAfterEvent();<br />

}<br />

Cliccando sul movieclip, se quadrati è falsa, <strong>in</strong>neschiamo <strong>un</strong> ciclo con il for. Per la i che va da 1 a 3, prendiamo i<br />

quadrat<strong>in</strong>i con nome di istanza "quad" più i (e qu<strong>in</strong>di, app<strong>un</strong>to, quad1, quad2, quad3), e ne settiamo la variabile fermo<br />

come vera. Se guardiamo lo script associato ai quadrat<strong>in</strong>i, vedremo che la scelta random della meta avviene se fermo è<br />

falsa: qu<strong>in</strong>di, <strong>un</strong>a volta premuto il movieclip, i quadrat<strong>in</strong>i raggi<strong>un</strong>geranno l'ultima meta scelta, e lì si fermeranno. Ma


noi facciamo di più: impostiamo <strong>un</strong>'altra meta, vic<strong>in</strong>o al limite del filmato. Sarà 650 più i <strong>per</strong> 10, e qu<strong>in</strong>di 660, 670 e<br />

690.<br />

Al contrario, quando cliccheremo ancora sul movieclip, (e quadrati sarà vera), riprist<strong>in</strong>eremo il valore di fermo su<br />

false (e i quadrat<strong>in</strong>i ricom<strong>in</strong>ceranno ad avere mete random, e qu<strong>in</strong>di a muoversi).<br />

Il pannello di controllo<br />

L'oggetto So<strong>un</strong>d<br />

Prima di passare allo sviluppo del controllo del suono, faccio <strong>un</strong> excursus sull'argomento "oggetto So<strong>un</strong>d". Dal<br />

momento che <strong>in</strong>seriremo <strong>un</strong> sistema abbastanza avanzato <strong>per</strong> la regolazione del volume, è meglio aver chiaro il<br />

f<strong>un</strong>zionamento dei metodi e delle proprietà f<strong>in</strong> dall'<strong>in</strong>izio. Per questi esempi, essendo preferibile <strong>un</strong> <strong>un</strong> suono costante, e<br />

molto leggero, ho scelto <strong>un</strong> noiosissimo tono telefonico. Inoltre, <strong>per</strong> non appesantire troppo la pag<strong>in</strong>a, ho deciso di<br />

lasciare libera scelta su quali esempi caricare.<br />

Spiegazione<br />

Creiamo <strong>un</strong> nuovo documento flash, e importiamo <strong>un</strong> suono nella libreria. Clicchiamo con il tasto destro del mouse sul<br />

suono (nella libreria), e dal menu contestuale scegliamo L<strong>in</strong>kage (Concatenamento).<br />

Scegliamo adesso l'opzione Export this symbol, e nel campo Identifier (Identificatore), scriviamo loop. A questo<br />

p<strong>un</strong>to premiamo OK.<br />

Andiamo al primo frame della timel<strong>in</strong>e pr<strong>in</strong>cipale, e scriviamo:<br />

suono = new So<strong>un</strong>d(_root);<br />

suono.attachSo<strong>un</strong>d("loop");


Quello che abbiamo fatto, è stato <strong>creare</strong> <strong>un</strong>'istanza dell'oggetto So<strong>un</strong>d, associata alla _root, con il nome suono. Poi, a<br />

questa istanza, abbiamo "attaccato" il suono l<strong>in</strong>kato come loop nella libreria. Se il suono è impostato nel filmato<br />

pr<strong>in</strong>cipale, si può omettere il _root tra le parentesi del new So<strong>un</strong>d: se <strong>in</strong>vece viene impostato all'<strong>in</strong>terno di <strong>un</strong> movieclip,<br />

o su <strong>un</strong> livello diverso dal pr<strong>in</strong>cipale, tra parentesi bisogna <strong>in</strong>dicare il target.<br />

L'<strong>un</strong>ica cosa che manca, ora, è il comando <strong>per</strong> riprodurre il suono:<br />

suono.start(0,999);<br />

dove 0 è l'offset (cioè dopo quanti secondi deve avvenire la riproduzione, rispetto all'<strong>in</strong>izio del suono), e 999 è il<br />

numero di cicli (il suono viene ripetuto 999 volte di seguito). Per fermare il suono, il comando :<br />

suono.stop();<br />

Possiamo associare questi comandi ad <strong>un</strong> frame, ad <strong>un</strong> evento dei movieclip, o a <strong>un</strong> pulsante: noi scegliamo l'ultima<br />

opzione (anche se <strong>in</strong> verità uso <strong>un</strong> movieclip che f<strong>un</strong>ge da pulsante, più avanti vedremo <strong>per</strong>ché). Quello che otteniamo è<br />

il filmato seguente: <strong>un</strong>a cosa da provare, è quella di premere più volte il pulsante "play".<br />

Come si nota, premendo più volte il pulsante "play", vengono riprodotte più istanze dello stesso suono, con <strong>un</strong>o<br />

spiacevole accavallamento. E' preferibile allora porre <strong>un</strong> controllo, aff<strong>in</strong>chè <strong>un</strong>a volta <strong>in</strong>izializzata la riproduzione, non<br />

ne possa essere avviata <strong>un</strong>'altra f<strong>in</strong>o alla pressione del tasto "stop". Il comando <strong>per</strong> il "play", qu<strong>in</strong>di, diventerà:<br />

if(!riproduzione){<br />

suono.start(0,999);<br />

riproduzione = true;<br />

}<br />

e quello <strong>per</strong> lo stop:<br />

if(riproduzione){<br />

suono.stop();<br />

riproduzione = false;<br />

}<br />

All'avvio del filmato, non essendo stata def<strong>in</strong>ita prima, la variabile riproduzione è falsa. Quando premiamo il pulsante<br />

"play", il suono viene avviato e riproduzione diventa vera. Al quel p<strong>un</strong>to, la condizione !riproduzione non è più<br />

verificata, e le successive pressioni del pulsante non sortiranno alc<strong>un</strong> effetto. Per il tasto "stop", vale lo stesso<br />

ragionamento, solo che il valore della variabile è <strong>in</strong>vertito. Questo è quello che otteniamo:<br />

Per regolare il volume del suono, si usa il metodo setVolume(valore), dove "valore" corrisponde ad <strong>un</strong> <strong><strong>in</strong>tero</strong> che va da<br />

0 a 100. Per cui, se scriviamo<br />

suono.setVolume(50);<br />

il volume del nostro suono sarà ridotto alla metà. Per poter aumentare il volume di <strong>un</strong>a <strong>un</strong>ità, <strong>per</strong>ò, dobbiamo sa<strong>per</strong>e a<br />

quanto ammonta attualmente il valore: si usa qu<strong>in</strong>di il metodo getVolume() <strong>per</strong> ricavare il valore attuale, e si somma 1<br />

<strong>per</strong> aumentare. Il comando sarà di questo tipo:


suono.setVolume(suono.getVolume()+1);<br />

D'altronde si può fare di meglio: sapendo che quando avviamo <strong>un</strong> suono, questo ha <strong>un</strong> volume di 100 (di default),<br />

possiamo anche settare <strong>un</strong>a variabile che <strong>in</strong>terpreti e regoli <strong>per</strong> noi il volume. Nella timel<strong>in</strong>e pr<strong>in</strong>cipale scriviamo:<br />

i = 100;<br />

e <strong>per</strong> abbassare il volume:<br />

i--;<br />

suono.setVolume(i)<br />

Naturalmente, il valore di "i" potrebbe anche scendere sotto lo zero, mentre il volume si fermerebbe com<strong>un</strong>que lì.<br />

Qu<strong>in</strong>di poniamo delle condizioni sul valore della "i", <strong>per</strong> mantenerla tra 0 e 100. Per alzare il volume:<br />

if(i < 100){<br />

i++;<br />

suono.setVolume(i);<br />

}<br />

e <strong>per</strong> abbassarlo:<br />

&gt;if(i > 0){<br />

i--;<br />

suono.setVolume(i);<br />

}<br />

Il vantaggio di tutto ciò, sta nel fatto che abbiamo <strong>un</strong>a variabile, la "i", che ci <strong>in</strong>dica il volume, e che possiamo utilizzare<br />

<strong>per</strong> altri scopi. Ad esempio, se sullo stage posizioniamo <strong>un</strong> campo di testo d<strong>in</strong>amico a cui associamo la variabile<br />

volume, quando modifichiamo il volume, possiamo modificare anche il contenuto del campo di testo basandoci sulla i,<br />

ottenendo <strong>un</strong> <strong>in</strong>dicatore <strong>in</strong> cifre. Se poi settiamo anche la larghezza di <strong>un</strong>a barra su quel valore, come con:<br />

if(i > 0){<br />

i--;<br />

volume = vol._xscale = i;<br />

suono.setVolume(i);<br />

}<br />

otteniamo:<br />

Possiamo fare ancora di più, e sfruttare gli eventi dei movieclip (ora vedremo <strong>per</strong>chè usare questi piuttosto che i<br />

pulsanti). Impostiamo <strong>un</strong>a variabile come vera alla pressione del tasto s<strong>in</strong>istro del mouse su <strong>un</strong> movieclip, e su falsa<br />

quando rilasciamo il tasto. Contemporaneamente, sullo stesso movieclip, sottoponiamo ad <strong>un</strong> enterFrame la modifica<br />

del volume f<strong>in</strong>chè la variabile è vera:<br />

onClipEvent(mouseDown){<br />

if(this.hitTest(_root._xmouse,_root._ymouse,true)){


modifica = true;<br />

}<br />

}<br />

onClipEvent(mouseUp){<br />

modifica = false;<br />

}<br />

onClipEvent(enterFrame){<br />

if(modifica){<br />

if(_root.i > 0){<br />

_root.i--;<br />

_root.volume = _root.vol._xscale = _root.i;<br />

_root.suono.setVolume(_root.i);<br />

}<br />

}<br />

}<br />

Spiegato riga <strong>per</strong> riga:<br />

// alla pressione del tasto s<strong>in</strong>istro del mouse<br />

onClipEvent(mouseDown){<br />

// se il p<strong>un</strong>tatore del mouse è sopra questo movieclip<br />

if(this.hitTest(_root._xmouse,_root._ymouse,true)){<br />

// setta la variabile "modifica" come vera<br />

modifica = true;<br />

}<br />

}<br />

// al rilascio del tasto s<strong>in</strong>istro del mouse<br />

onClipEvent(mouseUp){<br />

// setta la variabile "modifica" come falsa<br />

modifica = false;<br />

}<br />

// ad ogni riproduzione del movieclip<br />

onClipEvent(enterFrame){<br />

// se la variabile "modifica" è vera<br />

if(modifica){<br />

// se "i" è maggiore di 0<br />

if(i > 0){<br />

// dim<strong>in</strong>uisci il valore di "i" di <strong>un</strong>a <strong>un</strong>ità<br />

i--;<br />

// scrivi nel campo di testo "volume", il valore<br />

// dell'_xscale della barra "vol", che è uguale a "i"<br />

volume = vol._xscale = i;<br />

// setta il volume su "i"<br />

suono.setVolume(i);


}<br />

}<br />

}<br />

Il risultato:<br />

Il pannello di controllo<br />

_xmouse<br />

Un'ultima digressione prima di entrare nel vivo. La proprietà _xmouse di <strong>un</strong> movieclip, ci dice qual'è la posizione del<br />

p<strong>un</strong>tatore del mouse nel suo sistema di coord<strong>in</strong>ate. Se poi il movieclip è <strong>un</strong>a barra, è facile capire come questa proprietà<br />

ci possa tornare utile con la regolazione del volume.<br />

Facciamo subito <strong>un</strong>a prova: creiamo <strong>un</strong> nuovo progetto <strong>Flash</strong>, e aggi<strong>un</strong>giamo <strong>un</strong> movieclip alla libreria con il nome<br />

barra. Dentro questo movieclip, disegniamo <strong>un</strong> rettangolo alto 10 pixel e largo 100, con l'angolo su<strong>per</strong>iore s<strong>in</strong>istro sul<br />

p<strong>un</strong>to di registrazione del movieclip stesso. Trasc<strong>in</strong>iamo sullo stage <strong>un</strong>'istanza di questo movieclip, alla quale diamo mc<br />

come nome.<br />

Disegniamo ora sullo stage <strong>un</strong> campo di testo d<strong>in</strong>amico, a cui associamo la variabile "testo". Inseriamo il campo <strong>in</strong> <strong>un</strong><br />

movieclip, al quale associamo il seguente script:<br />

onClipEvent (mouseMove) {<br />

testo = _parent.mc._xmouse;<br />

}<br />

Ad ogni movimento del mouse, <strong>in</strong>seriamo nel campo di testo il valore dell'_xmouse rispetto alla barra.<br />

Adesso <strong>in</strong>seriamo <strong>un</strong>'altra istanza del movieclip barra sopra quella precedente, e le associamo:<br />

onClipEvent (load) {<br />

_visible = 0;<br />

}<br />

onClipEvent (mouseMove) {<br />

_parent.mc._xscale = _xmouse;<br />

}<br />

La nuova barra, all'avvio, è <strong>in</strong>visibile, e sul proprio _xmouse viene scalata la barra mc. Nella casella di testo, quello che<br />

leggiamo è mc._xscale:<br />

Adesso non solo sottoponiamo la scalatura al trasc<strong>in</strong>amento con il mouse, <strong>in</strong>vece che solamente al movimento, ma<br />

poniamo anche dei limiti <strong>per</strong> non strabordare nell'<strong>un</strong>a o nell'altra direzione. Associamo alla barra su<strong>per</strong>iore:<br />

onClipEvent(load){<br />

f<strong>un</strong>ction setta(){<br />

k = Math.ro<strong>un</strong>d(_xmouse);<br />

if(k < 0){<br />

k = 0;<br />

}else if(k > 100){


k = 100;<br />

}<br />

_parent.mc._xscale = k;<br />

updateAfterEvent();<br />

}<br />

}<br />

onClipEvent (mouseDown) {<br />

if (this.hitTest(_root._xmouse,_root._ymouse,true)) {<br />

premuto = true;<br />

setta();<br />

}else{<br />

premuto = false;<br />

}<br />

}<br />

onClipEvent(mouseMove){<br />

if(premuto){<br />

setta();<br />

}<br />

}<br />

onClipEvent(mouseUp){<br />

premuto = false;<br />

}<br />

Quando clicchiamo sulla barra, che viene resa <strong>in</strong>visibile al caricamento, la variabile premuto diventa vera: al rilascio<br />

del pulsante del mouse, torna falsa. Se il mouse si muove quando premuto è vera, o si clicca sulla barra, viene<br />

richiamata la f<strong>un</strong>zione setta def<strong>in</strong>ita all'<strong>in</strong>izio. La f<strong>un</strong>zione setta calcola l'_xmouse sulla barra <strong>in</strong>visibile, e ne attribuisce<br />

il valore arrotondato alla variabile k. Se k su<strong>per</strong>a il 100, viene riportata a 100, se su<strong>per</strong>a <strong>in</strong> basso lo 0, viene riportata a 0:<br />

<strong>in</strong> ogni caso, il movieclip con la barra visibile, mc, viene scalato sul valore di k.<br />

// al caricamento del movieclip<br />

onClipEvent(load){<br />

// def<strong>in</strong>isci la f<strong>un</strong>zione "setta"<br />

f<strong>un</strong>ction setta(){<br />

// al richiamo della f<strong>un</strong>zione, attribuisci a "k" il<br />

// valore arrotondato dell'_xmouse su questo movieclip<br />

k = Math.ro<strong>un</strong>d(_xmouse);<br />

// se "k" diventa m<strong>in</strong>ore di 0<br />

if (k < 0){<br />

// poni "k" uguale a 0<br />

k = 0;<br />

// altrimenti, se "k" diventa maggiore di 100<br />

}else if (k > 100){<br />

// poni "k" uguale a 100<br />

k = 100;


}<br />

// scala il movieclip "mc" sul valore di "k"<br />

_parent.mc._xscale = k;<br />

// forza <strong>un</strong> refresh dello schermo<br />

updateAfterEvent();<br />

}<br />

}<br />

// alla pressione del tasto s<strong>in</strong>istro del mouse<br />

onClipEvent (mouseDown) {<br />

// se il p<strong>un</strong>tatore è su questo movieclip<br />

if (this.hitTest(_root._xmouse,_root._ymouse,true)) {<br />

// setta la variabile "premuto" come vera<br />

premuto = true;<br />

// richiama la f<strong>un</strong>zione "setta"<br />

setta();<br />

// altrimenti<br />

}else{<br />

// (non siamo sulla barra) rendi "premuto" come falsa<br />

premuto = false;<br />

}<br />

}<br />

// allo spostamento del mouse<br />

onClipEvent(mouseMove){<br />

// se la variabile "premuto" è vera<br />

if(premuto){<br />

// richiama la f<strong>un</strong>zione "setta"<br />

setta();<br />

}<br />

}<br />

// al rilascio del tasto s<strong>in</strong>istro del mouse<br />

onClipEvent(mouseUp){<br />

// setta la variabile "premuto" come falsa<br />

premuto = false;<br />

}<br />

Ed ecco il risultato:<br />

Scaliamo <strong>un</strong>a barra da 0 a 100, e questo valore è racchiuso <strong>in</strong> "k". E se regoliamo il volume su k?<br />

Volume<br />

Apriamo il filmato suono.fla. Aggi<strong>un</strong>giamo alla libreria <strong>un</strong> nuovo movieclip, che chiameremo barraVolume, e che<br />

conterrà <strong>un</strong> rettangolo giallo senza contorno di 100 pixel <strong>per</strong> 10: <strong>in</strong>oltre, l'angolo su<strong>per</strong>iore s<strong>in</strong>istro del rettangolo dovrà<br />

essere al centro del movieclip. Andiamo al secondo frame del movieclip strumenti: nel layer "asset" <strong>in</strong>seriamo


<strong>un</strong>'istanza della barra, t<strong>in</strong>ta di grigio tramite il pannello Effetti.<br />

Nel layer "pulsanti", <strong>in</strong>seriamo 4 campi di testo statici, che convertiremo <strong>in</strong> movieclip: nel layer "cornice" <strong>in</strong>seriamo<br />

<strong>un</strong>'altra istanza del movieclip barraVolume, questa volta con il colore orig<strong>in</strong>ario e con nome di istanza barra, e sopra<br />

di essa, <strong>un</strong>'istanza del movieclip cornice, delle stesse dimenzioni della barra. Nel layer "scritte", <strong>in</strong>f<strong>in</strong>e, posizioniamo <strong>un</strong><br />

campo di testo d<strong>in</strong>amico, a cui associamo la variabile volume. Nel primo frame del movieclip, <strong>in</strong>seriamo <strong>un</strong> i=100;<br />

Il risultato dovrà essere questo:<br />

A tutti e quattro i pulsanti associamo lo stesso script dei titoli. Nella riga commentata, <strong>in</strong>seriamo rispettivamente<br />

(riporto solo le parti modificate):<br />

al pulsante PLAY<br />

al pulsante STOP<br />

onClipEvent(mouseUp){<br />

premuto = false;<br />

if(sopra){<br />

colore.setRGB( 0xFFFFFF );<br />

if (_root.riproduzione) {<br />

_root.suono.stop();<br />

_root.riproduzione = false;<br />

}<br />

}else{<br />

colore.setRGB( 0x000000 );<br />

}<br />

updateAfterEvent();<br />

}<br />

onClipEvent(mouseUp){<br />

premuto = false;<br />

if(sopra){<br />

colore.setRGB( 0xFFFFFF );<br />

if (!_root.riproduzione) {<br />

_root.suono.start(0,999);<br />

_root.riproduzione = true;<br />

}<br />

}else{<br />

colore.setRGB( 0x000000 );<br />

}<br />

updateAfterEvent();<br />

}<br />

al pulsante MIN (al quale diamo m<strong>in</strong> come nome di istanza)<br />

onClipEvent(mouseUp){<br />

premuto = false;<br />

if(sopra){<br />

colore.setRGB( 0xFFFFFF );<br />

vai = true;<br />

_parent.max.vai = false;<br />

}else{


colore.setRGB( 0x000000 );<br />

}<br />

updateAfterEvent();<br />

}<br />

onClipEvent(enterFrame){<br />

if(vai){<br />

start = _parent.i;<br />

fade = (0-start)/30;<br />

_parent.i = Math.floor(_parent.i + fade);<br />

_root.suono.setVolume(_parent.i);<br />

_parent.barra._width = _parent.volume = _parent.i;<br />

}<br />

}<br />

al pulsante MAX (al quale diamo max come nome di istanza)<br />

onClipEvent(mouseUp){<br />

premuto = false;<br />

if(sopra){<br />

colore.setRGB( 0xFFFFFF );<br />

vai = true;<br />

_parent.m<strong>in</strong>.vai = false;<br />

}else{<br />

colore.setRGB( 0x000000 );<br />

}<br />

updateAfterEvent();<br />

}<br />

onClipEvent(enterFrame){<br />

if(vai){<br />

start = _parent.i;<br />

fade = (100-start)/30;<br />

_parent.i = Math.ceil(_parent.i + fade);<br />

_root.suono.setVolume(_parent.i);<br />

_parent.barra._width = _parent.volume = _parent.i<br />

}<br />

}<br />

Abbiamo impostato, nella timel<strong>in</strong>e pr<strong>in</strong>cipale del filmato, questo script. Il suono parte <strong>in</strong> automatico, all'avvio del<br />

filmato, e la variabile riproduzione è vera: gli script del tasto PLAY e STOP non hanno bisogno di spiegazione (li<br />

abbiamo visti tali e quali nella sezione precedente).<br />

Gli script <strong>in</strong>teressanti sono quelli dei pulsati MAX e MAX. Come possiamo vedere, <strong>un</strong>a volta premuto <strong>un</strong>o dei due<br />

movieclip, rendiamo vera la variabile vai: a quel p<strong>un</strong>to vengono eseguite le azioni sottoposte all'enterFrame (if(vai),<br />

cioè se vai è vera).<br />

Altra cosa da vedere, è che allo stesso tempo viene settata come falsa la variabile vai dell'altro movieclip: il che<br />

significa che i due blocchi di enterFrame, non vengono mai eseguiti contemporaneamente.


Quello che succede, con questi script, non è nient'altro che l'applicazione della formula del moto <strong>un</strong>iformemente<br />

decelerato, applicato a qualcosa che non si muove. Infatti, quello che facciamo, e decrementare decelarando il valore<br />

della variabile "i", settata nel movieclip strumenti come 100, e che ci rappresenta il volume del suono. La "posizione"<br />

f<strong>in</strong>ale, sarà sempre lo 0 <strong>per</strong> il pulsante MIN, e 100 <strong>per</strong> il pulsante MAX. La "posizione" <strong>in</strong>iziale sarà il valore attuale di<br />

"i".<br />

L'<strong>un</strong>ica fondamentale differenza, assolutamente degna di nota, è che alla "posizione" attuale della "i", noi sommiamo,<br />

<strong>in</strong>vece che la somma tra la "posizione" e lo "spostamento" (fade), l'arrotondamento <strong>per</strong> difetto della somma tra la<br />

"posizione" e lo "spostamento", nel caso del MIN, e l'arrotondamento <strong>per</strong> eccesso, nel caso del MAX. Se non<br />

facessimo così, il valore non arriverebbe mai rispettivamente allo 0 e al 100. Spiego riga <strong>per</strong> riga <strong>un</strong>o solo dei due<br />

codici (sono praticamente identici):<br />

onClipEvent(mouseUp){<br />

premuto = false;<br />

if(sopra){<br />

colore.setRGB( 0xFFFFFF );<br />

// setta la variabile "vai" come vera<br />

vai = true;<br />

// setta la variabile "vai" <strong>in</strong> "max" come falsa<br />

_parent.max.vai = false;<br />

}else{<br />

colore.setRGB( 0x000000 );<br />

}<br />

updateAfterEvent();<br />

}<br />

// ad ogni riproduzione del movieclip<br />

onClipEvent(enterFrame){<br />

// se la variabile "vai" è vera<br />

if(vai){<br />

// dai a "start" il valore attuale della "i"<br />

start = _parent.i;<br />

// dai a "fade" il valore di -"start" fratto 30<br />

fade = (0-start)/30;<br />

// assegna a "i" il valore dell'arrotondamento <strong>per</strong><br />

// difetto della somma tra "i" e "fade"<br />

_parent.i = Math.floor(_parent.i + fade);<br />

// setta il volume del suono uguale a "i"<br />

_root.suono.setVolume(_parent.i);<br />

// dai alla larghezza della barra il valore di "i"<br />

// e scrivi "i" nel campo di testo "volume"<br />

_parent.barra._width = _parent.volume = _parent.i;<br />

}<br />

}<br />

La barra


Alla barra t<strong>in</strong>ta di grigio, associamo lo stesso script che abbiamo visto all'<strong>in</strong>izio di questa sezione (riporto solo le parti<br />

salienti):<br />

onClipEvent(load){<br />

_parent.barra._width = _parent.i;<br />

f<strong>un</strong>ction setta(){<br />

k = Math.ro<strong>un</strong>d(_xmouse);<br />

if(k < 0){<br />

k = 0;<br />

}else if(k > 100){<br />

k = 100;<br />

}<br />

_root.suono.setVolume(k);<br />

_parent.barra._width = _parent.volume = _parent.i = k;<br />

updateAfterEvent();<br />

}<br />

}<br />

onClipEvent (mouseDown) {<br />

if (this.hitTest(_root._xmouse,_root._ymouse,true)) {<br />

_parent.max.vai = _parent.m<strong>in</strong>.vai = false;<br />

premuto = true;<br />

setta();<br />

}else{<br />

premuto = false;<br />

}<br />

}<br />

onClipEvent(mouseMove){<br />

if(premuto){<br />

setta();<br />

}<br />

}<br />

Unica differenza, è che al click sulla barra viene settata come falsa la variabile vai <strong>in</strong> entrambi i movieclip MIN e MAX,<br />

<strong>in</strong> modo da <strong>in</strong>terrom<strong>per</strong>e gli eventuali cicli sottoposti all'enterFrame. Questo è il risultato.<br />

Concludiamo: andiamo al movieclip pannello, e nel layer "strumenti" trasc<strong>in</strong>iamo dalla libreria <strong>un</strong>'istanza del movieclip<br />

strumenti che abbiamo appena completato. Diamo al movieclip, come nome di istanza, il nome strumenti.<br />

Selezionando ora i titoli <strong>un</strong>o ad <strong>un</strong>o, sostituiamo alle righe commentate il comando:<br />

_parent.strumenti.gotoAndStop(X);<br />

dove X rappresenta di volta <strong>in</strong> volta il frame a cui rimandare.<br />

Qu<strong>in</strong>di, <strong>in</strong> ord<strong>in</strong>e, il pulsante data conterrà:<br />

_parent.strumenti.gotoAndStop(1);<br />

il pulsante suono:<br />

_parent.strumenti.gotoAndStop(2);<br />

eccetera.


L'<strong>in</strong>tro<br />

Il problema dell'<strong>in</strong>tro<br />

A mio parere, i filmati <strong>in</strong>troduttivi sono la cosa peggiore portata dal <strong>Flash</strong>. Intendiamoci, solo i filmati <strong>in</strong>troduttivi, non<br />

i filmati <strong>in</strong> generale.<br />

Non sempre abbiamo tempo e voglia di guardare <strong>un</strong>a <strong>in</strong>tro da 500k, quando quello che cerchiamo è il contenuto (anche<br />

se presentato <strong>in</strong> <strong>un</strong>a veste grafica accattivante). Se poi consideriamo che mettiamo mani nel registro <strong>per</strong> elim<strong>in</strong>are gli<br />

splash screen, che ci fanno <strong>per</strong>dere secondi preziosi, e che daremmo fuoco a chi ci fa scaricare allegati <strong>in</strong>utili e catene di<br />

Sant'Antonio, il ragionamento non appare <strong>in</strong>coerente.<br />

Credo s<strong>in</strong>ceramente che le <strong>in</strong>tro abbiano fatto il loro tempo: non nego la bellezza di <strong>un</strong> filmato di presentazione, che<br />

spesso dimostra grande tecnica e gusto artistico, ma lo vedo meglio come "<strong>un</strong>a scelta" all'<strong>in</strong>terno di <strong>un</strong> <strong>sito</strong>, che come<br />

passaggio obbligato. Soprattutto tre sono le cose che mi <strong>in</strong>fastidiscono:<br />

• l'assenza del meraviglioso tasto skip, che <strong>per</strong>metta di saltare tout-court l'animazione<br />

• l'essere costretto a passare <strong>per</strong> l'<strong>in</strong>tro ogni volta che accedo nuovamente al <strong>sito</strong><br />

• <strong>un</strong>o stile ormai abusato: musica tecno, immag<strong>in</strong>i veloci, frasi ridicole come<br />

"stiamo arrivando!"<br />

"siete pronti?"<br />

"dimenticate tutto quello che sapete sul web"<br />

"state <strong>per</strong> entrare <strong>in</strong> <strong>un</strong>a nuova dimensione"<br />

"lo spazio... il tempo"<br />

"<strong>in</strong>ternet... la rete si evolve"<br />

e altre amenità di questo tipo.<br />

Naturalmente, si tratta della mia <strong>per</strong>sonalissima op<strong>in</strong>ione.<br />

D'altronde, lo scopo di questa sezione della guida, non è spiegare come fare <strong>un</strong> filmato <strong>in</strong>troduttivo, ma come utilizzarlo<br />

nel modo tradizionale. Il problema pratico è: avere l'<strong>in</strong>tro, e poterla evitare.<br />

I metodi sono:<br />

• <strong>in</strong>serire <strong>un</strong> filmato di presentazione, ma solo a scelta dall'<strong>in</strong>terno del <strong>sito</strong>, non prima<br />

• porre al navigatore la scelta di accedere al <strong>sito</strong> con o senza il filmato <strong>in</strong>troduttivo<br />

• passare obbligatoriamente <strong>per</strong> l'<strong>in</strong>tro la prima volta, ma non <strong>in</strong> quelle successive, anche se non è stata visualizzata<br />

Il primo metodo non ha bisogno di tecniche particolari, si tratta semplicemente di rendere accessibile <strong>un</strong> filmato da <strong>un</strong><br />

menu <strong>in</strong>terno. Il secondo, prevede o l'accesso diretto al <strong>sito</strong>, o il passaggio <strong>per</strong> l'<strong>in</strong>tro che, <strong>un</strong>a volta term<strong>in</strong>ata, richiama<br />

la pag<strong>in</strong>a pr<strong>in</strong>cipale.<br />

Il terzo caso, <strong>in</strong>vece, è quello che <strong>in</strong>teressa a noi. Supponiamo di essere obbligati a <strong>in</strong>serire l'<strong>in</strong>tro, ma a non voler<br />

tediare troppo i visitatori le volte successive: dobbiamo qu<strong>in</strong>di trovare <strong>un</strong> sistema <strong>per</strong> lasciare traccia dell'avvenuto<br />

accesso alla pag<strong>in</strong>a. Con i l<strong>in</strong>guaggi esistenti, siano essi asp, cgi, o php, possiamo scrivere dei cookies che, rimanendo<br />

nella cache del browser, potranno essere letti successivamente, <strong>per</strong> passarci le <strong>in</strong>formazioni di cui abbiamo bisogno.<br />

Quello che ci siamo proposti nella progettazione del <strong>sito</strong>, <strong>per</strong>ò, era il non usare altri l<strong>in</strong>guaggi oltre all'Actionscript, f<strong>in</strong><br />

dove possibile. Per questo motivo, tutto dovrà essere fatto da dentro <strong>Flash</strong>.<br />

Unica cosa veramente importante, e da applicare <strong>in</strong> ogni caso, è la separazione del filmato <strong>in</strong>troduttivo da quello<br />

pr<strong>in</strong>cipale: non devono mai essere contenuti nello stesso file.<br />

Il filmato


Creiamo <strong>un</strong> nuovo progetto <strong>in</strong> <strong>Flash</strong>, 700x300, 24 fps, composto da due scene (ricordo che le scene sono<br />

esclusivamente <strong>per</strong> comodità di chi progetta, dal momento che all'esportazione non esistono più).<br />

Nella seconda scena, si svolge l'animazione <strong>in</strong>troduttiva, che <strong>in</strong> questo caso la creazione dell'om<strong>in</strong>o di HTML.it tramite<br />

l'effetto laser, già spiegato <strong>in</strong> <strong>un</strong> articolo precedente. Nel primo frame della timel<strong>in</strong>e, <strong>in</strong> <strong>un</strong> layer qualsiasi, <strong>in</strong>seriamo il<br />

suono di sottofondo, impostato come evento, e con loop massimi.<br />

In <strong>un</strong> altro layer, posizioniamo il pulsante skip.<br />

Il tasto skip<br />

Il tasto skip non fa altro che richiamare il filmato pr<strong>in</strong>cipale, e deve essere presente f<strong>in</strong> dall'<strong>in</strong>izio dell'<strong>in</strong>tro, preloader<br />

compreso. Vediamo quali sono le azioni da associare al pulsante:<br />

loadMovieNum ("flash5.swf", 0);<br />

Al click sul pulsante, o sul movieclip, viene caricato nel livello 0 il filmato flash5.swf, che semplicemente prende il<br />

posto dell'<strong>in</strong>tro. Nel nostro caso, il pulsante skip è <strong>un</strong> movieclip, al quale associamo:<br />

onClipEvent(mouseDown){<br />

if(this.hitTest(_root._xmouse,_root._ymouse,false)){<br />

loadMovieNum ("flash5.swf", 0);<br />

}<br />

}// alla pressione del pulsante s<strong>in</strong>istro del mouse<br />

onClipEvent(mouseDown){<br />

// se il p<strong>un</strong>tatore è sul moveiclip<br />

if(this.hitTest(_root._xmouse,_root._ymouse,false)){<br />

// carica il filmato "flash5.swf" sul livello 0<br />

loadMovieNum ("flash5.swf", 0);<br />

}<br />

}<br />

Il preloader<br />

La parte più importante dell'<strong>in</strong>tro è il preloader: <strong>in</strong>fatti, grazie a quello, riusciamo ad evitarne l'ennesima riproduzione ai<br />

successivi accessi.<br />

Vediamo la sequenza di eventi che si succederanno dal lancio del <strong>sito</strong>:<br />

- avvio del preloader del filmato <strong>in</strong>troduttivo<br />

- avviato il preloader (che <strong>in</strong> partenza è <strong>in</strong>visibile), viene verificato se il filmato è già completamente carico (e qu<strong>in</strong>di se<br />

è stato già visualizzato, dal momento che, <strong>per</strong> essere subito carico, deve risiedere nella cache del browser)


- se il filmato non è carico, il preloader diventa visibile e mostra i dati sul processo di caricamento. Term<strong>in</strong>ato il<br />

caricamento, viene avviato il filmato <strong>in</strong>troduttivo vero e proprio, alla cui f<strong>in</strong>e è presente <strong>un</strong> pulsante <strong>per</strong> entrare nella<br />

pag<strong>in</strong>a pr<strong>in</strong>cipale del <strong>sito</strong>.<br />

- se <strong>in</strong>vece il filmato risulta carico, viene eseguito <strong>un</strong> comando uguale a quello del tasto skip, e immediatamente<br />

richiamato il filmato pr<strong>in</strong>cipale<br />

Questo sistema è molto semplice, ma presenta <strong>un</strong> difetto: <strong>per</strong> f<strong>un</strong>zionare, l'<strong>in</strong>tro deve essere stata completamente<br />

caricata. Il che significa che se il visitatore, che accede <strong>per</strong> la prima volta al <strong>sito</strong>, "skippa" subito l'<strong>in</strong>tro, al successivo<br />

accesso ne vedrà nuovamente il caricamento. Tutto ciò si può evitare, se il primo controllo, a preloader <strong>in</strong>visibile, si<br />

basa su <strong>un</strong>a <strong>per</strong>centuale di bytes caricati <strong>in</strong>feriore a quella totale.<br />

Aggi<strong>un</strong>giamo alla libreria <strong>un</strong> movieclip che chiameremo preloader: nel primo layer <strong>in</strong> alto, <strong>in</strong>seriamo <strong>un</strong>a copia del<br />

tasto skip che abbiamo utilizzato nella scena pr<strong>in</strong>cipale. Nel secondo layer, <strong>un</strong>a semplice scritta "Caricamento <strong>in</strong>tro".<br />

Nel terzo layer, posizioniamo <strong>un</strong>'istanza del movieclip cornice importato da flash5.fla, di dimensioni 200x8.<br />

Nel layer sotto, <strong>un</strong> movieclip contenente <strong>un</strong> rettangolo delle stesse dimensioni della cornice: il movieclip, chiamato<br />

barraPreloader, avrà come nome di istanza barra, e <strong>un</strong> _xscale, settato tramite il pannello Transform, dello 0%.<br />

Nell'ultimo layer <strong>in</strong> basso, posizioniamo <strong>un</strong>'istanza del movieclip freccia3d, con nome di istanza freccia, alla quale<br />

associamo:<br />

// al caricamento del movieclip<br />

onClipEvent (load) {<br />

// settane l'alpha sullo 0<br />

_alpha = 0;<br />

}<br />

// ad ogni riproduzione del movieclip<br />

onClipEvent(enterFrame){<br />

// se la variabile "vai" è vera<br />

if(vai){<br />

// se l'alpha è m<strong>in</strong>ore di 30<br />

if(_alpha


loadMovieNum ("flash5.swf", 0);<br />

}else{<br />

carica = true;<br />

}<br />

}<br />

onClipEvent (enterFrame) {<br />

if (carica) {<br />

car = _root.getBytesLoaded();<br />

tot = _root.getBytesTotal();<br />

if (car == tot) {<br />

_root.gotoAndPlay(4);<br />

} else {<br />

_visible = 1;<br />

barra._xscale = Math.ro<strong>un</strong>d((car/tot)*100);<br />

}<br />

}<br />

}<br />

Vediamolo spiegato riga <strong>per</strong> riga:<br />

// al caricamento del movieclip<br />

onClipEvent (load) {<br />

// rendi questo movieclip <strong>in</strong>visibile<br />

_visible = 0;<br />

// ferma la riproduzione della timel<strong>in</strong>e pr<strong>in</strong>cipale<br />

_root.stop();<br />

// se i bytes caricati sono uguali a quelli totali<br />

// (il filmato è nella cache, qu<strong>in</strong>di già visto)<br />

if (_root.getBytesLoaded() == _root.getBytesTotal()) {<br />

// carica il filmato flash5.swf sul livello 0<br />

loadMovieNum ("flash5.swf", 0);<br />

// altrimenti<br />

}else{<br />

// setta la variabile "carica" come vera<br />

carica = true;<br />

}<br />

}<br />

// ad ogni riproduzione del movieclip<br />

onClipEvent (enterFrame) {<br />

// se la variabile "carica" è vera<br />

if (carica) {<br />

// assegna a "car" il numero di bytes caricati<br />

car = _root.getBytesLoaded();<br />

// assegna a "tot" il numero di bytes totali


tot = _root.getBytesTotal();<br />

// se "car" è uguale a "tot"<br />

if (car == tot) {<br />

// riprendi la riproduzione della timel<strong>in</strong>e pr<strong>in</strong>cipale<br />

// dal frame numero 4 (il primo della seconda scena)<br />

_root.gotoAndPlay(4);<br />

// altrimenti (ancora non caricato completamente)<br />

} else {<br />

// rendi il movieclip visibile<br />

_visible = 1;<br />

// scala il movieclip "barra" sull'arrotondamento<br />

// del valore di 100 <strong>per</strong> il quoto tra "car" e "tot"<br />

barra._xscale = Math.ro<strong>un</strong>d((car/tot)*100);<br />

}<br />

}<br />

}<br />

Il preloader<br />

Preloader<br />

Oltre al preloader <strong>per</strong> l'<strong>in</strong>tro, che abbiamo appena visto, nella costruzione del <strong>sito</strong> useremo altri due tipi di preloader:<br />

<strong>un</strong>o <strong>per</strong> tutti i filmati esterni tranne suono.swf, l'altro solo <strong>per</strong> il filmato pr<strong>in</strong>cipale, flash5.swf<br />

Primo preloader: filmati esterni<br />

I nostri filmati esterni vengono tutti caricati sul livello 1, <strong>un</strong>o alla volta: <strong>in</strong>fatti, al caricamento di <strong>un</strong> nuovo filmato,<br />

questo prende il posto di quello che occupava il livello precedentemente. Inoltre, dal momento che parliamo di<br />

caricamento su livelli, e non <strong>in</strong> movieclip, possiamo utilizzare il tipo di preloader più com<strong>un</strong>e, basato sul controllo dei<br />

bytes caricati e totali della _root. (riferimento al filmato <strong>in</strong> cui è presente lo script, <strong>in</strong> qual<strong>un</strong>que livello sia). Quando<br />

caricheremo <strong>un</strong>o dei filmati esterni, vedremo il preloader come se fosse nel filmato pr<strong>in</strong>cipale, <strong>in</strong> trasparenza sopra gli<br />

altri oggetti. Vediamone la costruzione, da effettuare <strong>in</strong> tutti i filmati tranne flash5.fla e suono.fla<br />

Innanzitutto, dobbiamo <strong>in</strong>serire il preloader <strong>un</strong> frame prima di quello pr<strong>in</strong>cipale (i filmati sono tutti composti da <strong>un</strong> solo<br />

frame): il metodo più semplice, <strong>per</strong> non dover spostare il frame su ogni livello, è quello di aggi<strong>un</strong>gere <strong>un</strong>a scena che<br />

preceda quella pr<strong>in</strong>cipale. Apriamo qu<strong>in</strong>di il nostro filmato, e andiamo al menu Modify/Scene (Elabora/Scene):<br />

nell'appo<strong>sito</strong> pannello, premiamo il pulsante con il simbolo + <strong>in</strong> basso a destra. Nel nostro filmato verrà aggi<strong>un</strong>ta <strong>un</strong>a<br />

scena dopo quella già esistente.


Cliccando sul nome della scena, la r<strong>in</strong>om<strong>in</strong>iamo <strong>in</strong> preloader, e la trasc<strong>in</strong>iamo sopra la prima.<br />

Ciò è necessario <strong>per</strong>ché, nella gerarchie delle scene, quella più sopra viene riprodotta prima di quelle sotto.<br />

Aggi<strong>un</strong>giamo alla libreria <strong>un</strong> nuovo movieclip, che chiameremo barraPreloader. All'<strong>in</strong>terno del movieclip,<br />

disegniamo <strong>un</strong> rettangolo bianco largo 60 pixel e alto 6, con l'angolo su<strong>per</strong>iore s<strong>in</strong>istro sul p<strong>un</strong>to di registrazione.<br />

Premiamo nuovamente il pulsante + nella libreria, e <strong>in</strong>seriamo <strong>un</strong> altro movieclip, che chiameremo preloader: conterrà<br />

tre layer di <strong>un</strong> frame ciasc<strong>un</strong>o, chiamati rispettivamente, dall'alto verso il basso, "cornice", "barra" e "testo".<br />

Nel layer "barra", trasc<strong>in</strong>iamo dalla libreria <strong>un</strong>'istanza del movieclip barraPreloader, alla quale daremo, come nome di<br />

istanza, barra. Selezioniamo la barra, e apriamo il pannello Transform: nel campo Width, <strong>in</strong>seriamo il valore più basso<br />

possibile (lo 0, che verrà trasformato <strong>in</strong> 0.8), riducendo la barra ad essere praticamente <strong>in</strong>visibile.<br />

Nel layer "cornice" trasc<strong>in</strong>iamo dalla libreria <strong>un</strong>'istanza del movieclip cornice, che posizioneremo, con le stesse<br />

dimensioni (60x6), proprio sopra la barra.<br />

Inf<strong>in</strong>e, nel layer "testo", <strong>in</strong>seriremo sopra la barra la scritta statica "caricamento <strong>in</strong> corso...", e accanto alla barra, <strong>un</strong><br />

campo di testo d<strong>in</strong>amico con associata la variabile <strong>per</strong>centuale. Visivamente, il risultato sarà questo:<br />

Torniamo alla timel<strong>in</strong>e pr<strong>in</strong>cipale, nell'<strong>un</strong>ico frame della scena "preloader". Dalla libreria, trasc<strong>in</strong>iamo sullo stage<br />

<strong>un</strong>'istanza del movieclip preloader, alla quale associamo:<br />

onClipEvent (load) {<br />

_visible = 0;<br />

_root.stop();<br />

}<br />

onClipEvent (enterFrame) {<br />

if (_root.getBytesLoaded() == _root.getBytesTotal()) {<br />

_root.nextFrame();<br />

}<br />

_visible = 1;<br />

<strong>per</strong>c = barra._xscale = Math.ro<strong>un</strong>d((_root.getBytesLoaded()/_root.getBytesTotal())*100);<br />

<strong>per</strong>centuale = <strong>per</strong>c + "%";<br />

}


All'avvio del filmato, il preloader è <strong>in</strong>visibile. Viene controllato se i bytes caricati del filmato <strong><strong>in</strong>tero</strong> sono uguali a quelli<br />

totali: se vero, il filmato passa al frame successivo, dove c'è l'animazione pr<strong>in</strong>cipale, altrimenti il preloader diventa<br />

visibile e mostra i dati di caricamento. Questo sistema serve ad evitare che, ai successivi caricamenti dello stesso<br />

filmato, si veda il preloader anche solo <strong>per</strong> <strong>un</strong> secondo. Spiegato riga <strong>per</strong> riga:<br />

// al caricamento del movieclip<br />

onClipEvent (load) {<br />

// settane la visibilità su 0<br />

_visible = 0;<br />

// ferma la riproduzione della timel<strong>in</strong>e pr<strong>in</strong>cipale<br />

_root.stop();<br />

}<br />

// ad ogni riproduzione del movieclip<br />

onClipEvent (enterFrame) {<br />

// se i bytes caricati del filmato, sono uguali a quelli totali<br />

if (_root.getBytesLoaded() == _root.getBytesTotal()) {<br />

// riprendi la riproduzione della timel<strong>in</strong>e pr<strong>in</strong>cipale, fermandola sul frame seguente<br />

_root.nextFrame();<br />

}<br />

// rendi il movieclip visibile<br />

_visible = 1;<br />

// assegna a "<strong>per</strong>c" lo stesso valore usato <strong>per</strong> scalare la barra, cioè l'arrotondamento<br />

// del quoto tra bytes caricati e totali moltiplicato <strong>per</strong> 100<br />

<strong>per</strong>c = barra._xscale = Math.ro<strong>un</strong>d((_root.getBytesLoaded()/_root.getBytesTotal())*100);<br />

// scrivi nel campo di testo "<strong>per</strong>centuale", il valore di "<strong>per</strong>c" più il simbolo "%"<br />

<strong>per</strong>centuale = <strong>per</strong>c + "%";<br />

}<br />

Il preloader è <strong>per</strong>fettamente identico <strong>in</strong> tutti i filmati.<br />

Secondo preloader: filmato pr<strong>in</strong>cipale<br />

Il preloader del filmato pr<strong>in</strong>cipale, oltre a non essere visibile nei caricamenti successivi, come quello dei filmati esterni,<br />

ha anche <strong>un</strong>'altra caratteristica: deve precaricare il filmato suono.swf. Quest'ultimo <strong>in</strong>fatti, dal momento che contiene <strong>un</strong><br />

suono l<strong>in</strong>kato, non può avere <strong>un</strong> preloader come gli altri filmati. <strong>Flash</strong>, nel caso di oggetti l<strong>in</strong>kati, pone questi <strong>in</strong> <strong>un</strong><br />

frame virtuale 0, prima di tutti gli altri: <strong>per</strong> questo motivo, è necessario che sia completo il caricamento degli oggetti<br />

l<strong>in</strong>kati prima che sia possibile vedere il preloader. Se poi l'oggetto l<strong>in</strong>kato è da 100k (tipicamente <strong>un</strong> suono di<br />

sottofondo), e il filmato stesso è da 10k, il preloader diventa assolutamente <strong>in</strong>utile.<br />

Com<strong>in</strong>ciamo con il preparare il filmato suono.swf <strong>per</strong> il preloader: apriamo suono.fla, e aggi<strong>un</strong>giamo <strong>un</strong>a nuova scena<br />

prima di quella già esistente. Nell'<strong>un</strong>ico frame, mettiamo <strong>un</strong>o stop, e salviamo.<br />

Apriamo flash5.fla e, come negli altri filmati, aggi<strong>un</strong>giamo <strong>un</strong>a scena prima di quella già esistente: <strong>in</strong> questa scena,<br />

creiamo tre layer, "preloader", "frecce", "sfondo", dall'alto verso il basso. Nel layer "sfondo", disegniamo <strong>un</strong> rettangolo<br />

grande quanto l'<strong><strong>in</strong>tero</strong> filmato, e riempito con <strong>un</strong> gradiente che richiami quello della fascia centrale della scena seguente.<br />

Nel layer "frecce", trasc<strong>in</strong>iamo dalla libreria tre istanze del movieclip clip, posizioniate appena al di fuori della s<strong>in</strong>istra


dello stage, con altezza, colore, e trasparenza diversa. Alle tre frecce diamo, come nome di istanza, freccia1, freccia2,<br />

freccia3, e associamo a ciasc<strong>un</strong>a il seguente script:<br />

onClipEvent (load) {<br />

f<strong>in</strong>e = 1000;<br />

frame = 40:<br />

}<br />

onClipEvent (enterFrame) {<br />

if(vai){<br />

<strong>in</strong>izio = _x;<br />

_x += (f<strong>in</strong>e-_x)/frame;<br />

if(_x > 980){<br />

_x = -20;<br />

}<br />

}<br />

}<br />

Nuovamente si tratta del moto decelerato: le frecce si sposteranno, se la variabile "vai" è vera, attraversando tutto lo<br />

stage: quando <strong>per</strong>ò la loro posizione sull'asse delle X su<strong>per</strong>erà il valore di 980 (quello f<strong>in</strong>ale è 1000), torneranno al<br />

p<strong>un</strong>to di partenza, ricom<strong>in</strong>ciando lo spostamento. L'<strong>un</strong>ico valore da cambiare da freccia a freccia, è quello della<br />

variabile frame, che determ<strong>in</strong>a la velocità di spostamento.<br />

// al caricamento del movieclip<br />

onClipEvent (load) {<br />

// attribuisci alla variabile "f<strong>in</strong>e" il valore 1000<br />

f<strong>in</strong>e = 1000;<br />

// attribuisci alla variabile "frame" il valore 40<br />

frame = 40;<br />

}<br />

// ad ogni riproduzione del movieclip<br />

onClipEvent (enterFrame) {<br />

// se la variabile "vai" è vera<br />

if(vai){<br />

// attribuisci alla variabile "<strong>in</strong>izio" il valore<br />

// dell'attuale posizione del movieclip sull'asse delle X<br />

<strong>in</strong>izio = _x;<br />

// moto decelerato<br />

_x += (f<strong>in</strong>e-_x)/frame;<br />

// se la posizione del movieclip è su<strong>per</strong>iore a 980<br />

if(_x > 980){<br />

// riporta il movieclip alla posizione -20 sull'asse delle X<br />

_x = -20;<br />

}<br />

}<br />

}


Aggi<strong>un</strong>giamo alla libreria <strong>un</strong> movieclip che chiameremo barraPreloader, contenente <strong>un</strong> rettangolo 200x8 con l'angolo<br />

su<strong>per</strong>iore s<strong>in</strong>istro sul p<strong>un</strong>to di registrazione. Aggi<strong>un</strong>giamo <strong>in</strong>f<strong>in</strong>e alla libreria, <strong>un</strong> ultimo movieclip che chiameremo<br />

preloader, al cui <strong>in</strong>terno creiamo tre layer.<br />

Nel primo layer, che chiameremo "scritte", <strong>in</strong>seriamo due campo di testo statici, "caricamento grafica" e "caricamento<br />

audio". Nel layer sotto, "cornici", trasc<strong>in</strong>iamo dalla libreria due istanze del movieclip cornice, che ridimensioneremo a<br />

200x8. Nel layer "barre", <strong>in</strong>seriamo due istanze del movieclip barraPreloader: le posizioniamo sotto le due cornici, le<br />

scaliamo a 0 <strong>in</strong> larghezza, e le chiamiamo barra1 e barra2.<br />

Nel layer "preloader" della prima scena del filmato, trasc<strong>in</strong>iamo dalla libreria <strong>un</strong>'istanza del movieclip preloader, alla<br />

quale associamo:<br />

onClipEvent (load) {<br />

_visible = 0;<br />

loadMovieNum ("suono.swf", 10);<br />

_root.stop();<br />

}<br />

onClipEvent (enterFrame) {<br />

car0 = _root.getBytesLoaded();<br />

tot0 = _root.getBytesTotal();<br />

car10 = _level10.getBytesLoaded();<br />

tot10 = _level10.getBytesTotal();<br />

if (_level10._url != null) {<br />

if (car0 == tot0 && car10 == tot10) {<br />

_level10.nextFrame();<br />

_root.nextFrame();<br />

} else {<br />

_parent.freccia1.vai = _parent.freccia2.vai = _parent.freccia3.vai = true;<br />

_visible = 1;<br />

barra1._xscale = Math.ro<strong>un</strong>d((car0/tot0)*100);<br />

barra2._xscale = Math.ro<strong>un</strong>d((car10/tot10)*100);<br />

}<br />

}<br />

}<br />

Il preloader, all'avvio del filmato, è <strong>in</strong>visibile: viene caricato il filmato suono.swf sul livello 10, e fermata la<br />

riproduzione della timel<strong>in</strong>e pr<strong>in</strong>cipale. Ad ogni riproduzione del movieclip, vengono stabiliti i dati di caricamento di<br />

entrambi i filmati: quando sono carichi, ne viene avviata la riproduzione. Nel frattempo, vengono visualizzati i dati di<br />

caricamento, dopo che il preloader è stato reso visibile.<br />

// al caricamento del movieclip<br />

onClipEvent (load) {<br />

// rendi <strong>in</strong>visibile il movieclip


_visible = 0;<br />

// carica il filmato "suono.swf" sul livello 10<br />

loadMovieNum ("suono.swf", 10);<br />

// <strong>in</strong>terrompi la riproduzione della timel<strong>in</strong>e pr<strong>in</strong>cipale<br />

_root.stop();<br />

}<br />

// ad ogni riproduzione del movieclip<br />

onClipEvent (enterFrame) {<br />

// assegna a "car0" il numero di bytes caricati del filmato pr<strong>in</strong>cipale<br />

car0 = _root.getBytesLoaded();<br />

// assegna a "tot0" il numero di bytes totali del filmato pr<strong>in</strong>cipale<br />

tot0 = _root.getBytesTotal();<br />

// assegna a "car10" il numero di bytes caricati del filmato suono.swf<br />

car10 = _level10.getBytesLoaded();<br />

// assegna a "tot10" il numero di bytes totali del filmato suono.swf<br />

tot10 = _level10.getBytesTotal();<br />

// se l'url del livello 10 non è nulla (qu<strong>in</strong>di è <strong>in</strong>iziato il caricamento)<br />

if (_level10._url != null) {<br />

// se "car0" è uguale a "tot0" e "car10" è uguale a "tot10"<br />

if (car0 == tot0 && car10 == tot10) {<br />

// riprendi la riproduzione del livello 10 fermandola sul frame seguente<br />

_level10.nextFrame();<br />

// riprendi la riproduzione del filmato fermandola sul frame seguente<br />

_root.nextFrame();<br />

// altrimenti<br />

} else {<br />

// setta la variabile "vai" come vera sulle tre frecce<br />

_parent.freccia1.vai = _parent.freccia2.vai = _parent.freccia3.vai = true;<br />

// rendi il movieclip visibile<br />

_visible = 1;<br />

// scala la barra1 sul valore di "car0" fratto "tot0" moltiplicato <strong>per</strong> 100<br />

barra1._xscale = Math.ro<strong>un</strong>d((car0/tot0)*100);<br />

// scala la barra2 sul valore di "car10" fratto "tot10" moltiplicato <strong>per</strong> 100<br />

barra2._xscale = Math.ro<strong>un</strong>d((car10/tot10)*100);<br />

}<br />

}<br />

}<br />

Index.htm<br />

Premessa<br />

Prima di cont<strong>in</strong>uare, <strong>un</strong> app<strong>un</strong>to sui <strong>per</strong>corsi dei file. Costruendo <strong>un</strong> <strong>sito</strong>, la cosa migliore da fare è usare dei l<strong>in</strong>k relativi,<br />

f<strong>in</strong> dove è possibile: <strong>in</strong> questo modo, il f<strong>un</strong>zionamento sarà sempre lo stesso <strong>in</strong>dipendentemente dalla posizione <strong>in</strong> cui lo<br />

si metta, sia esso sulla propria macch<strong>in</strong>a, o sul proprio spazio web.


Per questione di ord<strong>in</strong>e, ho <strong>in</strong>serito tutti i filmati <strong>in</strong> <strong>un</strong>'<strong>un</strong>ica cartella, nom<strong>in</strong>ata "filmati", e i file txt <strong>in</strong> <strong>un</strong>a nom<strong>in</strong>ata<br />

"testi". La pag<strong>in</strong>a html che contiene il filmato pr<strong>in</strong>cipale è esterna alle due cartelle, e nel codice di <strong>in</strong>corporamento,<br />

qu<strong>in</strong>di, non farà riferimento a<br />

flash5.swf<br />

bensì a<br />

filmati/flash5.swf<br />

Una volta caricato il filmato, quest'ultimo, <strong>per</strong> recu<strong>per</strong>are gli altri filmati e i testi, dovrà fare riferimento alla nuova<br />

posizione ass<strong>un</strong>ta, cioè dentro <strong>un</strong>a pag<strong>in</strong>a html fuori dalle due cartelle. Il che significa che se anche i filmati sono nella<br />

stessa posizione, i comandi vi faranno riferimento non con<br />

loadMovieNum("filmato.swf, 1);<br />

ma con<br />

loadMovieNum("filmati/filmato.swf", 1);<br />

e ai testi con<br />

loadVariables("testi/actionscript.txt", 1);<br />

E' necessario qu<strong>in</strong>di, rispetto agli script che abbiamo visto f<strong>in</strong>o ad adesso, cambiare i <strong>per</strong>corsi dei file <strong>per</strong> rispettare<br />

questo schema.<br />

Costruzione<br />

Introduzione<br />

Term<strong>in</strong>ata la parte <strong>in</strong> <strong>Flash</strong>, dobbiamo adesso occuparci necessariamente dell'html: dobbiamo <strong>in</strong>fatti <strong>creare</strong> le basi <strong>per</strong><br />

poter rendere il <strong>sito</strong> accessibile.<br />

Con il comando Pubblica (Shift+F12), vengono generati <strong>un</strong>a pag<strong>in</strong>a html contenente il filmato e il filmato stesso: questi<br />

due file sarebbero già sufficienti <strong>per</strong> la pubblicazione, ma offrono <strong>un</strong> tipo di visualizzazione troppo standardizzata.<br />

Riprendiamo qu<strong>in</strong>di i propositi di <strong>in</strong>izio guida, e cerchiamo di rispettarli tutti.<br />

Scelta <strong>in</strong> entrata<br />

Innanzitutto al navigatore, <strong>un</strong>a volta arrivato alla pag<strong>in</strong>a pr<strong>in</strong>cipale del <strong>sito</strong>, lasciamo la possibilità di scegliere cosa fare:<br />

se accedere alla versione creata con <strong>Flash</strong>, o a quella creata <strong>in</strong> HTML, o se <strong>in</strong>vece scaricare il plug<strong>in</strong>. La pag<strong>in</strong>a<br />

<strong>in</strong>dex.htm, qu<strong>in</strong>di, conterrà dei collegamenti legati ad immag<strong>in</strong>i esplicative, premendo le quali si o<strong>per</strong>erà la scelta.<br />

Cliccando sullo scaricamento del plug<strong>in</strong>, apriremo <strong>un</strong>a popup il cui contenuto sarà la pag<strong>in</strong>a di download dello stesso,<br />

presso il <strong>sito</strong> della Macromedia. Cliccando su "versione HTML", la pag<strong>in</strong>a di <strong>Flash</strong>5.it verrà caricata all'<strong>in</strong>terno della<br />

f<strong>in</strong>estra.<br />

Cliccando su "versione FLASH", all'<strong>in</strong>terno della f<strong>in</strong>estra caricheremo la pag<strong>in</strong>a detect.htm, che contiene il <strong>Flash</strong><br />

Dispatcher della Macromedia <strong>per</strong> il controllo del plug<strong>in</strong>. Se il controllo risulterà positivo, verrà caricata <strong>un</strong>a pag<strong>in</strong>a html<br />

base che lancia <strong>in</strong> popup la f<strong>in</strong>estra con il filmato: alla base di questa pag<strong>in</strong>a html, ci sarà la possibilità di rilanciare la<br />

popup, e di tornare alla pag<strong>in</strong>a pr<strong>in</strong>cipale.<br />

Qualora <strong>in</strong>vece il controllo risultasse negativo, caricheremo la pag<strong>in</strong>a noflash.htm, contenente <strong>un</strong> messaggio <strong>per</strong> il<br />

navigatore. Questi avrà di nuovo tre possibilità: aprire <strong>in</strong> popup la pag<strong>in</strong>a di download della Macromedia, tornare alla<br />

pag<strong>in</strong>a pr<strong>in</strong>cipale del <strong>sito</strong> (<strong>in</strong>dex.htm), oppure lanciare com<strong>un</strong>que la pag<strong>in</strong>a contenente <strong>in</strong>tro.swf, nel caso il controllo<br />

fosse stato impreciso.<br />

<strong>in</strong>dex.htm


Partiamo dalla pag<strong>in</strong>a <strong>in</strong>dex.htm. Questa sarà composta da <strong>un</strong>a tabella centrata con dimensioni al 100%, contenente, <strong>un</strong>a<br />

sotto l'altra, le immag<strong>in</strong>i <strong>per</strong> le scelte.<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

Inoltre, aggi<strong>un</strong>geremo sotto queste altre due immag<strong>in</strong>i <strong>per</strong> <strong>in</strong>serire la pag<strong>in</strong>a tra i Preferiti, o impostarla come Pag<strong>in</strong>a<br />

Pr<strong>in</strong>cipale del browser (solo <strong>per</strong> IE). Queste immag<strong>in</strong>i, richiameranno delle f<strong>un</strong>zioni <strong>in</strong> javascript che sono contenute <strong>in</strong><br />

<strong>un</strong> file *.js esterno: il riferimento al file *.js, è da <strong>in</strong>serire all'<strong>in</strong>izio della pag<strong>in</strong>a, all'<strong>in</strong>terno dei tag . La pag<strong>in</strong>a<br />

completa sarà:<br />

<br />

<br />

<strong>Flash</strong>5.it<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />


<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

L'a<strong>per</strong>tura della pag<strong>in</strong>a sul <strong>sito</strong> della Macromedia, <strong>per</strong> lo scaricamento del plug<strong>in</strong>, si effettua con <strong>un</strong> semplice richiamo<br />

della pag<strong>in</strong>a <strong>in</strong> <strong>un</strong> target _blank, cioè <strong>in</strong> <strong>un</strong>a nuova f<strong>in</strong>estra. Il richiamo alla pag<strong>in</strong>a <strong>in</strong> html (http://flash5.html.it/), e alla<br />

pag<strong>in</strong>a <strong>in</strong> flash avviene <strong>in</strong>vece tramite il richiamo della pag<strong>in</strong>a <strong>in</strong> <strong>un</strong> target _self, all'<strong>in</strong>terno cioè della stessa f<strong>in</strong>estra.<br />

Noi vedremo quest'ultimo caso.<br />

Detect<br />

Se il navigatore, nella pag<strong>in</strong>a <strong>in</strong>dex.htm, sceglie di visualizzare la versione <strong>Flash</strong> del <strong>sito</strong>, verrà <strong>in</strong>dirizzato alla pag<strong>in</strong>a<br />

detect.htm. Questa pag<strong>in</strong>a, effettuerà <strong>un</strong> controllo sul plug<strong>in</strong>, e re<strong>in</strong>derizzerà il navigatore a seconda del risultato (può<br />

darsi che l'utente creda di avere il plug<strong>in</strong>, ma non ce l'abbia: <strong>per</strong> questo effettuiamo il controllo).<br />

La pag<strong>in</strong>a detect.htm è costruita sulla base del Macromedia <strong>Flash</strong> Dispatcher: si tratta di <strong>un</strong> kit composto da <strong>un</strong> file<br />

Jscript, da <strong>un</strong>o script Vb e <strong>un</strong> filmato swf, che con <strong>un</strong>a serie di procedure e controlli, verificano nel browser la presenza<br />

o meno del plug<strong>in</strong>. Nell'eventualità esso sia presente, stabilisce il numero di versione, <strong>per</strong>mettendo di scegliere cosa fare<br />

nei vari casi.<br />

Innanzitutto, scarichiamo dal <strong>sito</strong> della Macromedia i file del <strong>Flash</strong> Deployment kit. Estraiamo il contenuto del file *.zip<br />

<strong>in</strong> <strong>un</strong>a cartella temporanea, ed entriamo nella cartella flash_deploy_kit\<strong>Flash</strong>_Deployment_Kit\<strong>Flash</strong>_Deployment_kit e<br />

da questa cartella preleviamo solo i file che ci servono:<br />

• detect<strong>Flash</strong>.swf<br />

• Dispatcher.js<br />

• Dispatcher.vbs<br />

• enter.htm (che r<strong>in</strong>om<strong>in</strong>iamo <strong>in</strong> detect.htm)<br />

e li mettiamo nella cartella che contiene <strong>in</strong>dex.htm e le sottocartelle con i filmati, i testi e le immag<strong>in</strong>i <strong>per</strong> le pag<strong>in</strong>e html.


L'<strong>un</strong>ico file da modificare è detect.htm, <strong>per</strong> adattarlo alle nostre esigenze. Il contenuto si presenta così (ho tradotto i<br />

commenti):<br />

<br />

<br />

detect plug<strong>in</strong><br />

<br />

<br />

<br />

<br />

<br />

<br />

// Cambia i parametri <strong>in</strong> questa f<strong>un</strong>zione <strong>per</strong> <strong>in</strong>dirizzare l'utente<br />

// alla pag<strong>in</strong>a appropriata<br />

MM_<strong>Flash</strong>Dispatch(<br />

);<br />

"flash/<strong>in</strong>dex.html", // pag<strong>in</strong>a <strong>in</strong> caso il plug<strong>in</strong> sia presente e nella giusta versione<br />

"5.0", // versione richiesta<br />

false, // richiesta dell'ultima versione (vero o falso)<br />

"upgrade<strong>Flash</strong>.html", // pag<strong>in</strong>a <strong>per</strong> l'upgrade del plug<strong>in</strong><br />

!MM_<strong>Flash</strong>UserDemurred(), // <strong>in</strong>stallazione (vero o falso)<br />

"<strong>in</strong>stall<strong>Flash</strong>.html", // pag<strong>in</strong>a <strong>per</strong> l'<strong>in</strong>stallazione<br />

"noflash/<strong>in</strong>dex.html", // pag<strong>in</strong>a con contenuto alternativo<br />

false // <strong>in</strong>serimento del Plug<strong>in</strong>sPage <strong>in</strong> caso sia necessario usare detect<strong>Flash</strong>.swf<br />

<br />

<br />

<br />

La cambiamo così:<br />

<br />

<br />

detect plug<strong>in</strong><br />

<br />

<br />

<br />

<br />

<br />

<br />

MM_<strong>Flash</strong>Dispatch(<br />

"flash.htm", // contentURL<br />

"5.0", // contentVersion<br />

false, // requireLatestRevision<br />

"noflash.htm", // upgradeURL<br />

MM_<strong>Flash</strong>UserDemurred(), // <strong>in</strong>stall


"noflash.htm", // <strong>in</strong>stallURL<br />

);<br />

"noflash.htm", // altURL<br />

false // overridePlug<strong>in</strong>sPage<br />

<br />

<br />

<br />

La URL da raggi<strong>un</strong>gere, <strong>in</strong> caso sia presente il plug<strong>in</strong> nella versione richiesta, è la pag<strong>in</strong>a flash.htm. La versione<br />

richiesta del plug<strong>in</strong> è la 5.0, e non ne è richiesta l'ultima versione.<br />

In caso il plug<strong>in</strong> non sia presente nella versione adatta, o non sia presente del tutto, non ne viene richiesta l'<strong>in</strong>stallazione<br />

(bisogna togliere il simbolo "!" prima di MM_<strong>Flash</strong>UserDemurred()), e il navigatore viene re<strong>in</strong>dirizzato alla pag<strong>in</strong>a<br />

noflash.htm.<br />

Se lasciassimo la richiesta di <strong>in</strong>stallazione del plug<strong>in</strong>, <strong>in</strong> caso l'utente non lo avesse, verrebbe re<strong>in</strong>dirizzato com<strong>un</strong>que a<br />

flash.htm, e <strong>in</strong>izierebbe lo scaricamento automatico: questa è <strong>un</strong>a cosa che vogliamo evitare, dal momento che la<br />

maggior parte degli utenti, all'a<strong>per</strong>tura non espressamente richiesta di <strong>un</strong>a f<strong>in</strong>estrella che chiede di scaricare qualcosa,<br />

preme "Annulla". Quello che faremo noi, <strong>in</strong>vece, è rimandare ad <strong>un</strong>a pag<strong>in</strong>a che consiglia di andare a quella di<br />

download della Macromedia: lasciando qu<strong>in</strong>di all'utente il pieno controllo della situazione.<br />

Non ci resta ora che cambiare l'aspetto della pag<strong>in</strong>a di detect, cambiandone il colore di sfondo, e <strong>in</strong>serendo <strong>un</strong>a tabella<br />

centrata con l'immag<strong>in</strong>e "controllo plug<strong>in</strong> <strong>in</strong> corso".<br />

<br />

<br />

detect plug<strong>in</strong><br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

MM_<strong>Flash</strong>Dispatch(<br />

&quot;flash.htm&quot;, // contentURL<br />

&quot;5.0&quot;, // contentVersion<br />

false, // requireLatestRevision<br />

&quot;noflash.htm&quot;, // upgradeURL<br />

MM_<strong>Flash</strong>UserDemurred(), // <strong>in</strong>stall


&quot;noflash.htm&quot;, // <strong>in</strong>stallURL<br />

);<br />

&quot;noflash.htm&quot;, // altURL<br />

false // overridePlug<strong>in</strong>sPage<br />

<br />

<br />

<br />

Scelte<br />

flash.htm<br />

Abbiamo visto come, <strong>in</strong> caso il plug<strong>in</strong> sia presente nella versione corretta e adatta al contenuto, l'utente venga<br />

re<strong>in</strong>dirizzato alla pag<strong>in</strong>a flash.htm<br />

Costruiamo ora questa pag<strong>in</strong>a.<br />

Costruzione<br />

Creiamo <strong>un</strong> nuovo documento html con <strong>un</strong> qualsiasi editor testuale. All'<strong>in</strong>terno della pag<strong>in</strong>a, <strong>in</strong>seriamo <strong>un</strong>a tabella<br />

centrata contenente <strong>un</strong>'immag<strong>in</strong>e cliccabile, che l'utente si troverà davanti qualora chiuda la popup lanciata <strong>in</strong><br />

automatico all'accesso alla pag<strong>in</strong>a: il l<strong>in</strong>k servirà a lanciare di nuovo la popup, mentre <strong>un</strong>'altra immag<strong>in</strong>e cliccabile<br />

conduce l'utente a <strong>in</strong>dex.html<br />

<br />

<br />

::flash5.it::<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

Analizziamo la struttura della pag<strong>in</strong>a. Innanzitutto, si chiama ::flash5.it::, nome che apparirà nell'icona sulla barra degli<br />

strumenti, ed esiste <strong>un</strong> riferimento al file JScript esterno flash5.js. Il colore della pag<strong>in</strong>a nero, i bordi sono azzerati e non<br />

c'è barra di scorrimento: all'avvio, vengono richiamate le f<strong>un</strong>zioni javascript riempi() e lancia(). Nel corpo della pag<strong>in</strong>a,


c'è la tabella centrata contenente le due immag<strong>in</strong>i cliccabili: la prima richiama la f<strong>un</strong>zione lancia(), la seconda manda<br />

<strong>in</strong>dietro il browser di due passi nella cronologia, tornando qu<strong>in</strong>di a <strong>in</strong>dex.htm<br />

noflash.htm<br />

Qualora non sia presente il plug<strong>in</strong>, il navigatore verrà re<strong>in</strong>dirizzato alla pag<strong>in</strong>a noflash.htm: <strong>in</strong> questa pag<strong>in</strong>a, come <strong>in</strong><br />

quella appena vista, abbiamo <strong>un</strong>a tabella centrata contenente delle immag<strong>in</strong>i cliccabili, più <strong>un</strong> messaggio <strong>per</strong> l'utente.<br />

Il messaggio avverte l'utente che, dal controllo, risulta sprovvisto del plug<strong>in</strong>. Qu<strong>in</strong>di si offrono tre scelte: tornare alla<br />

pag<strong>in</strong>a <strong>in</strong>dex.htm, aprire <strong>un</strong>a popup <strong>per</strong> raggi<strong>un</strong>gere la pag<strong>in</strong>a di download della Macromedia, lanciare lo stesso la<br />

versione <strong>in</strong> <strong>Flash</strong> (nel caso <strong>in</strong> cui l'utente sia certo di avere la versione corretta del plug<strong>in</strong>, e che qu<strong>in</strong>di il controllo non<br />

sia stato efficiente).<br />

<br />

<br />

::flash5.it::<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

<br />

Analizziamo la struttura della pag<strong>in</strong>a. Innanzitutto, si chiama ::flash5.it:: come la precedente, e ha <strong>un</strong> riferimento allo<br />

stesso file JScript esterno. Il colore della pag<strong>in</strong>a è nero, i bordi sono azzerati e non c'è barra di scorrimento: <strong>in</strong>oltre,<br />

all'avvio, viene richiamata la f<strong>un</strong>zione riempi(). Nel corpo della pag<strong>in</strong>a, c'è la tabella centrata contenente le tre<br />

immag<strong>in</strong>i cliccabili: la prima richiama la f<strong>un</strong>zione lancia(), la seconda manda <strong>in</strong>dietro il browser di due passi nella<br />

cronologia, tornando qu<strong>in</strong>di a <strong>in</strong>dex.htm. La terza apre <strong>in</strong> popup la pag<strong>in</strong>a di download della Macromedia.


flash5.htm<br />

Eccoci f<strong>in</strong>almente alla pag<strong>in</strong>a fondamentale del <strong>sito</strong>, quella lanciata come popup quando si accede a flash.htm. La<br />

pag<strong>in</strong>a è <strong>un</strong> frameset composto da due frame: <strong>un</strong>o al 100%, occupato dalla pag<strong>in</strong>a ma<strong>in</strong>.htm che <strong>in</strong>corpora <strong>in</strong>tro.swf, e<br />

<strong>un</strong>o allo 0% occupato dalla pag<strong>in</strong>a vuota.htm (vuota di nome e di fatto).<br />

Il sistema del frameset è necessario <strong>per</strong> elim<strong>in</strong>are i bordi che si presentano attorno al filmato: con la str<strong>in</strong>ga<br />

marg<strong>in</strong>width="0" marg<strong>in</strong>height="0" topmarg<strong>in</strong>="0" leftmarg<strong>in</strong>="0"<br />

<strong>in</strong>serita nel body di ma<strong>in</strong>.htm (la pag<strong>in</strong>a che <strong>in</strong>corpora il filmato), elim<strong>in</strong>iamo i bordi <strong>per</strong> Microsoft Internet Explorer.<br />

Invece, <strong>in</strong> Netscape Navigator, i bordi <strong>in</strong>feriore e destro cont<strong>in</strong>uano ad essere visibili. Con il frameset, questi<br />

scompaiono.<br />

flash5.htm<br />

<br />

<br />

::flash5.it::<br />

<br />

<br />

<br />

<br />

<br />

<br />

Il tuo browser non supporta i frame e questa pag<strong>in</strong>a ne fa uso.<br />

<br />

<br />

vuota.htm<br />

<br />

<br />

::flash5.it::<br />

<br />

<br />

<br />

<br />

ma<strong>in</strong>.htm<br />

<br />

<br />

::flash5.it::<br />

<br />

<br />


var dim = screen.width;<br />

if(dim >= "1280"){<br />

larghezza = 1050;<br />

altezza = 450;<br />

}else{<br />

larghezza = 700;<br />

altezza = 300;<br />

}<br />

document.write (' '<br />

+' '<br />

+' '<br />

+' '<br />

+' '<br />

+' '<br />

+'');<br />

<br />

<br />

<br />

Javascript<br />

Vediamo il significato del javascript contenuto nella pag<strong>in</strong>a ma<strong>in</strong>.htm.<br />

<br />

var dim = screen.width;<br />

if(dim >= "1280"){<br />

larghezza = 1050;<br />

altezza = 450;<br />

}else{<br />

larghezza = 700;<br />

altezza = 300;<br />

}<br />

document.write (' '<br />

+' '<br />

+' '<br />

+' '<br />

+' '


+' '<br />

+'');<br />

<br />

Quando viene richiamata la pag<strong>in</strong>a, lo script recu<strong>per</strong>a la larghezza dello schermo (più precisamente, il numero di pixel<br />

che ne compongono orizzontalmente l'area visibile). Se questa misura, associata alla variabile dim, risulta essere<br />

maggiore o uguale a 1280, vengono def<strong>in</strong>ite le variabili larghezza e altezza, con i valori rispettivamente di 1050 e 450<br />

(rapporto 7 a 3).<br />

Se la larghezza dello schermo è <strong>in</strong>vece m<strong>in</strong>ore di 1280 (else), le variabili larghezza e altezza avranno come valore 700<br />

e 300 (a 1600x1200, <strong>un</strong> filmato 700x300 è troppo piccolo).<br />

Una volta def<strong>in</strong>ite le due variabili, viene scritto (tramite il document.write), il codice di <strong>in</strong>corporamento del filmato: le<br />

due variabili vengono riportate all'<strong>in</strong>terno di esso, e <strong>in</strong>serite nei posti corrispondenti agli attributi width ed height. Di<br />

conseguenza, all'<strong>in</strong>terno della popup, troveremo <strong>un</strong> filmato a dimensioni fisse (non scalabile): dimensioni che, <strong>per</strong>ò,<br />

saranno state stabilite al momento, relative al caso particolare.<br />

jscript esterno<br />

Come abbiamo visto, all'<strong>in</strong>terno del codice di alc<strong>un</strong>e delle pag<strong>in</strong>e considerate f<strong>in</strong>ora, era presente il riferimento ad <strong>un</strong><br />

file *.js esterno, flash5.js:<br />

<br />

Grazie a questo riferimento, è possibile richiamare f<strong>un</strong>zioni javascript non presenti nella pag<strong>in</strong>a html vera e propria:<br />

caso che abbiamo visto più volte, come nell'a<strong>per</strong>tura della popup, o dell'aggi<strong>un</strong>ta ai preferiti.<br />

Riporto il contenuto del file:<br />

/****************************************<br />

* <strong>Flash</strong>5.it http://flash5.html.it/<br />

* Guida <strong>per</strong> la costruzione di <strong>un</strong> <strong>sito</strong> <strong>in</strong> Macromedia <strong>Flash</strong>5<br />

*<br />

* negatyve@libero.it<br />

****************************************/<br />

f<strong>un</strong>ction riempi() {<br />

if (w<strong>in</strong>dow.screen) {<br />

var w = screen.availWidth;<br />

var h = screen.availHeight;<br />

w<strong>in</strong>dow.moveTo(0, 0);<br />

w<strong>in</strong>dow.resizeTo(w, h);<br />

}<br />

}<br />

f<strong>un</strong>ction lancia() {<br />

var w = screen.width;<br />

var h = screen.height;


if(w >= "1280"){<br />

larghezza = 1050;<br />

altezza = 450;<br />

}else{<br />

larghezza = 700;<br />

altezza = 300;<br />

}<br />

var x = Math.ro<strong>un</strong>d(w / 2) - Math.ro<strong>un</strong>d(larghezza / 2);<br />

var y = Math.ro<strong>un</strong>d(h / 2) - Math.ro<strong>un</strong>d(altezza / 2);<br />

f<strong>in</strong>estra = w<strong>in</strong>dow.open ('flash5.htm', null, 'left=' + x + ',screenX=' + x + ',top='<br />

+ y + 'screenY=' + y +',width=' + larghezza + ',height=' + altezza );<br />

}<br />

f<strong>un</strong>ction preferiti(){<br />

var url="http://flash5.html.it/"<br />

var titolo="<strong>Flash</strong>5.it - Risorse italiane su <strong>Flash</strong>"<br />

if (document.all) {<br />

w<strong>in</strong>dow.external.AddFavorite(url,titolo);<br />

}<br />

}<br />

f<strong>un</strong>ction pag<strong>in</strong>aIniziale() {<br />

document.body.style.behavior='url(#default#homepage)';<br />

document.body.setHomePage('http://flash5.html.it/');<br />

}<br />

La f<strong>un</strong>zione riempi, determ<strong>in</strong>a le dimensioni dell'area utile dello schermo (barre degli strumenti escluse): qu<strong>in</strong>di sposta<br />

la pag<strong>in</strong>a al p<strong>un</strong>to 0,0 (angolo su<strong>per</strong>iore s<strong>in</strong>istro dello schermo), e la ridimensiona f<strong>in</strong>o a riempire l'area visibile.<br />

La f<strong>un</strong>zione lancia, fa più o meno lo stesso lavoro della f<strong>un</strong>zione di ma<strong>in</strong>.htm: viene calcolata la larghezza dello<br />

schermo, e <strong>in</strong> base a questa, stabilite le dimensioni che dovrà avere la popup, centrata nello schermo e senza alc<strong>un</strong>a<br />

barra degli strumenti. Dal momento che i valori sono gli stessi dello script visto prima, se la risoluzione è <strong>in</strong>feriore a<br />

1280, avremo <strong>un</strong>a popup 700x300 contenente <strong>un</strong> filmato 700x300, se è su<strong>per</strong>iore, <strong>un</strong>a popup 1050x450 che <strong>in</strong>corpora<br />

<strong>un</strong> filmato 1050x450.<br />

La f<strong>un</strong>zione preferiti, aggi<strong>un</strong>ge il <strong>sito</strong> alla lista dei Preferiti o Bookmark, con le <strong>in</strong>formazioni (<strong>in</strong>dirizzo e nome)<br />

def<strong>in</strong>ite nella variabili url e titolo.<br />

Inf<strong>in</strong>e la f<strong>un</strong>zione pag<strong>in</strong>aIniziale, setta la la pag<strong>in</strong>a corrente come quella Iniziale del browser: questo script, è valido<br />

solo <strong>per</strong> i browser <strong>in</strong>ternet Explorer 4 e su<strong>per</strong>iori.<br />

/****************************************<br />

* <strong>Flash</strong>5.it http://flash5.html.it/<br />

* Guida <strong>per</strong> la costruzione di <strong>un</strong> <strong>sito</strong> <strong>in</strong> Macromedia <strong>Flash</strong>5<br />

*<br />

* negatyve@libero.it<br />

****************************************/<br />

f<strong>un</strong>ction riempi() {<br />

if (w<strong>in</strong>dow.screen) {


assegna a w il valore corrispondente alla larghezza disponibile dello schermo <strong>in</strong> px<br />

var w = screen.availWidth;<br />

// assegna a h il valore corrispondente all'altezza disponibile dello schermo <strong>in</strong> px<br />

var h = screen.availHeight;<br />

// sposta la f<strong>in</strong>estra nel p<strong>un</strong>to di coord<strong>in</strong>ate 0,0<br />

w<strong>in</strong>dow.moveTo(0, 0);<br />

// ridimensiona la f<strong>in</strong>estra f<strong>in</strong>o a riempire l'area visibile, determ<strong>in</strong>ata da w e h<br />

w<strong>in</strong>dow.resizeTo(w, h);<br />

}<br />

}<br />

f<strong>un</strong>ction lancia() {<br />

// assegna a "w" il valore corrispondente alla larghezza disponibile dello schermo <strong>in</strong> px<br />

var w = screen.width;<br />

// assegna a "h" il valore corrispondente all'altezza disponibile dello schermo <strong>in</strong> px<br />

var h = screen.height;<br />

// se "w" è maggiore o uguale a 1280<br />

if(w >= "1280"){<br />

// assegna a "larghezza" il valore 1050<br />

larghezza = 1050;<br />

// assegna a "altezza" il valore 450<br />

altezza = 450;<br />

// altrimenti<br />

}else{<br />

// assegna a "larghezza" il valore 700<br />

larghezza = 700;<br />

// assegna a "altezza" il valore 450<br />

altezza = 300;<br />

}<br />

// assegna a "x" il valore ricavato dalla differenza tra l'arrotondamento di "w" fratto 2<br />

// e la metà di "larghezza"<br />

var x = Math.ro<strong>un</strong>d(w / 2) - Math.ro<strong>un</strong>d(larghezza / 2);<br />

// assegna a "y" il valore ricavato dalla differenza tra l'arrotondamento di "h" fratto 2<br />

// e la metà di "altezza"<br />

var y = Math.ro<strong>un</strong>d(h / 2) - Math.ro<strong>un</strong>d(altezza / 2);<br />

// apri la f<strong>in</strong>estra con le caratteristiche <strong>in</strong>dicate, centrata e senza barre<br />

f<strong>in</strong>estra = w<strong>in</strong>dow.open ('flash5.htm', null, 'left=' + x + ',screenX=' + x + ',top='<br />

+ y + 'screenY=' + y +',width=' + larghezza + ',height=' + altezza );<br />

}<br />

f<strong>un</strong>ction preferiti(){<br />

var url="http://flash5.html.it/"<br />

var titolo="<strong>Flash</strong>5.it - Risorse italiane su <strong>Flash</strong>"<br />

if (document.all) {<br />

w<strong>in</strong>dow.external.AddFavorite(url,titolo);


}<br />

}<br />

f<strong>un</strong>ction pag<strong>in</strong>aIniziale() {<br />

document.body.style.behavior='url(#default#homepage)';<br />

document.body.setHomePage('http://flash5.html.it/');<br />

}<br />

Pubblicazione<br />

Test<br />

Term<strong>in</strong>ata la costruzione di tutte le pag<strong>in</strong>e e di tutti i filmati del <strong>sito</strong>, bisogna <strong>in</strong>iziare <strong>un</strong>a fase accurata di test <strong>in</strong> locale.<br />

Bisogna provare tutti i collegamenti e tutti i tipi di file, verificando la loro presenza nei p<strong>un</strong>ti <strong>in</strong> cui ci si aspetta che<br />

siano. Bisogna verificare, ad esempio, la correttezza dei nomi e delle estensioni, dal momento che <strong>in</strong> rete <strong>un</strong>a maiuscola<br />

o <strong>un</strong>a m<strong>in</strong>uscola cambiano <strong>in</strong> modo determ<strong>in</strong>ante il nome di <strong>un</strong> file. Bisogna premere tutti i pulsanti, muovere tutti gli<br />

oggetti, e verificare il comportamento dei filmati anche <strong>in</strong> casi anomali, come cercando di accedere più volte allo stesso<br />

file.<br />

Fatto questo, si può spostare il <strong>sito</strong> sul proprio spazio web, ricom<strong>in</strong>ciando da capo tutti i test, e aggi<strong>un</strong>gendone altri: ad<br />

esempio, verificare il f<strong>un</strong>zionamento dei preloader dei filmati esterni (cosa che non si può fare <strong>in</strong> locale), o il passaggio<br />

di variabili (che nei processi http f<strong>un</strong>ziona solo <strong>in</strong> rete).<br />

Altre verifiche importanti, sono quelle <strong>in</strong> relazione all'uso di browser diversi dal proprio: testare il f<strong>un</strong>zionamento dei<br />

javascript, ad esempio, su Explorer come su Netscape o su O<strong>per</strong>a, su pc come su Mac.<br />

Upload<br />

Vediamo la procedura di upload tramite <strong>un</strong> com<strong>un</strong>e client FTP, il ws_ftp pro.<br />

All'avvio del programma, si apre <strong>in</strong> automatico il pannello <strong>per</strong> la connessione: all'<strong>in</strong>terno del pannello, <strong>in</strong>seriamo solo la<br />

prima volta i dati necessari, fornitici dal provider dello spazio web:<br />

Si preme sul pulsate "Connect", e <strong>in</strong>izia la procedura <strong>per</strong> la connessione. Una volta entrati nello spazio web, visibile<br />

nello spazio di destra, accediamo alla cartella <strong>in</strong> cui devono essere messi i file, <strong>per</strong> essere visibile dall'esterno (dipende<br />

dai casi, talvolta direttamente nella cartella <strong>in</strong>iziale). Esploriamo nella parte s<strong>in</strong>istra dell'<strong>in</strong>terfaccia il nostro disco alla<br />

ricerca della cartella <strong>in</strong> cui giacciono i file e, <strong>un</strong>a volta trovati, non bisogna fare altro che trasc<strong>in</strong>arli dall'altra parte.


Unico app<strong>un</strong>to importante: è preferibile costruire manualmente le cartelle, tramite il pulsante MkDir, e riempirle <strong>un</strong>a ad<br />

<strong>un</strong>a.<br />

Struttura<br />

Sul nostro spazio web, il <strong>sito</strong> dovrà avere questa struttura:<br />

• cartella filmati: tutti i filmati swf<br />

• cartella testi: tutti i file txt<br />

• cartella immag<strong>in</strong>i: tutti i file immag<strong>in</strong>i usati nelle pag<strong>in</strong>e html<br />

Nella cartella pr<strong>in</strong>cipale, tutti i restanti file:<br />

Da notare la presenza dell'icona favicon.ico che, se posizionata nella root dello spazio web, viene automaticamente<br />

aggi<strong>un</strong>ta accanto al nome nell'elenco dei Preferiti.

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!