Salve,
questo post ha lo scopo di esplorare alcune peculiarità del linguaggio ActionScript 3.0...
Ritengo che il motivo per cui Flash è diventato così famoso è che chiunque era in grado di vedere un risultato dopo pochi esperimenti.
Da quando è uscita la nuova versione del linguaggio ActionScript sembra che Flash sia diventato una “cosa per programmatori”: gli esempi che si trovano in rete sono listati lunghissimi di codice incomprensibile e, spesso, non immediatamente utilizzabile da un neofita.
Quindi cominciamo con il primo di quello che spero sia una lunga serie di “tutorial pratici”.
Alla fine di ogni tutorial avremo realizzato qualcosa con ActionScript 3.0, anche se dovesse trattarsi di un giochino stupido come quello che vi presento oggi:
Ammazza la Mosca!
Preparazione
La prima cosa da fare è senza dubbio disegnare una mosca, questo compito lo lascio totalmente nelle vostre mani, ognuno è libero di disegnare come preferisce, sia con gli strumenti di Flash che importando grafica realizzata con altri programmi.
Una volta disegnata la masca è necessario
selezionarla e premere F8, in questo modo la convertiremo in un
MovieClip e la ritroveremo nella
Libreria.
Possiamo cancellare la mosca che si trova sullo Stage, infatti per realizzare il giochino diremo a Flash di pescare i Simboli direttamente dalla Libreria.
Esportare il Simbolo e utilizzarlo nel codice
Una delle più grosse innovazioni della versione 3.0 è che qualunque cosa vogliamo creare la sintassi è sempre la stessa, non esistono più metodi come createEmptyMovieClip o createTextField. Per creare un MovieClip o un campo di testo basta istanziare le classi corrispondenti con new MovieClip() e new TextField(), e così funziona con tutte le altre Classi.
Questa che ho scritto è già di per se una bella notizia, ma come se non bastasse qualunque oggetto della nostra Libreria può diventare una Classe ed essere istanziato allo stesso modo. Come si fa?
- Click con il tasto destro sull’Oggetto che si trova nella Libreria.
- Selezionare la voce Linkage (Concatenamento), che apre una finestra di dialogo.
- Applicare la spunta sulla casella Export for ActionScript (Esporta per ActionScript).
- Inserire un nome nella casella Class (Classe), per questo esempio io ho scritto mosca.
- Click su OK.
Quello che abbiamo appena fatto ci consente di utilizzare il nostro MovieClip direttamente dalla Libreria, il codice per richiamarlo è questo:
Codice:
var unaMosca:mosca = new mosca();
Il codice qui sopra va inserito in un fotogramma, in questo modo:
- Fare click sul primo Fotogramma nella Timeline.
- Aprire il Pannello Azioni (F9).
- Scrivere il codice.
A questo punto l’Oggetto che ci interessa è stato istanziato, però se proviamo il filmato ci accorgiamo che non è visibile... questo perché
non lo abbiamo ancora messo sullo Stage, aggiungiamo un rigo al codice, che diventa così:
Codice:
var unaMosca:mosca = new mosca();
addChild(unaMosca);
Proviamo il Filmato (CTRL + INVIO) e ci accorgiamo che, effettivamente, la nostra mosca si trova sullo Stage, in alto a sinistra.
Citazione:
|
In questa prima parte abbiamo visto che è possibile utilizzare un oggetto dalla Libreria come se fosse una qualunque Classe di ActionScript e che possiamo istanziarlo e posizionarlo sullo Stage in sole due righe.
|
OK, abbiamo la mosca... ma come la spostiamo?
Una volta istanziato un Oggetto possiamo assegnargli delle azioni, modificare delle Proprietà, ecc.
Proviamo ad aggiungere un altro rigo di codice:
Codice:
unaMosca.x = 100;
Proviamo il filmato e ci accorgiamo che la mosca non sta più a sinistra, si è scostata dal bordo, più esattamente si trova a 100 pixel dal bordo sinistro.
Abbiamo cambiato la posizione orizzontale della mosca semplicemente modificando il valore dell’attributo corrispondente. Qualunque attributo si modifica nello stesso identico modo:
nomeOggetto.nomeAttributo = nuovoValore;
Citazione:
|
Chi utilizza ActionScript in una versione precedente noterà che è sparito il trattino basso dal nome della Proprietà x, anche le altre Proprietà sono state rinominate: la maggior parte coserva ancora il vecchio nome privato del trattino basso (_x è diventato x, _y è diventato y, _alpha è diventato alpha, ecc...).
|
Vediamo se riusciamo ad ucciderla...
Mentre ragioniamo su come fare per muovere la mosca vediamo se riusciamo ad ucciderla... per farlo ci serviremo di un’altra importante Classe di ActionScript 3.0, quella che gestisce gli
Eventi del Mouse.
Prima cerchiamo di capire cosa è un Evento...
Se un albero cade nella foresta e nessuno lo sente, che rumore fa?
In ActionScript non ha nessuna importanza. Soltanto se mettiamo qualcuno in ascolto l’evento viene percepito, altrimenti è come se non fosse mai accaduto.
Troppo difficile? Proviamo di nuovo...
Muovere il mouse è un Evento, premere un tasto è un Evento, caricare un filmato esterno è un Evento, ogni secondo che passa è un Evento...
In ActionScript posso creare un “Ascoltatore di Evento”, lui starà fermo e buono ad aspettare che avvenga quello per cui è stato creato.
Come se fosse un uomo lasciato solo nella foresta, ad aspettare che un albero cada; soltanto quando sentirà il rumore dell’albero cadere potrà agire.
Ecco quindi cosa faremo: metteremo un ascoltatore in attesa del click del Mouse, così saremo in grado di sapere se qualcuno ha cliccato sulla mosca per ucciderla.
Aggiungiamo un rigo di codice:
Codice:
unaMosca.addEventListener(MouseEvent.CLICK, muori);
Questo codice aggiunge un “Ascoltatore di Eventi” regolato per intercettare il Click del Mouse sul nostro MovieClip...
Quando faremo click sulla mosca verrà richiamato un comando che ancora non esiste, questo comando si chiama
muori... si capisce cosa dovrà fare, vero?
Se proviamo il filmato adesso otteniamo un errore, questo è dovuto al fatto che la parola
muori non significherà niente fino a quando non avremo scritto il codice corrispondente.
Ecco qua il codice che assegna un significato alla parola muori, usata in precedenza...
Codice:
function muori(event:MouseEvent):void
{
event.target.alpha = .5;
event.target.scaleX = 1.5;
event.target.scaleY = 1.5;
event.target.rotation = 135;
}
Questa è una Funzione... una Funzione è una
porzione di Codice riutilizzabile, così se in futuro ci verrà in mente di aggiungere altre mosche al nostro gioco non dovremo riscrivere la parte di codice che ne gestisce la morte.
Una cosa molto importante nel codice precedente è che possiamo impostare le Proprietà dell’oggetto che ha richiamato la funzione, anche se non ne conosciamo il nome...
event.target significa appunto “colui su cui si è scatenato l’evento”.
Citazione:
Per gli utenti delle versioni precedenti...
Le Proprietà alpha, scaleX e scaleY non sono espresse con valori da 0 a 100 come vi aspettereste... in AS3 queste Proprietà variano da 0 a 1.
|
Proviamo il filmato e vediamo come muore la mosca se facciamo click su di essa.
Si, ma ancora non si muove!
Non vi piace vincere facile? Allora dovremo fare in modo che la mosca scappi invece di stare ferma.
Per fare muovere la mosca utilizzeremo un altro evento, questa volta un evento che accade di continuo, così che il movimento della mosca sia continuo.
Decido che l’evento che fa a caso nostro è
EnterFrame.
EnterFrame è sincronizzato con la frequenza del filmato, se il filmato è impostato per girare a 12 Frame al secondo l’evento viene richiamato 12 volte al secondo, se il filmato è impostato a 60 Frame al secondo l’evento si verifica 60 volte al secondo e così via.
Codice:
unaMosca.addEventListener(Event.ENTER_FRAME, muovi);
L’aggiunta dell’Ascoltatore di Evento funziona nello stesso modo di prima, però questo sta ad ascoltare i Fotogrammi e non il Mouse... inoltre il nome della funzione da richiamare è cambiato, questa volta si chiama
muovi.
Come è facile comprendere, adesso dobbiamo scrivere una funzione, chiamata muovi, che sposti la mosca di qua e di la...
Codice:
function muovi(event):void {
var myX = Math.round(event.target.x);
var myY = Math.round(event.target.y);
event.target.destX = Math.round(event.target.destX);
event.target.destY = Math.round(event.target.destY);
if (isNaN(event.target.destX) ) {
event.target.destX = Math.random()*(stage.width);
event.target.destY = Math.random()*(stage.height);
}
event.target.x -= (event.target.x-event.target.destX)/10;
event.target.y -= (event.target.y-event.target.destY)/10;
}
Mamma mia! Questa è difficile!!!
No, adesso vediamo riga per riga cosa vuol dire...
Citazione:
var myX = Math.round(event.target.x);- La posizione orizzontale del nostro MovieClip (event.target.x)
- Arrotondata per non avere numeri con la virgola che potrebbero dare fastidio (Math.round)
- La conserviamo in una variabile (var myX).
|
Citazione:
var myY = Math.round(event.target.y);- La posizione verticale del nostro MovieClip (event.target.y)
- Arrotondata per non avere numeri con la virgola che potrebbero dare fastidio (Math.round)
- La conserviamo in una variabile (var myY).
|
Citazione:
event.target.destX = Math.round(event.target.destX);- La posizione orizzontale di destinazione (event.target.destX)
- Deve essere arrotondata per non avere numeri con la virgola che potrebbero dare fastidio (Math.round)
|
Citazione:
event.target.destX = Math.round(event.target.destX);- La posizione verticale di destinazione (event.target.destY)
- Deve essere arrotondata per non avere numeri con la virgola che potrebbero dare fastidio (Math.round)
|
Citazione:
if (isNaN(event.target.destX) ) {- Se per caso (if)
- La posizione orizzontale di destinazione (event.target.destX)
- Non è un numero (isNaN)
|
La condizione IF serve a compiere delle azioni soltanto in determinati casi.
Se la condizione del codice qui sopra non è vera (cioé se il valore di destX è già un numero) esiste allora i due blocchi di codice che seguono saranno ignorati.
Citazione:
event.target.destX = Math.random()*(stage.width);- La posizione orizzontale di destinazione (event.target.destX)
- Deve essere un numero a caso (Math.random) tra ZERO e...
- ...la larghezza dello Stage (stage.width)
|
Citazione:
event.target.destY = Math.random()*(stage.height);- La posizione verticale di destinazione (event.target.destY)
- Deve essere un numero a caso (Math.random) tra ZERO e...
- ...l’altezza dello Stage (stage.height)
|
Finito il codice che si esegue una sola volta e che è contenuto dentro la condizione IF, troviamo due righe che vengono eseguite comunque:
Citazione:
event.target.x -= (event.target.x-event.target.destX)/10;- La posizione orizzontale del MovieClip (event.target.x)
- Deve decrescere (-=)
- Di un decimo (/10)
- Della distanza che c’è tra la posizione attuale e la posizione di destinazione (event.target.x-event.target.destX)
|
Citazione:
event.target.y -= (event.target.y-event.target.destY)/10;- La posizione orizzontale del MovieClip (event.target.y)
- Deve decrescere (-=)
- Di un decimo (/10)
- Della distanza che c’è tra la posizione attuale e la posizione di destinazione (event.target.y-event.target.destY)
|
Sono queste ultime due righe a compiere il vero movimento, il resto della funzione erano solo variabili che ci servivano per arrivare a questo risultato.
Adesso proviamo il filmato per vedere che succede...
La mosca si muove!!!
Se Clicco su di essa muore!!!
Ma che succede... la mosca ha fatto un movimento e poi si è fermata... come mai?
Ah... è vero... la posizione di destinazione è stata generata a caso una sola volta, adesso voglio che la posizione venga generata di continuo... non è che possiamo giocare con la mosca che si ferma!
Alla funzione muovi aggiungiamo tre righe... un’altra condizione IF che dice se la mosca ha raggiunto le coordinate di destinazione, cambia le coordinate di destinazione scegliendo altri due numeri a caso...
Codice:
function muovi(event):void {
var myX = Math.round(event.target.x);
var myY = Math.round(event.target.y);
event.target.destX = Math.round(event.target.destX);
event.target.destY = Math.round(event.target.destY);
if (isNaN(event.target.destX) || isNaN(event.target.destY)) {
event.target.destX = Math.random()*(stage.width);
event.target.destY = Math.random()*(stage.height);
} else if (myX == event.target.destX && myY == event.target.destY) {
event.target.destX = Math.random()*550;
event.target.destY = Math.random()*400;
}
event.target.x -= (event.target.x-event.target.destX)/10;
event.target.y -= (event.target.y-event.target.destY)/10;
}
Le righe aggiunte sono evidenziate in rosso, ormai dovreste essere in grado di leggerle.
Ultimo ritocco
Una volta uccisa, la mosca continua a scappare, vero?
Questo perché continua ad ascoltare l’evento ENTER_FRAME che ne regola il movimento.
Quello che dobbiamo fare è rimuovere l’Ascoltatore di evento, e lo faremo all’interno della funzione
muori, in questo modo:
Codice:
function muori(event:MouseEvent):void {
event.target.alpha = .5;
event.target.scaleX = 1.5;
event.target.scaleY = 1.5;
event.target.rotation = 135;
unaMosca.removeEventListener(Event.ENTER_FRAME, muovi);
}
Così il filmato è finito, possiamo provare l’emozione di uccidere una mosca sullo schermo, non è esaltante?
Per chi non ha seguito fino a qui ma vuole solo lo script senza interruzioni, ecco come appare per intero...
Codice:
var unaMosca:mosca = new mosca();
addChild(unaMosca);
unaMosca.addEventListener(MouseEvent.CLICK, muori);
unaMosca.addEventListener(Event.ENTER_FRAME, muovi);
function muori(event:MouseEvent):void {
event.target.alpha = .5;
event.target.scaleX = 1.5;
event.target.scaleY = 1.5;
event.target.rotation = 135;
unaMosca.removeEventListener(Event.ENTER_FRAME, muovi);
}
function muovi(event):void {
var myX = Math.round(event.target.x);
var myY = Math.round(event.target.y);
event.target.destX = Math.round(event.target.destX);
event.target.destY = Math.round(event.target.destY);
if (isNaN(event.target.destX) || isNaN(event.target.destY)) {
event.target.destX = Math.random()*(stage.width);
event.target.destY = Math.random()*(stage.height);
} else if (myX == event.target.destX && myY == event.target.destY) {
event.target.destX = Math.random()*550;
event.target.destY = Math.random()*400;
}
event.target.x -= (event.target.x-event.target.destX)/10;
event.target.y -= (event.target.y-event.target.destY)/10;
}
Ma come? Un post così lungo per un codice così breve?
Ebbene si... sono un po’ prolisso, ma spero anche di essere esauriente.