Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Il menu di Flash-MX.it

Costruzione e funzionamento del menu di Flash-MX.it
Costruzione e funzionamento del menu di Flash-MX.it
Link copiato negli appunti

Scarica il file sorgente del menu

Premessa

Nonostante il menu non sia molto complesso, il sistema di duplicazione può sembrarlo (oltre che esserlo): d'altronde, una spiegazione accurata prevederebbe troppi argomenti che devo dare per scontati. Quindi, per chi è interessato alla struttura interna del menu, ci sono le seguenti pagine che ne trattano la costruizione grafica e gli script. Per tutti gli altri, può bastare questa pagina, che spiega come modificare a mano il file di testo esterno che genera il menu, e l'ultima, in cui è spiegato il sistema di apertura del menu al caricamento della pagina html.

Il sistema di creazione menu prevede delle limitazioni in relazione al numero dei menu (l'swf ha delle dimensioni predefinite): quindi chi volesse aggiungere altri menu, o modificare altre caratteristiche, può leggere alcune di queste pagine senza doversi necessariamente addentrare nel vivo dello script.

File di testo

Il punto di forza di questo menu è la facilità con cui se ne possono modificare le caratteristiche: tutte le informazioni relative ai colori utilizzati, al numero dei menu, alle label, ai link ed ai target dei singoli pulsanti vengono infatti attinte da un comunissimo file di testo esterno.

Per comprendere meglio gli script con cui viene generato il menu, è più oppurtuno quindi cominciare con l'analisi di come è fatto il file di testo stesso.

Struttura del file di testo

Esempio del contenuto del file di testo

subText=000000&mainText=ffffff&mainOff=8a8a8a&mainOn=FF8608&subOff=D6D3D6&subOn=ffffff&pres=5&pre1=homepage|/index.asp&pre2=articoli|/articoli/index.asp&pre3=tutorial pratici|/tutorial/index.asp&pre4=faq|/faq/index.asp&pre5=i nostri sondaggi|/sondaggi/index.asp&items=6&main1=guide|/guide/index.asp|_self&sub1=flash mx shared objects|/guide/lista_lezioni.asp?idguida=7$costruire un sito in flash|/guide/lista_lezioni.asp?idguida=6$as: principianti|/guide/lista_lezioni.asp?idguida=3$as: apprendisti|/guide/lista_lezioni.asp?idguida=4$as: esperti|/guide/lista_lezioni.asp?idguida=5$flash e javascript|/guide/lista_lezioni.asp?idguida=2$flash e asp|/guide/lista_lezioni.asp?idguida=1&main2=movies|/movies/index.asp|_self&sub2=raccolta|/movies/index.asp$top ten|/movies/topten.asp$invia il tuo filmato|/movies/invia.asp&main3=loop|/loop/index.asp&sub3=lista loop|/loop/index.asp$top ten|/loop/topten.asp$invia il tuo loop|/loop/invia.asp&main4=effetti sonori|/fx/index.asp&sub4=lista effetti|/fx/index.asp$top ten|/fx/topten.asp$invia il tuo effetto|/fx/invia.asp&main5=servizi|/servizi/index.asp&sub5=recensione software|/servizi/software/index.asp$mailing-list|/servizi/mailing-list.asp$forum|http://forum.html.it&main6=informazioni|/info/index.asp&sub6=staff e autori|/info/staff.asp$pubblicita'|/info/pubblicita.asp$copyright|/info/copyright.asp$privacy|/info/privacy.asp

È presente tutta una serie di informazioni, nella struttura:

variabile1=contenuto1&variabile2=contenuto2&variabile3=contenuto3

quindi:

nome della variabile = valore & nome della variabile = valore & nome...

Talvolta le variabili contengono dei valori "semplici", come nel caso di subText che contiene il valore RGB del colore del testo nei sottomenu, la stringa 000000.

Altre volte le variabili contengono valori più complessi, come serie di stringhe: ad esempio main1, che contiene l'indicazione della label, del link, e del target del primo menu principale, intervallati dal carattere "|".

Ancora, all'interno di altre variabili, abbiamo più serie come quella di main1, a loro volta intervallate dal carattere "$". Queste serie ci indicano label, link e target di tutti i sottomenu del singolo menu principale. Ad esempio, la variabile sub1 contiene le informazioni relative a tutti i sottomenu del primo menu principale:

sub1=flash mx shared objects|/guide/lista_lezioni.asp?idguida=7|_self
$costruire un sito in flash|/guide/lista_lezioni.asp?idguida=6|_self
$as: principianti|/guide/lista_lezioni.asp?idguida=3|_self
$as: apprendisti|/guide/lista_lezioni.asp?idguida=4|_self
$as: esperti|/guide/lista_lezioni.asp?idguida=5|_self
$flash e javascript|/guide/lista_lezioni.asp?idguida=2|_self
$flash e asp|/guide/lista_lezioni.asp?idguida=1|_self

Le variabili, una per una, sono queste:

  • subText: il valore RGB del colore del testo dei sottomenu
  • mainText: il valore RGB del colore del testo dei menu principali
  • mainOff: il valore RGB del colore dei pulsanti dei menu principali nello stato non attivo
  • mainOn: il valore RGB del colore dei pulsanti dei menu principali nello stato attivo (al rollOver)
  • subOff: il valore RGB del colore dei pulsanti dei sottomenu nello stato non attivo
  • subOn: il valore RGB del colore dei pulsanti dei sottomenu nello stato attivo (al rollOver)
  • pres: il numero di menu esterni
  • items: il numero dei menu principali
  • main(x): label, link e target del singolo menu principale
  • sub(x): label, link e target di tutti i sottomenu del singolo menu principale

In questo senso, è possibile editare a mano il menu senza dover più aprire il fla. Aggiungendo una unità al valore di pres, ed aggiungendo una stringa del tipo (al posto della x va il numero del nuovo menu):

pre(x)=label|link|target&

lanciando l'swf avremo un nuovo menu esterno.

Ad esempio, scarichiamo il file zip dal pulsante in alto a destra nella pagina, e scompattiamolo. Proviamo il menu lanciando l'swf, e notiamo come i menu esterni siano 5.

5 menu esterni

Editiamo il file di testo menu.txt, e cambiamo:

...pres=5...

in

...pres=6...

Quindi, alla fine del file di testo, subito dopo l'ultima parola, aggiungiamo:

&pre6=HTML.IT|https://www.html.it/|_blank

Lanciamo nuovamente l'swf, e vedremo come adesso i menu esterni siano sei, come l'ultimo abbia la label "HTML.IT", e una volta cliccato apra l'homepage all'indirizzo http://www.html.it in una nuova finestra.

6 menu esterni

Lo schema della modifica è il seguente:

separatore di variabili nome della variabile label del pulsante separatore di stringa link del pulsante separatore di stringa target del pulsante
& pre6= HTML.IT | https://www.html.it/ | _blank

Se vogliamo invece che "HTML.IT" sia un menu principale, con due sottomenu, "freeasp" e "freephp", procederemo così. Editando il file di testo, senza le modifiche precedenti, cambiamo:

...items=6...

in

...items=7...

(un menu principale in più). Quindi inseriamo le informazioni relative al nuovo menu, in fondo al testo, con:

&main7=HTML.IT|https://www.html.it/|_blank

(stessa cosa che aggiungere un menu esterno, cambia solo il nome della variabile).

separatore di variabili nome della variabile label del pulsante separatore di stringa link del pulsante separatore di stringa target del pulsante
& main7= HTML.IT | https://www.html.it/ | _blank

A questo punto dobbiamo aggiungere le informazioni relative ai sottomenu. Quindi aggiungiamo ancora:

&sub7=freeasp|http://freeasp.html.it/|_blank$freephp|http://freephp.html.it/|_blank

Lanciando l'swf:

Settimo menu principale con due pulsanti

Lo schema della modifica è il seguente:

separatore di variabili nome della variabile label del pulsante separatore di stringa link del pulsante separatore di stringa target del pulsante
& sub7= freeasp | http://freeasp.html.it/ | _blank
separatore di pulsanti label del pulsante separatore di stringa link del pulsante separatore di stringa target del pulsante
$ freephp | http://freephp.html.it/ | _blank

Per cambiare i colori dei menu non attivi, modifichiamo le variabili:

mainOff=6699FF
subOff=FF9900

ottenendo:

Colori modificati

Rettangolo e cornice

Prima di analizzare gli script, vediamo passo passo la costruzione grafica del menu. Creiamo un nuovo documento Flash, con dimensioni 130x300 (queste dimensioni vanno bene per un menu composto da 5 voci esterne, e 5 o 6 principali: per un numero maggiore, bisogna aumentare l'altezza del filmato).

Movieclip

Cominciamo da 2 figure base che riutilizzeremo più volte attraverso il progetto: dal pulsante + in basso a sinistra nella libreria, aggiungiamo un nuovo movieclip che chiameremo rettangolo. All'interno, disegniamo un rettangolo bianco largo 128 pixel e alto 12, con il vertice superiore sinistro sul punto di registrazione del movieclip.

Aggiungiamo un altro movieclip alla libreria, tramite il pulsante +, e chiamiamolo cornice. Dentro il movieclip, disegniamo il contorno di un rettangolo di dimensioni 128x12, di colore 999999, stroke "hairline", e poi cancelliamo il lato inferiore e il lato destro. Il vertice superiore sinistro, come nel caso del rettangolo, va posizionato sul punto di registrazione del movieclip.

Movieclip

Pulsante

Tramite il pulsante + in basso a sinistra nella libreria, creiamo un nuovo simbolo "Button" che chiameremo pulsante. Nel frame "Up" della timeline interna, trasciniamo dalla libreria un'istanza del movieclip rettangolo creato precedentemente. A questo punto, clicchiamo sul frame "Up", e tenendo premuto, trasciniamo la selezionie fino al frame "Hit", dover rilasciamo il tasto del mouse.

In questo modo, abbiamo creato un pulsante trasparente, la cui area di pressione corrisponde alle dimensioni del rettangolo.

BaseSub

Aggiungiamo alla libreria un nuovo movieclip, che chiameremo baseSub. All'interno della timeline del movieclip inseriamo 4 layer secondo il seguente schema:

Schema dei layer

Nel layer pulsante, trasciniamo dalla libreria un'istanza del bottone pulsante, con il vertice superiore sinistro nel punto di registrazione. Al pulsante associamo (ne vedremo il significato più avanti) il seguente script:

on (rollOver, dragOver) {
    coloreRettangolo.setRGB(parseInt(subOn, 16));
}
on (rollOut, dragOut) {
    coloreRettangolo.setRGB(parseInt(subOff, 16));
}
on(release){
    getURL(link, target);
}

Nel layer label, disegniamo un campo di testo dinamico con le seguenti caratteristiche:

Campo di testo dinamico

(per questo menu, ho utilizzato la font hooge05_55 della miniml.com, impostata secondo queste regole).

Nel layer cornice, inseriamo due istanze del movieclip cornice: la prima nella posizione originaria, con il vertice superiore sinistro nel punto di registrazione del movieclip baseSub, la seconda ruotata di 180 gradi.

Layer

Selezioniamo la seconda, e tramite il pannello "Effect" la tingiamo di nero:

Pannello

Infine, nel layer rettangolo, trasciniamo un'istanza del movieclip rettangolo alla quale assegniamo "rettangolo" come nome di istanza.

BaseMain

Con quasi identica procedura costruiamo il movieclip baseMain. Stessa struttura dei layer, stesso pulsante nel primo layer, diverso lo script associato:

on (rollOver, dragOver) {
    coloreRettangolo.setRGB(parseInt(mainOn, 16));
}
on (rollOut, dragOut) {
    coloreRettangolo.setRGB(parseInt(mainOff, 16));
}
on (release) {
    if(_xmouse < 15){
        apri();
    }else{
        if(link == "null"){
            apri();
        }else{
            getURL(link, target);
        }
    }
}

 

Nel layer label, invece, avremo due campi di testo dinamici: il primo avrà associata la variabile plus, il secondo la variabile label. Il primo avrà queste caratteristiche:

Campo di testo

il secondo invece:

Campo di testo

Questa la disposizione sullo stage:

Disposizione sullo stage

Nel layer cornice, avremo nuovamente due istanze del movieclip cornice, solo che questa volta anche la prima avrà una tinta differente dall'originale: il bianco.

Cornici

Sub

Aggiungiamo alla libreria un nuovo movieclip, che chiameremo sub. Al suo interno, trasciniamo un'istanza del movieclip baseSub, alla quale daremo baseSub come nome di istanza. Al movieclip baseSub, associamo il seguente script:

onClipEvent (load) {
    coloreRettangolo = new Color(rettangolo);
    coloreRettangolo.setRGB(parseInt(subOff,16));
}

Main

Creiamo un nuovo movieclip, main. Editiamolo, e al suo interno disponiamo tre layer secondo la seguente figura:

Timeline del movieclip

Nel layer baseSub trasciniamo dalla libreria un'istanza del movieclip sub appena creato, alle quale assegniamo "sub" come nome di istanza. Associamo al movieclip lo script:

onClipEvent (enterFrame) {
    move(fine);
}

Nel layer baseMain trasciniamo un'istanza del movieclip baseMain, nome di istanza "baseMain" (ho cercato di mantenere gli stessi nomi in tutte le parti per questioni di semplicità). Associamo al movieclip:

onClipEvent (load) {
    coloreRettangolo = new Color(rettangolo);
    coloreRettangolo.setRGB(parseInt(mainOff,16));
}

Nel layer maschera, disegniamo unna figura rettangolare della larghezza di 130 pixel, e dell'altezza di 280. L'interno del movieclip main ci deve apparire così:

Stage del movieclip

Esterno

Creiamo un nuovo movieclip, all'interno del quale posizioniamo un'istanza del movieclip main appena creato (nome di istanza "main"). A quest'ultimo associamo:

onClipEvent (load) {
  num = _name.substr(_name.length-1, 1);
  fine = _y;
}
onClipEvent (enterFrame) {
  if (num > 1) {
    if (_parent["main"+(num-1)].aperto) {
      fine = _parent["main" + (num-1)]._y + (_parent["main" + (num-1)].sotto + 1) * 15;
    } else {
      fine = _parent["main" + (num-1)]._y + 15;
    }
    move(fine);
  }
}

Sullo stage

Torniamo alla timeline principale del filmato. Nel primo frame dal basso, trasciniamo un'istanza del movieclip esterno, nome di istanza est, poi una del movieclip baseSub, nome di istanza pre, e infine un movieclip vuoto (nel fla, un cerchietto), al quale è associato lo script per la creazione del menu. Lo stage appare così:

Timeline principale del filmato

Loader

Al movieclip loader è associato questo script:

// <-------- NEGATYVE ------->//
onClipEvent (load) {
  fscommand ("allowscale", false);
  _visible = 0;
  _parent.stop();
  // Branden J. Hall String object rewrite v1.5 //
  String.prototype.split = function(d){
    if (d != null){
      var r = new Array();
      var size = this.length;
      var c = 0;
      var n = 0;
      if (d != ""){
        for (var i=0; i<=size; ++i){
          if (substring(this, i+1, 1) == d){
            r[n] = substring(this, c+1, i-c);
            c = i+1;
            ++n;
          }
        }
        if (c != i){
          r[n] = substring(this, c+1, i-c);
        }
      }else{
        for (var i=0; i<size; ++i){
          r[i] = substring(this, i+1, 1);
        }
      }
    }else{
      r = new Array(this.toString());
    }
    return (r);
  }
  // prototipo per il movimento del menu
  MovieClip.prototype.move = function (fine) {
    spos = (fine-_y)/3;
    _y += spos;
    if (Math.abs(_y-fine)<=0.5) {
      _y = fine;
    }
  };
  // prototipo per l'apertura dei menu principali
  MovieClip.prototype.apri = function () {
    if (!_parent.aperto) {
      _parent.sub.fine = _parent.sotto*15;
      plus = "<p align='center'><font color='#"+mainText+"'>-</font></p>";
      _parent._parent._parent.loader.menu(_parent._name);
    } else {
      _parent.sub.fine = -1;
      plus = "<p align='center'><font color='#"+mainText+"'>+</font></p>";
    }
    _parent.aperto = !_parent.aperto;
  };
  // visibilità dei "seed" clip
  p = _parent.est;
  _parent.pre._visible = 0;
  _parent.est.main._visible = 0;
  // caricamento del file di testo
  var inizio = _root._url.lastIndexOf("/") + 1
  var fine = _root._url.lastIndexOf(".swf");
  var u = _root._url.substring(inizio,fine) + ".txt";
  loadVariables(u, this);
  // funzione per la chiusura dei menu
  function menu (nome) {
    if (nome != prec) {
      p[prec].aperto = false;
      p[prec].sub.fine = -1;
      p[prec].baseMain.plus = "<p align='center'>
        <font color='#"+mainText+"'>+</font></p>";
      prec = nome;
    }
  }
  // funzione per la creazione del menu
  function creaMenu () {
    // creazione array temporanei
    var mainLabel = new Array();
    var subLabel = new Array();
    var preLabel = new Array();
    // colori scritte e menu
    MovieClip.prototype.mainText = mainText;
    MovieClip.prototype.mainOff = mainOff;
    MovieClip.prototype.mainOn = mainOn;
    MovieClip.prototype.subOff = subOff;
    MovieClip.prototype.subOn = subOn;
    // inserimento negli array
    var pres = Number(pres);
    var items = Number(items);
    if (pres > 0) {
      for (var j = 1; j < pres + 1; j++) {
        preLabel[j] = this["pre"+j].split("|");
      }
    }
    for (var i = 1; i < items + 1; i++) {
      mainLabel[i] = this["main" + i].split("|");
      subLabel[i] = this["sub" + i].split("$");
      for (var k = 0; k<subLabel[i].length; k++) {
        subLabel[i][k] = subLabel[i][k].split("|");
      }
    }
    // duplicazione
    if (pres) {
      for (var j = 1; j < pres + 1; j++) {
        var n = "pre" + j;
        duplicateMovieClip ("_parent.pre", n, j);
        _parent[n].label = "<font color='#"+subText+"'>"
            + preLabel[j][0].toUpperCase()+"</font>";
        _parent[n].link = preLabel[j][1];
        _parent[n].target = preLabel[j][2];
        _parent[n]._y = 15*(j-1);
      }
    }
    for (var i = 1; i < items + 1; i++) {
      var n = "main" + i;
      duplicateMovieClip ("_parent.est.main", n, 100+i);
      p[n].aperto = false;
      p[n]._y = 15*(i-1);
      p[n].baseMain.plus = "<p align='center'>
          <font color='#"+mainText+"'>+</font></p>";
      p[n].baseMain.label = "<font color='#"+mainText+"'>"+
      mainLabel[i][0].toUpperCase()+"</font>";
      p[n].baseMain.link = mainLabel[i][1];
      p[n].baseMain.target = mainLabel[i][2];
      var num = subLabel[i].length;
      for (var y = 0; y < num; y++) {
        var n = "sub" + i + y;
        duplicateMovieClip ("_parent.est.main"+i+".sub.baseSub", n, y);
        p["main"+i].sub[n]._x = 150;
        p["main"+i].sub[n]._y = (15 * y) - ((num - 1) * 15);
        p["main"+i].sub[n].label = "<font color='#"+subText+"'>• "+
          subLabel[i][y][0].toUpperCase()+"</font>";
        p["main"+i].sub[n].link = subLabel[i][y][1];
        p["main"+i].sub[n].target = subLabel[i][y][2];
        p["main"+i].sotto = subLabel[i].length;
      }
    }
    // apertura tramite html
    if (_root.q != undefined && Number(_root.q)<=items) {
      var q = Number(_root.q);
      p["main"+q].aperto = true;
      p["main"+q].baseMain.plus = "<p align='center'>
          <font color='#"+mainText+"'>-</font></p>";
      p["main"+q].sub.fine = p["main"+q].sub._y = p["main"+q].sotto*15;
      for (var o=q+1; o<items+1; o++) {
        p["main"+o]._y = (p["main"+q].sotto*15)+((o-1)*15);
      }
      prec = "main" + q;
    } else {
      prec = "nessuno";
    }
    p._y = 15*(j-1);
    // rimozione delle variabili dalla memoria
    var fix = ["Text", "On", "Off"];
    for (var z = 0; z<fix.length; z++) {
      delete this["main"+fix[z]];delete this["sub"+fix[z]];
    }
    for (var z = 0; z<10; z++) {
      delete this["main"+z];delete this["sub"+z];delete this["pre"+z];
    }
    delete u;delete inizio;delete fine;delete items;delete pres;
  }
}
onClipEvent (data) {
  creaMenu();
}

Progetto

Innanzitutto, vediamo qual'è lo schema della creazione del menu.

Dobbiamo duplicare il menu esterno di base tante volte quanto indicato dalla variabile pres del file di testo, e spostare man mano i duplicati verso il basso. Finiti gli esterni, al di sotto di questi, dobbiamo duplicare il movieclip chiamato esterno tante volte quanto indicato dalla variabile items. Dentro ciascun movieclip esterno, sarà presente il movieclip che funge da menu principale, e subMain che deve essere duplicato per creare i "sottomenu".

I movieclip dei sottomenu, vengono duplicati dentro sub, movieclip inserito nel livello coperto dalla maschera. Questo perchè i sottomenu vengono fatti scorrere sotto la maschera, in modo da apparire solo sotto il menu principale, e non sopra.

Dato che i movieclip copie di esterno vengono posizionati alla distanza delle dimensioni del pulsante, tutti i sottomenu si sovrapporranno, solo che, spostati verso l'alto, verranno nascosti dalle rispettive maschere.

Quando clicchiamo su un menu esterno o su un sottomenu, l'azione è un semplice getURL che richiamo una pagina in un target preciso, entrambi impostati nel file di testo. Quando clicchiamo su un menu principale, se siamo più a destra del simbolo "+", viene lanciata una pagina, se siamo sul "+", vengono mostrati i sottomenu.

Per mostrare i sottomenu, dobbiamo fare due cose:

  • spostare verso il basso tutti i menu principali dopo quello selezionato, basandoci sul numero di sottomenu di quest'ultimo
  • all'interno del movieclip principale, spostare verso il basso il movieclip contenente i sottomenu, in modo che appaia sotto la maschera

Per fare queste cose, abbiamo bisogno di impostare un sistema di movimento per entrambi, e di sapere dinamicamente, quando clicchiamo un pulsante principale, quanti sono i sottomenu presenti.

Inoltre, quando clicchiamo ancora su un menu principale, dobbiamo sapere se abbiamo cliccato sullo stesso, per chiuderlo, o su un altro, per chiudere il precedente e aprire quello nuovo.

Infine, dobbiamo impostare per tutti i movieclip:

  • il colore nello stato non attivo
  • il colore nello stato attivo
  • la label
  • il link
  • il target
  • il colore del testo

    .baseSub

Cominciamo a vedere i codici del filmato partendo dal basso. Il movieclip con nome di istanza pre, sulla timeline principale (istanza del movieclip baseSub),

Primo movieclip

contiene questo script:

onClipEvent (load) {
    coloreRettangolo = new Color(rettangolo);
    coloreRettangolo.setRGB(parseInt(subOff, 16));
}

Poiché i colori del menu vengono decisi nel file di testo, i rettangoli contenuti nei movieclip vanno colorati via script. Quindi al caricamento del movieclip creiamo un'istanza dell'oggetto Color, chiamata coloreRettangolo, e associata al movieclip rettangolo all'interno di baseSub. Subito dopo, con il metodo setRGB, impostiamo il colore dell'istanza, basandoci sulla variabile subOff proveniente dal file di testo.

Il setRGB funziona con un numero interpretazione di un valore esadecimale di questo tipo:

.setRGB(0xRRGGBB);

0xFFFFFF, ad esempio (il bianco), viene interpretato dal Flash come il numero 16777215
Infatti, all'interno del Flash, i comandi:

.setRGB(0xFFFFFF);

e

.setRGB(16777215);

producono lo stesso identico effetto.

Ma nel nostro file di testo, abbiamo deciso di impostare i colori solo nel formato RRGGB, quindi FFFFFF per il bianco, senza il "0x" davanti. Inoltre quando carichiamo il file di testo, la variabile subOff viene interpretata come stringa, quindi non possiamo scrivere:

.setRGB(subOff);

ma dobbiamo convertirne il valore in numero. Questo si fa con:

parseInt(stringa, 16)

che riporta il contenuto della stringa al valore numerico corrispondente al formato esadecimale voluto (il 16 è riferito proprio a quello, esa = 6 decimale = 10).

Al pulsante dentro baseSub, che viene duplicato sia per i menu esterni che per i sottomenu, è associato questo script:

on (rollOver, dragOver) {
    coloreRettangolo.setRGB(parseInt(subOn, 16));
}
on (rollOut, dragOut) {
    coloreRettangolo.setRGB(parseInt(subOff, 16));
}
on(release){
    getURL(link, target);
}

All rollOver e al dragOver (necessari per simulare il comportamento di un pulsante basato sui quattro frame "Up" - "Over" - "Down" - "Hit") settiamo il colore dell'istanza coloreRettangolo basandoci sulla variabile subOn, e la riportiamo al valore di subOff al rollOut e al dragOut.

Quando clicchiamo sul pulsante, infine, viene lanciata la pagina contenuta nella variabile link nel frame o pagina di destinazione target. Queste due variabili, verranno distribuite per ciascun duplicato grazie allo script del movieclip loader.

(gli stessi identici script sono presenti nel movieclip con questo percorso: _root.esterno.main.sub.baseSub)

BaseMain

Con il doppio click, editiamo il movieclip esterno presente nella timeline principale:

Secondo movieclip

Al suo interno, troviamo un'istanza del movieclip main: editiamo anche questo con il doppio click. Valutiamo adesso il movieclip istanza di baseMain, indicato dalla freccia:

Istanza di baseMain

Al suo esterno, è associato uno script già visto, solo che valuta mainOff invece che subOff:

onClipEvent (load) {
    coloreRettangolo = new Color(rettangolo);
    coloreRettangolo.setRGB(parseInt(mainOff, 16));
}

Il pulsante all'interno, invece, ha uno script diverso:

on (rollOver, dragOver) {
    coloreRettangolo.setRGB(parseInt(mainOn, 16));
}
on (rollOut, dragOut) {
    coloreRettangolo.setRGB(parseInt(mainOff, 16));
}
on (release) {
    if(_xmouse < 15){
        apri();
    }else{
        if(link == "null"){
            apri();
        }else{
            getURL(link, target);
        }
    }
}

La parte relativa al rollOver del pulsante è identica a quella di baseSub, solo che prende in condiserazione una coppia di colori diversi, relativi al menu principale.

Quella relativa al click invece, controlla alla pressione del tasto sinistro del mouse, la posizione del puntatore rispetto al movieclip che contiene il pulsante. Se la posizione è minore di 15 (siamo sopra il simbolo "+", che occupa appunto 15 pixel dal lato sinistro del movieclip), viene richiamata la funzione apri(), che provvede all'apertura del menu. Altrimenti, viene controllato il valore della variabile link: se il valore è la stringa null, viene nuovamente chiamata la funzione apri(), altrimenti viene lanciata in target la pagina link.

Perchè questo controllo? Perchè impostando nel file di testo la stringa "null" come link del menu principale, ovunque clicchiamo vengono mostrati i sottomenu, e non viene mai lanciata alcuna pagina. Un esempio classico di questo è proprio il menu di flash-mx.it. (mentre l'impostazione di default del menu è: apri i sottomenu se clicchi sul "+", e lancia la pagina se clicchi sul resto del pulsante).

// all rollOver e al dragOver sul pulsante
on (rollOver, dragOver) {
    // imposta il colore del rettangolo con il
    // valore estratto dalla variabile mainOn

    coloreRettangolo.setRGB(parseInt(mainOn, 16));
}
// all rollOut e al dragOut sul pulsante
on (rollOut, dragOut) {
    // imposta il colore del rettangolo con il
    // valore estratto dalla variabile mainOff

    coloreRettangolo.setRGB(parseInt(mainOff, 16));
}
// alla pressione sul pulsante
on (release) {
    // se la posizione del puntatore del mouse,
    // rispetto al movieclip, è inferiore a 15

    if(_xmouse < 15){
        // chiama la funzione apri(), e mostra
        // i sottomenu

        apri();
    // altrimenti (e quindi la posizione del
    // puntatore del mouse è maggiore di 15

    }else{
        // se "link" è uguale a "null"
        if(link == "null"){
            // richiama la funzione apri()
            apri();
        // altrimenti ("link" NON è uguale a "null")
        }else{
            // lancia "link" in "target"
            getURL(link, target);
        }
    }
}

Sub

Torniamo su di un livello, e valutiamo questo movieclip:

Movieclip

al suo interno è presente un'istanza del movieclip baseSub, per creare i sottomenu (è il movieclip sub che scorre sotto la maschera, non i singoli duplicati al suo interno), i cui script associati sono già stati visti (impostazione dei colori, apertura della pagina).

Al movieclip sub, invece, è associato:

onClipEvent (enterFrame) {
    move(fine);
}

Ad ogni riproduzione del movieclip, viene richiamata la funzione move (poi vedremo la sua definizione), passando la variabile fine come parametro.

Main

Torniamo ancora su di un livello, al movieclip main dentro esterno. A questo movieclip, è associato lo script che si occupa del movimento del singolo menu principale (non dei sottomenu).

onClipEvent (load) {
  num = Number(_name.substr(4));
  fine = _y;
}
onClipEvent (enterFrame) {
  if (num>1) {
    if (_parent["main"+(num-1)].aperto) {
      fine = _parent["main"+(num-1)]._y+(_parent["main"+(num-1)].sotto+1)*15;
    }else{
      fine = _parent["main"+(num-1)]._y+15;
    }
    move(fine);
  }
}

Al caricamento, dal nome del movieclip duplicato (i menu principali si chiameranno main1, main2, main3 ... eccetera), viene estratto il numero finale come identificativo, inserito nella variabile num, e alla variabile fine viene assegnato il valore della posizione attuale del movieclip sull'asse delle y.

Ad ogni riproduzione del movieclip, se il valore di num è maggiore di 1 (e quindi non è il caso del primo menu principale, che non si deve mai muovere), viene controllato il valore della variabile aperto nella timeline del movieclip il cui nome è composto dalla stringa "main" più il valore della variabile num meno una unità. In parole semplici, se siamo nel menu main3, viene verificato il valore della variabile aperto nel movieclip main2.

Se il valore di aperto è true, alla variabile fine viene assegnato il valore della posizione sull'asse delle y del menu precedente più il valore della variabile sotto del movieclip precedente moltiplicata per 15, altrimenti il valore della posizione del movieclip precedente più 15, e viene passata come parametro alla funzione move ( la stessa funzione per il movimento dei sottomenu).

Nella pratica: siamo nel movieclip main3, e fine ci indica la posizione che deve assumere. Controlliamo il valore di aperto in main2: se la variabile è falsa, fine è la posizione di main2 più 15 (il menu precedente è chiuso, quindi main3 sta subito sotto: il 15 sono i 15 pixel di altezza di un menu chiuso). Se invece la variabile aperto è vera, vuol dire che main2 sta mostrando i sottomenu. Per poter far vedere i sottomenu, dobbiamo abbassare main3, e allora lo portiamo all'altezza della posizione di main2 più sotto per 15. Sotto, è una variabile contenuta in ogni movieclip principale che indica il numero di sottomenu associati più 1. Quindi, se in main2 sono presenti 4 sottomenu, posizioniamo main3 all'altezza di main2, e lo abbassiamo di 15*5.

Movimento del menu

Codice di creazione

Vediamo pezzo a pezzo lo script di creazione del menu.

Load

onClipEvent (load) {
  fscommand ("allowscale", false);
  _visible = 0;
  _parent.stop();

Al caricamento del movieclip, con l'fscommand facciamo in modo che il filmato, guardato nello standalone player, non si ridimensioni con la finestra del proiettore, rendiamo invisibile il movieclip loader, e fermiamo la riproduzione della timeline principale.

Split

// Branden J. Hall String object rewrite v1.5 //
String.prototype.split = function(d){
  if (d != null){
    var r = new Array();
    var size = this.length;
    var c = 0;
    var n = 0;
    if (d != ""){
      for (var i=0; i<=size; ++i){
        if (substring(this, i+1, 1) == d){
          r[n] = substring(this, c+1, i-c);
          c = i+1;
          ++n;
        }
      }
      if (c != i){
        r[n] = substring(this, c+1, i-c);
      }
    }else{
      for (var i=0; i<size; ++i){
        r[i] = substring(this, i+1, 1);
      }
    }
  }else{
    r = new Array(this.toString());
  }
  return (r);
}

La funzione, creata da Brandon J. Hall di Fig Leaf Software, riscrive il metodo split della classe String. Questa funzione, serve a dividere in due una stringa, quando viene incontrata una particolare sequenza di caratteri. Nel nostro caso, serve ad esempio a separare label, link e target dei menu principali all'altezza del carattere "|":

&main(x)=label|link|target

Move

// prototipo per il movimento del menu
MovieClip.prototype.move = function (fine) {
  spos = (fine-_y)/3;
  _y += spos;
  if (Math.abs(_y-fine)<=0.5) {
    _y = fine;
  }
};

La funzione move, per il movimento dei menu principali e dei sottomenu, viene riscritta con questa particolare notazione:

MovieClip.prototype.nomeFunzione = function (parametri) {
  //-- codice --//
};

La classe MovieClip, dalla quale vengono generati tutti i movieclip in Flash, possiede, come tutte le altre classi, un oggetto predefinito che si chiama prototype. Quando una funzione viene scritta nell'oggetto prototype dei movieclip, tutti i movieclip del filmato ereditano questa funzione, come se fosse scritta nell'evento onClipEvent(load) del movieclip stesso.

Infatti, per richiamare questa funzione, nel movieclip main non abbiamo usato:

_root.loader.move(fine);

ma semplicemente:

move(fine);

Allo stesso modo, quando all'interno della funzione troviamo la parola this, il riferimento non è al movieclip loader, nel quale è definita la funzione, ma al movieclip nel quale viene chiamata e applicata.

La funzione, stabilisce la posizione del movieclip nella quale viene applicata utilizzando come parametro la variabile fine, vista in precedenza, e come formula quella del moto decelerato:

posizione_attuale = posizione_attuale + (posizione_finale - posizione_attuale)/intervallo

Alla fine della funzione è presente un controllo sull'effettiva posizione del movieclip rispetto alla variabile fine:

if (Math.abs(_y-fine)<=0.5) {
  _y = fine;
}

Apri

// prototipo per l'apertura dei menu principali
MovieClip.prototype.apri = function () {
  if (!_parent.aperto) {
    _parent.sub.fine = _parent.sotto*15;
    plus = "<p align='center'><font color='#"+mainText+"'>-</font></p>";
    _parent._parent._parent.loader.menu(_parent._name);
  } else {
    _parent.sub.fine = -1;
     plus = "<p align='center'><font color='#"+mainText+"'>+</font></p>";
  }
  _parent.aperto = !_parent.aperto;
};

La funzione, simile a quella vista per il movimento dei menu principali, si occupa dello spostamento del movieclip sub contenente i "sottomenu": anche questa funzione viene definita nell'oggetto prototype della classe MovieClip.

La funzione, richiamata al clic sui pulsanti, verifica lo stato della variabile aperto. Nel caso sia uguale a false, la variabile fine definita nella timeline del movieclip sub viene settata con il valore di sotto moltiplicato per 15 (il movieclip sub richiama la funzione move con fine come parametro all'enterFrame). Quindi, se il menu principale è chiuso, viene aperto.

Stabilita una nuova destinazione per il movieclip sub (che scorre sotto la maschera), cambiamo il valore della variabile plus associata al campo di testo con il simbolo "+", che diventa "-". Per cambiare il carattere, dobbiamo ridefinire anche il colore del campo di testo, che altrimenti diventerebbe nero (colore originario). Quindi viene passata alla funzione menu definita in loader, il nome del movieclip principale che contiene quello attuale.

Nel caso invece in cui la variabile aperto sia vera (il menu principale è aperto) spostiamo il movieclip sub alla coordinata -1, nascondendolo sotto la maschera, e di fatto chiudendo il menu: riscriviamo quindi il "+" nel campo plus.

Infine, qualunque sia il valore di aperto, ne settiamo l'opposto. Se aperto è true, diventa false, e viceversa.

// prototipo per l'apertura dei menu principali
MovieClip.prototype.apri = function () {
  // se la variabile "aperto" nella timeline superiore è uguale a false
  // e quindi il menu è chiuso

  if (!_parent.aperto) {
    // setta la variabile "fine" del movieclip sub contenuta nella
    // timeline superiore come il prodotto di "sotto" per 15
    // il movieclip "sub", che usa "fine" come parametro della funzione
    // "move", si sposta verso il basso

    _parent.sub.fine = _parent.sotto*15;
    // cambia in "-" il "+" del campo di testo "plus"
    plus = "<p align='center'><font color='#"+mainText+"'>-</font></p>";
    // passa come parametro alla funzione "menu" in loader,
    // il nome del movieclip contenitore

    _parent._parent._parent.loader.menu(_parent._name);
  // altrimenti (aperto è true e quindi il menu principale è aperto)
  } else {
    // sposta il movieclip "sub" sotto la maschera
    _parent.sub.fine = -1;
    // cambia il simbolo "-" in "+"
     plus = "<p align='center'><font color='#"+mainText+"'>+</font></p>";
  }
  // inverti il valore della variabile "aperto"
  _parent.aperto = !_parent.aperto;
};

p = _parent.est;
// funzione per la chiusura dei menu

function menu (nome) {
  if (nome != prec) {
    p[prec].aperto = false;
    p[prec].sub.fine = -1;
    p[prec].baseMain.plus = "<p align='center'>
         <font color='#"+mainText+"'>+</font></p>";
    prec = nome;
  }
}

La funzione menu riceve "nome" come parametro. Se nome è diverso da prec, la variabile aperto nel movieclip il cui percorso è composta da "_parent.est" (abbreviato in p) più prec viene settata come falsa. La variabile fine nel movieclip sub viene settata con il valore -1, e il simbolo "-" nel campo di testo plus (nel movieclip baseMain) viene convertito in "+". Quindi il valore di nome viene assegnato a prec.

Menu viene chiamata dalla funzione apri appena vista, e valuta se abbiamo cliccato sullo stesso menu principale, o su uno diverso. Se abbiamo cliccato su uno diverso, chiude il precedente, ne setta la variabile aperto come falsa (in modo da valutare se è aperto o meno), ne riprostina il "+" e aggiorna il valore della variabile prec, contenitore del nome del precedente movieclip.

Quindi, se apriamo il menu main2, e poi clicchiamo su main3, quest'ultimo viene aperto dalla funzione apri(), che chiama menu. Verificato positivamente che prec e nome sono diversi (uno è "main2", l'altro "main3"), main2 viene chiuso, e il prossimo menu da chiudere diventa main3.

LoadVariables

p = _parent.est;
_parent.pre._visible = 0;
_parent.est.main._visible = 0;
// caricamento del file di testo
var inizio = _root._url.lastIndexOf("/") + 1
var fine = _root._url.lastIndexOf(".swf");
var u = _root._url.substring(inizio,fine) + ".txt";
loadVariables(u, this);

Alla variabile p viene associato il riferimento al movieclip est presente nella timeline principale: in questo modo, potremo usare p.movieclip abbreviando per _parent.est.movieclip.

Rendiamo invisibili con la proprietà _visible sia il movieclip pre, che il movieclip est.main, cioè le basi per la duplicazione. Quindi carichiamo nel movieclip loader il file di testo, che deve avere lo stesso nome del filmato. Cambiando il nome al file swf, ci basterà cambiare anche quello del file di testo perchè tutto funzioni regolarmente. Questo perchè la funzione estrae dalla proprietà _url il percorso del file swf, ed elaborandone la stringa derivata crea il riferimento al file di testo. Vediamo come.

Supponiamo che il filmato sia all'indirizzo http://flash-mx.html.it/cartella/menuFlash.swf, la proprietà p restituisce appunto la stringa: "http://flash-mx.html.it/cartella/menuFlash.swf"

Con il substring(x, y), prendiamo una porzione di stringa che va dal carattere nella posizione x al carattere nella posizione y, mentre il lastIndexOf(stringa) ci restituisce la posizione dell'ultima evenienza della sottostringa indicata tra parentesi. Quindi con:

var inizio = _root._url.lastIndexOf("/") + 1

troviamo questo punto http://flash-mx.html.it/cartella/menuFlash.swf

con

var fine = _root._url.lastIndexOf(".swf");

troviamo quest'altro: http://flash-mx.html.it/cartella/menuFlash.swf

Prendendo quello che c'è in mezzo, e attacandogli in fondo ".txt", otteniamo "menuFlash.txt". E questo è il nome del file di testo da caricare.

Data

onClipEvent (data) {
  creaMenu();
}

Una volta caricato il file di testo, il movieclip resta in attesa delle variabili. Quando le variabili sono state completamente caricate, viene richiamata la funzione creaMenu(), che vediamo nella prossima pagina.

// una volta che tutte le
//variabili sono state caricate

onClipEvent (data) {
    // esegui la funzione creaMenu
    creaMenu();
}

CreaMenu

La funzione creaMenu è molto lunga, quindi la vediamo un po' per volta:

// funzione per la creazione del menu
function creaMenu () {
  // creazione array temporanei
  var mainLabel = new Array();
  var subLabel = new Array();
  var preLabel = new Array();
  // colori scritte e menu
  MovieClip.prototype.mainText = mainText;
  MovieClip.prototype.mainOff = mainOff;
  MovieClip.prototype.mainOn = mainOn;
  MovieClip.prototype.subOff = subOff;
  MovieClip.prototype.subOn = subOn;

Una volta caricato il file esterno, viene richiamata la funzione creaMenu. Innanzitutto vengono creati 3 array temporanei (l'utilizzo di var prima del nome della variabile implica la cancellazione dell'array alla fine della funzione) che serviranno per la duplicazione, quindi le 5 variabili relative ai colori vengono inserite nell'oggetto prototype della classe movieclip, in modo da essere disponibili ovunque (ai pulsanti per i rollOver, ad esempio). L'unica che non viene considerata è subText, poichè viene usata una sola volta proprio durante la creazione del menu.

// inserimento negli array
var pres = Number(pres);
var items = Number(items);
if (pres > 0) {
    for (var j = 1; j < pres + 1; j++) {
        preLabel[j] = this["pre"+j].split("|");
    }
}
for (var i = 1; i < items + 1; i++) {
    mainLabel[i] = this["main" + i].split("|");
    subLabel[i] = this["sub" + i].split("$");
    for (var k = 0; k<subLabel[i].length; k++) {
        subLabel[i][k] = subLabel[i][k].split("|");
    }
}

Le variabili pres e items, che contengono rispettivamente il numero di menu esterni e di menu principali, vengono convertite in numeri, dal momento che il Flash interpreta le variabili esterne come stringhe. Quindi, se il numero derivante da pres (anche questo temporaneo) è maggiore di zero, con un ciclo for di tante iterazioni quante il valore di pres, in ordine crescente, inseriamo nell'array temporaneo preLabel il contenuto della variabile "pre" + j spezzata all'altezza del carattere "|".

Brevemente: partendo dalla stringa "label|link|target", con:

stringa = "label|link|target";
mioArray = stringa.split("|");

ottengo lo stesso effetto di:

mioArray = new Array();
mioArray[0] = "label";
mioArray[1] = "link";
mioArray[2] = "target";

cioè direttamente inserisco per ogni elemento di un array le stringhe derivanti dalla separazione della stringa originaria. Iterando il ciclo di split con il for, ottengo:

Array

Ogni elemento dell'array preLabel, sarà a sua volta un array contenente i dati di ogni singolo menu esterno ripartiti per tre elementi, ciascuno contenente i tre dati forniti.

Lo stesso ciclo viene effettuato sul numero di items con le stringhe formate da "main" + i, inserite nell'array temporaneo mainLabel. All'interno di questo ciclo, ne è annidato un altro: come abbiamo visto in precedenza, le variabili relative ai sottomenu contengono i dati di tutti i pulsanti di ogni menu principale, separati dal carattere "$". PEr questo motivo, prima separiamo la stringa all'altezza del carattere "$", e poi a quella del carattere "|", ottenendo:

Array

Ogni elemento dell'array subLabel contiene i dati del gruppo di sottomenu associato al menu principale: ogni sottoelemento dell'array subLabel, contiene i dati relativi a tutti i sottomenu del singolo menu principale, e ancora ogni sottoelemento contiene i tre dati riferiti al singolo sottomenu.

// duplicazione
if (pres) {
  for (var j = 1; j < pres + 1; j++) {
    var n = "pre" + j;
    duplicateMovieClip ("_parent.pre", n, j);
    _parent[n].label = "<font color='#"+subText+"'>"
        + preLabel[j][0].toUpperCase()+"</font>";
    _parent[n].link = preLabel[j][1];
    _parent[n].target = preLabel[j][2];
    _parent[n]._y = 15*(j-1);
  }
}

Iniziamo la duplicazione: con un ciclo for di pres iterazioni, assegniamo alla variabile n il valore della stringa formata da "pre" più il valore di i. Duplichiamo il movieclip pre, assegniamo al duplicato il nome n, e profondità j (j è la variabile che aumenta durante il ciclo).

All'interno di ogni duplicato (stiamo creando i menu esterni), inseriamo nel campo di testo label il dato salvato nell'elemento [j][0] dell'array preLabel, portando tutte le lettere maiuscole.
Quindi prendiamo il valore [j][1] dell'array, e lo inseriamo nella variabile link del duplicato, e così per il terzo elemento e la variabile target.

Quindi posizioniamo il duplicato sull'asse delle y al pixel ottenuto dalla moltiplicazione di 15 per il valore di j sottratto di una unità (il primo elemento deve essere posizionato al pixel 0, non 15).

Ad esempio, il valore di pres è 5, quindi ci sono 5 menu esterni. Nella prima iterazione del ciclo, j è uguale a 1, quindi duplichiamo il movieclip pre, e come nome gli diamo "pre1". Prendiamo l'elemento [1][0] dell'array preLabel (guardando la prima figura, si vede come questo elemento sia "homepage"), lo trasformiamo in "HOMEPAGE", e lo inseriamo nel campo di testo label nel movieclip "pre1".

Prendiamo l'elemento [1][1] dell'array (e dalla figura si vede che è /index.asp), e lo associamo alla variabile link del duplicato, e così per "_self" e la variabile target. Se clicchiamo quindi sul pulsante del primo menu esterno, sul quale leggeremo "HOMEPAGE", lo script:

getURL(link, target);

visto in precedenza diventa:

getURL("/index.asp", "_self");

E così via per tutti i menu esterni.

[/NON TOCCARE! CODICE XML PER L'ESPORTAZIONE]-->

for (var i = 1; i < items + 1; i++) {
  var n = "main" + i;
  duplicateMovieClip ("_parent.est.main", n, 100+i);
  p[n].aperto = false;
  p[n]._y = 15*(i-1);
  p[n].baseMain.plus = "<p align='center'>
          <font color='#"+mainText+"'>+</font></p>";
  p[n].baseMain.label = "<font color='#"+mainText+"'>"+
          mainLabel[i][0].toUpperCase()+"</font>";
  p[n].baseMain.link = mainLabel[i][1];
  p[n].baseMain.target = mainLabel[i][2];
  var num = subLabel[i].length;
  for (var y = 0; y < num; y++) {
    var n = "sub" + i + y;
    duplicateMovieClip ("_parent.est.main"+i+".sub.baseSub", n, y);
    p["main"+i].sub[n]._x = 150;
    p["main"+i].sub[n]._y = (15 * y) - ((num - 1) * 15);
    p["main"+i].sub[n].label = "<font color='#"+subText+"'>• "+
          subLabel[i][y][0].toUpperCase()+"</font>";
    p["main"+i].sub[n].link = subLabel[i][y][1];
    p["main"+i].sub[n].target = subLabel[i][y][2];
    p["main"+i].sotto = subLabel[i].length;
  }
}

Come per i menu esterni, creiamo i menu principali, e popoliamo il movieclip sub, contenuto all'interno di ciascuno di essi, con i movieclip dei sottomenu: vediamo un esempio di duplicazione alla terza iterazione del ciclo.

La variabile i è uguale a 3, quindi n è uguale a "main3". Duplichiamo il movieclip est.main, assegniamo al duplicato il nome "main3", e profondità 100 + i. Settiamo la variabile aperto come falsa (in partenza ogni menu principale è chiuso), e posizioniamo il movieclip duplicato con _y uguale a 30 (15* i-1, quindi 15* 3-1, 15*2). Nel campo di testo plus di baseMain contenuto in "main3", inseriamo il carattere "+" con il colore dato da mainText; come label, l'elemento [3][1] (da [i][1]) dell'array mainLabel, e stessa cosa per il link e il target (esattamente come per i menu esterni).

Quindi, alla creazione di ogni menu esterno, con un altro ciclo for creiamo i sottomenu. Le iterazioni sono tante quanto la lunghezza del sotto array visto nell'ultima figura della pagina precedente. Duplichiamo il movieclip "_parent.est.main3.sub.baseSub", nome "sub30" (esempio per il primo sottomenu di "main3", ne settiamo posizione sull'asse delle y (negativa, dal momento che devono stare sotto la maschera, e partendo dal fondo, per non invertire i sottomenu) e sull'asse delle x (150: nella costruzione abbiamo posizionato i movieclip sulla sinistra, fuori dallo stage).

Per l'inserimento dei tre dati, si ripete il ragionamento fatto per i menu precedenti, solo che abbiamo a che fare con un array più complesso. Interpretando ad esempio la riga:

p["main"+i].sub[n].link = subLabel[i][y][1];

con i dati in nostro possesso diventa:

_parent.est.main3.sub.sub0.link = subLabel[3][y][1];

Siamo al terzo movieclip principale, prima iterazione del ciclo annidato, quindi prendiamo il primo elemento dell'array subLabel, tramutiamo il valore di y (identificativo dell'iterazione annidata) e otteniamo:

_parent.est.main3.sub.sub0.link = subLabel[3][1][1];

cioè la label del primo elemento, e così fino all'ultimo.

Apertura tramite html

Una delle funzioni più utili del menu è la possibilità, al caricamento della pagina html che lo incorpora, di aprirlo direttamente ad un determinato menu. Questo viene fatto con una semplice aggiunta ai tag di <object> ed <embed> (l'aggiunta è in rosso nel codice):

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
codebase="..." width=130 height=300>
<param name="movie" VALUE="menuFlash5.swf?q=4" />
<param name="loop" value="false" />
<param name="menu" value="false" />
<param name="quality" value="high" />
<param name="bgcolor" value="#CCCCCC" />
</object>

Alla fine del nome del filmato, aggiungiamo: ?q= più il numero del menu principale che vogliamo sia aperto, quindi se vogliamo aprire il primo scriveremo ?q=1, se vogliamo aprire il quinto, scriveremo ?q=5. Scrivendo il nome di una variabile e il suo contenuto, separati da un uguale, dopo un punto interrogativo alla fine del nome del filmato, troveremo la variabile definita nella root, come se avessimo scritto nel primo frame della timeline principale:

_root.q = "5";

Il 5 è tra virgolette perchè come già detto, le variabili esterne vengono interpretate dal flash come stringhe. Quindi, nella funzione di creazione del menu, possiamo valutare il contenuto della variabile q nella root, e in base a quella aprire il menu corrispondente.

// apertura tramite html
if (_root.q != undefined && Number(_root.q)<=items) {
  var q = Number(_root.q);
  p["main"+q].aperto = true;
  p["main"+q].baseMain.plus = "<p align='center'>
          <font color='#"+mainText+"'>-</font></p>";
  p["main"+q].sub.fine = p["main"+q].sub._y = p["main"+q].sotto*15;
  for (var o=q+1; o<items+1; o++) {
    p["main"+o]._y = (p["main"+q].sotto*15)+((o-1)*15);
  }
  prec = "main" + q;
} else {
  prec = "nessuno";
}
p._y = 15*(j-1);

Se q non è undefined, e quindi abbiamo scritto qualcosa nei tag, e se q, convertita in numero, è minore del valore di items (non possiamo aprire il sesto menu principale se i menu sono 5), allora modifichiamo la variabile aperto del menu corrispondente, ne cambiamo il "+" in "-", abbassiamo il movieclip sub al suo interno, e spostiamo verso il basso, per l'altezza legata al numero di sottomenu, tutti gli altri menu principali. Quindi, se abbiamo scritto q=2, e i menu sono 5, sposteremo verso il basso main3, main4 e main5, e settiamo come prec (la variabile per la chiusura del menu) appunto main2.

Se invece la condizione iniziale non è verificata, prec è uguale a "nessuno" (movieclip inventato e inesistente, in modo che qualunque menu principale, al primo click, si apra regolarmente).

// rimozione delle variabili dalla memoria
var fix = ["Text", "On", "Off"];
for (var z = 0; z<fix.length; z++) {
     delete this["main"+fix[z]];delete this["sub"+fix[z]];
}
for (var z = 0; z<10; z++) {
     delete this["main"+z];delete this["sub"+z];delete this["pre"+z];
}
delete u;delete inizio;delete fine;delete items;delete pres;

Infine, con lo script qui sopra, cancelliamo tutte le variabili temporanee che abbiamo usato, quindi gli array, le variabili importate dai file di testo, i contatori.

Ti consigliamo anche