Due volte al mese, rivisitiamo alcuni dei post preferiti dei nostri lettori da tutta la storia di Activetuts +. Questo tutorial è stato pubblicato per la prima volta un anno fa a gennaio 2010.
In questo tutorial imparerai come usare la classe DisplacementMapFilter di AS3 per creare un effetto di distorsione statica riutilizzabile per i rollover dei pulsanti.
Diamo un'occhiata al risultato finale su cui lavoreremo:
Una mappa di spostamento funziona utilizzando i valori di colore di un'immagine per modificare la posizione dei pixel in un'altra immagine. Questo effetto viene spesso utilizzato per creare una "grafica" piatta attorno a un'immagine dimensionale. Lo useremo qui per distorcere un pulsante in modo che sembri ricevere interferenze statiche.
Puoi leggere ulteriori informazioni sulla mappatura degli spostamenti qui.
Crea un nuovo file Flash (ActionScript 3).
Le impostazioni del film variano a seconda del gioco. Per questa demo sto configurando il mio film come 500x300, sfondo nero e 30 fps.
Crea un nuovo simbolo di pulsante sullo stage (Inserisci> Nuovo simbolo). Disegna i 4 stati per il tuo pulsante. Il design esatto dovrebbe essere qualcosa che corrisponde al tuo gioco. Qualcosa di brillante e semi-trasparente funziona bene con questo effetto.
Ho usato un font chiamato Genetrix Square per il mio, ma dovresti usare qualcosa che corrisponda all'aspetto del tuo gioco.
Dai al tuo pulsante un nome di istanza di "button1".
Se salvi e metti alla prova il tuo film (Controllo> Prova filmato) ora dovresti vedere il tuo pulsante sul palco rispondendo al mouse con gli stati di rollover che hai progettato. Come questo:
Abbiamo bisogno di aggiungere funzionalità personalizzate al nostro pulsante. Lo faremo creando una nuova classe personalizzata e inserendo il nostro semplice pulsante.
Creare un nuovo file ActionScript denominato "JitteryButton.as". Salva questo file nella stessa directory del tuo file Flash principale. Aggiungi questo codice per creare il wrapper per il nostro pulsante:
pacchetto import flash.display.Sprite; import flash.display.SimpleButton; public class JitteryButton estende Sprite private var myButton: SimpleButton; // contiene il riferimento al nostro semplice pulsante // CLASS CONSTRUCTOR public function JitteryButton (button: SimpleButton) myButton = button; // il pulsante sul palco viene passato in
Tutto questo codice fino ad ora è accettare il semplice pulsante e memorizzare un riferimento ad esso. Aggiungeremo più funzionalità in seguito.
Crea un nuovo file ActionScript denominato 'Game.as'. Questa sarà la classe del documento per il nostro film. Salvalo nella stessa directory del file Flash principale.
Questo codice aggiungerà il nostro pulsante personalizzato attorno al pulsante sul palco:
package import flash.display.MovieClip; public class Game estende MovieClip private var startButton: JitteryButton; // CLASS CONSTRUCTOR public function Game () // crea il pulsante jitter dal semplice pulsante sullo stage startButton = new JitteryButton (button1); // aggiungi il nuovo pulsante allo stage addChild (startButton);
Questo codice crea una nuova istanza della nostra classe personalizzata JitteryButton e passa il pulsante sullo stage ('button1').
Naturalmente la tua classe di documenti sembrerà molto diversa dato che avrà il codice per il tuo gioco. Qui ci occupiamo solo del codice per il nostro pulsante.
Tornando all'interno del file Flash, imposta la classe del documento su "Gioco". Ricorda, non includi l'estensione del file qui.
Se salvi e testi di nuovo il tuo film, a questo punto dovresti vedere esattamente la stessa cosa di quando abbiamo provato nel passaggio 4. L'unica differenza è che ora il nostro codice è impostato per poter aggiungere il nostro comportamento personalizzato.
Ora creeremo l'immagine del pattern statico che useremo per distorcere la grafica del pulsante.
Apri Photoshop e crea una nuova immagine riempita di grigio neutro (# 808080). L'immagine dovrebbe essere leggermente più larga del tuo pulsante e circa 3 o 4 volte più in alto. Il mio pulsante è 277x56 e la mia immagine è 310x220.
Iniziamo con un grigio neutro perché ciò non influirà sulla nostra immagine.
Ora aggiungeremo un po 'di rumore alla nostra immagine. Questo non sarà molto evidente nel nostro effetto statico, ma dona un tocco di luminosità in più. Puoi saltare questo passaggio se vuoi.
Duplica il livello di sfondo e chiama il nuovo livello "Rumore". Ora dovresti avere 2 livelli pieni di grigio neutro. Seleziona il nuovo livello di rumore e scegli Filtro> Disturbo> Aggiungi disturbo. Impostato Quantità al 120% e Distribuzione all'uniforme. Dai un'occhiata Monocromatico.
Hit OK.
Imposta il livello "Rumore" su un'opacità del 10%.
Crea un nuovo livello chiamato 'Linee'. Ora usa un pennello a matita 1px per aggiungere alcune linee orizzontali nere e grigie all'immagine.
Ricorda come queste linee influenzeranno la nostra immagine: qualsiasi cosa più scura della neutra sposta la nostra immagine in una direzione e qualsiasi cosa più leggera la sposterà nell'altra.
Scegli File> Salva per Web e dispositivi e salva l'immagine come un gif a 8 colori denominato 'staticMap.gif'.
Di nuovo in Flash, importa "staticMap.gif" nella tua libreria (File> Importa> Importa nella libreria?). Apri le proprietà del collegamento, verifica Esporta per ActionScript, e imposta il nome della classe su "StaticMap".
Possiamo ora fare riferimento a questa immagine nel nostro codice usando il nome della classe StaticMap.
Aggiungi questa funzione alla tua classe JitteryButton:
// crea la funzione privata filter map di spostamento createDMFilter (): DisplacementMapFilter var mapBitmap: BitmapData = new StaticMap (0,0); // usa i dati bitmap dalla nostra immagine StaticMap var mapPoint: Point = new Point (0, 0); // posizione dell'immagine StaticMap in relazione al nostro pulsante var channels: uint = BitmapDataChannel.RED; // quale colore usare per la varianza var componentX: uint = channels; var componentY: uint = canali; var scaleX: Number = 5; // la quantità di spostamento orizzontale var scaleY: Number = 1; // la quantità di spostamento verticale var mode: String = DisplacementMapFilterMode.COLOR; var color: uint = 0; var alfa: Number = 0; restituisce nuovo DisplacementMapFilter (mapBitmap, mapPoint, componentX, componentY, scaleX, scaleY, mode, color, alpha);
Questa funzione crea semplicemente il Filtro mappa di spostamento utilizzando BitmapData dalla nostra immagine StaticMap. Questo non ha bisogno di essere nella sua funzione, lo sto facendo solo per chiarezza.
Per funzionare, dovremo importare queste classi nella parte superiore della nostra classe JitteryButton:
import flash.display.BitmapData; import flash.display.BitmapDataChannel; import flash.filters.DisplacementMapFilter; import flash.filters.DisplacementMapFilterMode; import flash.geom.Point;
(Per ulteriori informazioni sulla classe DisplacementMapFilter nella documentazione AS3)
Ora creeremo una variabile per contenere il filtro. Lo applichiamo al pulsante impostando la proprietà 'filters' del pulsante su una matrice che contiene il nostro filtro.
Ecco la classe JitteryButton finora (le righe 18 e 25 sono nuove):
pacchetto import flash.display.Sprite; import flash.display.SimpleButton; import flash.display.BitmapData; import flash.display.BitmapDataChannel; import flash.filters.DisplacementMapFilter; import flash.filters.DisplacementMapFilterMode; import flash.geom.Point; import caurina.transitions.Tweener; public class JitteryButton estende Sprite private var myButton: SimpleButton; // crea una variabile per contenere il filtro della mappa di spostamento private var dmFilter: DisplacementMapFilter = createDMFilter (); // CLASS CONSTRUCTOR public function JitteryButton (pulsante: SimpleButton) myButton = pulsante; // applica il filtro al pulsante myButton.filters = new Array (dmFilter); // crea la funzione privata filter map di spostamento createDMFilter (): DisplacementMapFilter var mapBitmap: BitmapData = new StaticMap (0,0); // usa i dati bitmap dalla nostra immagine StaticMap var mapPoint: Point = new Point (0, 0); // questa è la posizione dell'immagine StaticMap in relazione al nostro pulsante var channels: uint = BitmapDataChannel.RED; // quale colore usare per la varianza var componentX: uint = channels; var componentY: uint = canali; var scaleX: Number = 5; // la quantità di spostamento orizzontale var scaleY: Number = 1; // la quantità di spostamento verticale var mode: String = DisplacementMapFilterMode.COLOR; var color: uint = 0; var alfa: Number = 0; restituisce nuovo DisplacementMapFilter (mapBitmap, mapPoint, componentX, componentY, scaleX, scaleY, mode, color, alpha);
Se salviamo e testiamo il file ora possiamo vedere il filtro della mappa di spostamento applicato al nostro pulsante:
Puoi vedere come le linee orizzontali che abbiamo disegnato nella StaticMap stanno spostando i pixel nel nostro pulsante a sinistra ea destra. La quantità di spostamento dipende dall'oscurità delle linee nell'immagine e dall'impostazione di scalaX nel nostro Filtro mappa di spostamento.
Sfortunatamente, la statica non si anima e quindi sembra piuttosto zoppa. Risolviamolo ora?
Questa è una semplice funzione che restituisce un numero intero casuale all'interno di un intervallo specificato:
// restituisce un numero casuale compreso nell'intervallo specificato (incluso) private function randRange (min: int, max: int): int var randomNum: int = Math.floor (Math.random () * (max - min + 1) ) + min; return randomNum;
Trovo che sia un po 'più facile generare valori casuali. Staremo randomizzando alcuni valori diversi per il nostro effetto statico, quindi sarà utile.
Aggiungilo alla tua classe JitteryButton.
Ci sono un paio di modi in cui possiamo animare l'effetto statico. Il primo sarà modificare la quantità di spostamento orizzontale applicato al nostro pulsante. Questo viene fatto attraverso la proprietà scaleX di DisplacementMapFilter.
Possiamo inoltre animare la posizione dell'immagine StaticMap in relazione al nostro pulsante. Ciò assicurerà che le stesse aree del pulsante non vengano sempre spostate.
Per animare l'effetto aggiungeremo una funzione chiamata 'displayStatic' che viene chiamata ogni frame per aggiornare queste due proprietà del filtro. Aggiungi questa funzione alla tua classe JitteryButton:
// ha richiamato la funzione privata ENTER_FRAME displayStatic (e: Event): void dmFilter.scaleX = randRange (fuzzMin, fuzzMax); dmFilter.mapPoint = new Point (0, randRange (0, -160)); myButton.filters = new Array (dmFilter);
La prima riga di questa funzione randomizza la quantità di spostamento orizzontale a un valore tra le variabili fuzzMin e fuzzMax. Aggiungi queste due variabili alla tua classe JitteryButton:
private var fuzzMin: int = 0; private var fuzzMax: int = 2;
La seconda riga della funzione displayStatic randomizza la posizione Y della StaticMap in relazione al nostro pulsante. Abbiamo già detto al filtro di usare la nostra immagine StaticMap, quindi abbiamo solo bisogno di aggiornare la posizione.
La terza riga applica nuovamente il filtro al nostro pulsante.
L'ultima cosa che dobbiamo fare per ottenere questa animazione è aggiungere il listener di eventi ENTER_FRAME. Aggiungi questa riga alla funzione di costruzione JitteryButton:
// inizia a mostrare l'effetto statico addEventListener (Event.ENTER_FRAME, displayStatic);
E non dimenticare di importare la classe Event nella parte superiore del file JitteryButton:
import flash.events.Event;
Se salvi e metti alla prova il film, vedrai che l'effetto sta facendo brillare e saltare il nostro pulsante:
È piuttosto interessante, ma vogliamo che anche l'effetto reagisca al mouse. in avanti?
Ora aggiungeremo due funzioni per regolare l'intensità dell'effetto jitter. Chiameremo l'effetto che abbiamo attualmente a bassa intensità, quindi aggiungeremo un'impostazione per l'intensità media e alta. Aggiungi queste funzioni alla tua classe JitteryButton:
// aumenta l'intensità dello statico in MEDIA funzione privata setStaticMedium (e: MouseEvent = null): void fuzzMin = 2; fuzzMax = 6; staticLength = randRange (8, 12); // aumenta l'intensità dello statico in funzione privata HIGH setStaticHigh (e: MouseEvent = null): void fuzzMin = 12; fuzzMax = 25; staticLength = 12;
Puoi vedere che stiamo regolando l'intensità impostando i valori delle variabili fuzzMin e fuzzMax. In questo modo la nostra funzione displayStatic utilizzerà questi nuovi valori quando imposta lo spostamento orizzontale del filtro.
Abbiamo anche aggiunto una variabile chiamata staticLength. Lo useremo per impostare quanto a lungo dovrebbe durare l'effetto più intenso (il numero di fotogrammi) prima di tornare a bassa intensità. Aggiungi questa variabile alla tua classe JitteryButton e modifica la tua funzione displayStatic in questo modo:
private var staticLength: int; // ha richiamato la funzione privata ENTER_FRAME displayStatic (e: Event): void dmFilter.scaleX = randRange (fuzzMin, fuzzMax); dmFilter.mapPoint = new Point (0, randRange (0, -160)); myButton.filters = new Array (dmFilter); staticLength--; if (staticLength <= 0) fuzzMin = 0; fuzzMax = 2;
Questo nuovo codice decrementa la variabile staticLength e ripristina fuzzMin e fuzzMax sui valori di bassa intensità una volta che il valore di staticLength raggiunge lo zero.
Per far reagire il nostro pulsante al mouse, è necessario aggiungere due listener di eventi del mouse e una funzione di gestore di eventi per ciascuno.
Aggiungi i listener del mouse nella funzione di costruzione della tua classe JitteryButton:
// aggiungi i listener di eventi di rollover al pulsante myButton.addEventListener (MouseEvent.ROLL_OVER, onButtonRollOver); myButton.addEventListener (MouseEvent.ROLL_OUT, onButtonRollOut);
Ora creare i due gestori di eventi a cui si fa riferimento in queste due nuove linee. Anche questi vanno nella classe JitteryButton:
// ha chiamato il pulsante ROLL_OVER private function onButtonRollOver (e: MouseEvent): void setStaticHigh (); // pulsante di chiamata tasto ROLL_OUT funzione privata onButtonRollOut (e: MouseEvent): void setStaticMedium ();
Per fare in modo che tutto funzioni, dovremo importare la classe MouseEvent nella parte superiore del nostro file JitteryButton:
import flash.events.MouseEvent;
Ora quando il nostro pulsante rileva un evento ROLL_OVER chiamerà il gestore di eventi che a sua volta chiama la nostra funzione setStaticHigh. Questa funzione aumenta i valori di fuzzMin e fuzzMax (usati per impostare lo spostamento orizzontale) per la durata specificata dalla variabile staticLength.
Potremmo fermarci qui. Il nostro effetto si sta animando bene e reagisce ai rollover del mouse. Mi sento ancora come se mancasse qualcosa qui. Aggiungiamo un piccolo effetto di ridimensionamento.
Dovrai scaricare la Libreria Tweener per questo passaggio se non lo hai già. Posiziona la cartella "caurina" nella directory del progetto e importa le classi Tweener nella parte superiore del tuo file JitteryButton:
import caurina.transitions.Tweener;
Tweener ci consente di aggiungere alcuni effetti di ridimensionamento con solo un paio di linee di codice. Possiamo aggiungere una riga a ciascuno dei nostri gestori di eventi di rollover:
// pulsante di chiamata ROLL_OVER funzione privata onButtonRollOver (e: MouseEvent): void Tweener.addTween (myButton, scaleX: 1.1, time: .5, transition: "easeOutElastic"); setStaticHigh (); // Pulsante di chiamata ROLL_OOUT funzione privata onButtonRollOut (e: MouseEvent): void Tweener.addTween (myButton, scaleX: 1, time: .5, transition: "easeOutElastic"); setStaticMedium ();
Qui stiamo aggiungendo un'animazione al gestore rollover che ridimensiona la proprietà scaleX del pulsante al 110% su 0,5 secondi. Stiamo usando un tipo di transizione elastica per dargli quella sensazione di rimbalzo. Nel gestore di rollover stiamo facendo la stessa cosa al contrario, ridimensionandolo al 100%.
È possibile ottenere ulteriori informazioni su come utilizzare Tweener nella documentazione Tweener.
L'ultima cosa che dobbiamo fare per completare questo effetto è aggiungere un po 'di suono. Ho realizzato il mio effetto sonoro in Garage Band. Puoi crearne uno o provare a trovarne uno online.
Una volta che ne hai uno, importalo nella tua libreria e imposta il collegamento da esportare come "StaticSound".
Per aggiungerlo al nostro JitteryButton dobbiamo prima importare la classe Sound:
import flash.media.Sound;
Quindi inizializzeremo (aggiungi questa riga subito prima della funzione di costruzione):
private var staticSound: Sound = new StaticSound ();
All'interno del gestore rollover diremo al suono di suonare:
// pulsante di chiamata ROLL_OVER funzione privata onButtonRollOver (e: MouseEvent): void Tweener.addTween (myButton, scaleX: 1.1, time: .5, transition: "easeOutElastic"); setStaticHigh (); staticSound.play ();
Ora siamo a posto. Metti alla prova il tuo film e tutto dovrebbe funzionare. Se il tuo pulsante o suono non funziona correttamente, controlla i file sorgente per vedere la mia classe JitteryButton completata.
La cosa bella della creazione di questo effetto come una classe separata che avvolge il nostro pulsante è che possiamo facilmente riutilizzarlo su altri pulsanti.
Se vuoi aggiungere altri pulsanti al tuo menu di gioco, basta creare un nuovo pulsante e aggiungerlo al palco. Dagli il nome dell'istanza 'button2'. Quindi all'interno della classe del documento (il file 'Game.as') crea un nuovo JitteryButton e passa il nuovo pulsante. Ecco come potrebbe apparire:
package import flash.display.MovieClip; public class Game estende MovieClip private var startButton: JitteryButton; private var menuButton: JitteryButton; // CLASS CONSTRUCTOR function function Game () // crea i pulsanti jittery dai pulsanti semplici sullo stage startButton = new JitteryButton (button1); addChild (startButton); // aggiungere un nuovo pulsante è facile! menuButton = new JitteryButton (button2); addChild (MenuButton);
Quasi sicuramente dovrai modificare questo codice per adattarlo alla struttura del tuo gioco. Speriamo che questo tutorial ti dia un buon punto di partenza.
Se vuoi cambiare l'aspetto di questo effetto puoi provare a utilizzare diversi tipi di immagini per il tuo grafico StaticMap e ad aggiustare i valori per fuzzMin e fuzzMax.
Questo è il mio primo tutorial quindi fammi sapere se c'è qualcosa che posso fare meglio la prossima volta. Grazie per aver letto!