ActionScript 3

Installare Flex e FlashDevelop


In questo tutorial vi fornirò gli strumenti per creare un ambiente di sviluppo gratuito, che ci consentirà di realizzare nuovi filmati Flash, utilizzando solo ed esclusivamente software free ed open source.

6. Classe Documento

Con il presente capitolo concludiamo finalmente questo tutorial, introducendo il codice di una Classe Documento che utilizzerà la classe TestoDinamico per animare il testo "Realizzazione-Sito.info".

Scrivo direttamente il codice interessato spiegandolo attraverso i commenti nel sorgente.

HelloWorld.as

package
{
	import flash.events.Event;
	import flash.text.TextFormat;
	import flash.display.MovieClip;
	import fl.transitions.easing.*;
	import rsinfo.dtext.TestoDinamico;
	import rsinfo.dtext.TDinamicoEvent;

	public class HelloWorld extends MovieClip
	{
		public function HelloWorld():void
		{
			// Imposto il framerate del filmato a 32 frame al secondo
			stage.frameRate = 32;

			// Scelgo il font, la dimensione e il colore per il testo da animare
			var format:TextFormat = new TextFormat();
			format.font = "Verdana";
			format.size = 15;
			format.color = 0x3CB44A;

			// Configuro la mia istanza di "TestoDinamico"
			var txt:TestoDinamico = new TestoDinamico();
			txt.x = 30;
			txt.y = -50;

			/* Prima di assegnare il testo desiderato e di far partire l'animazione
			abbiate cura di assegnare la formattazione desiderata attraverso "defaultTextFormat" */
			txt.defaultTextFormat = format;
			txt.intervallo = 100;

			/* Prima di aggiungere l'istanza all'elenco di visualizzazione e di far
			partire l'animazione, assegniamo il testo desiderato e configuriamo l'animazione
			nel caso in cui ne desideriate una, altrimenti le lettere appariranno semplicemente
			una dietro l'altra senza alcun effetto */
			txt.testo = "Realizzazione-Sito.info";
			txt.animazione("y", Elastic.easeOut, 100, 2);

			txt.addEventListener(TDinamicoEvent.ANI_STARTED, this.eventHandler);
			txt.addEventListener(TDinamicoEvent.ANI_COMPLETE, this.eventHandler);

			this.addChild(txt);
			txt.start();
		}

		/* Questo ascoltatore non fa altro che tracciare nella
		finestra di Output gli eventi di inizio e fine animazione */
		private function eventHandler(evt:Event):void
		{
			trace(evt.type);
		}
	}
}

Questo è il risultato ottenuto.
Spero che il tutorial vi sia tornato utile.
Buon lavoro e buon divertimento.


5. Testo Dinamico

In questo capitolo analizzeremo il codice dell'ultima classe del pacchetto rsinfo.dtext, la classe TestoDinamico.

Questa sarà l'unica classe che istanzieremo nei nostri sorgenti, è quindi fondamentale capirne il funzionamento per poterne effettuare eventuali personalizzazioni.

Prima di tutto vediamo le librerie da importare necessarie :

  • import Event
    Utilizzata esclusivamente per inviare gli eventi di TDinamicoEvent nel flusso degli eventi.
  • import TextFormat
    Utilizzata nella classe per memorizzare la formattazione predefinita per tutte le lettere.
  • import Sprite
    Utilizzata per l'ereditarietà, poichè essendo la stessa Sprite derivata dalle classi DisplayObjectContainer e EventDispatcher, ci fornisce la struttura adatta al nostro scopo.
  • import Timer e TimerEvent
    Utilizzate per temporizzare la comparsa delle lettere del testo aldilà dell'animazione conferitogli.
  • import Lettera, Animazione e TDinamicoEvent
    Classi del pacchetto rsinfo.dtext illustrate singolarmente nei capitoli precedenti.

Di seguito analizziamo rapidamente gli attributi della classe.
Ho reso tutti gli attributi privati, mettendo a disposizione alcuni attributi pseudo-pubblici attraverso i metodi set e get.

  • box:Array
    Un array di istanze della classe Lettera.
  • stringa:String
    Conterrà il testo da animare in formato stringa tradizionale.
  • format:TextFormat
    Terrà in memoria la formattazione desiderata per le istanze di Lettera.
  • time:uint
    Tempo in millisecondi che stabilisce l'intervallo di apparizione fra una lettera e la seguente.
  • timer:Timer
    Istanza della classe Timer usata per temporizzare l'apparizione fra una lettera e la seguente.
  • settings:Boolean
    Flag per stabilire se è stata configurata un'animazione o se le lettere devono semplicemente apparire una dopo l'altra secondo l'intervallo time.
  • prop:String
    Stabilisce quale proprietà di Lettera deve essere considerata per un'eventuale animazione.
    Ricordo che Lettera è comunque un DisplayObject essendo derivata dalla classe Sprite, di conseguenza possiede tutti gli attributi classici come le coordinate x e y, alpha, width, height ecc...
    Se viene quindi specificata la x, l'animazione consisterà in uno spostamento della lettera da sinistra a destra o viceversa.
  • func:Function
    Indica la funzione di andamento utilizzata per implementare l'animazione di ogni lettera.
    Le funzioni di andamento sono contenute nelle classi del pacchetto fl.transitions.easing o fl.motion.easing.
  • interval:Number
    Intervallo utilizzato per calcolare i valori begin e finish dalla classe personalizzata Animazione.
  • duration:Number
    Durata in secondi dell'animazione di ogni lettera.

A seguire la lista dei metodi della classe con relativo sorgente e spiegazione.
Salterò pertanto il costruttore della classe poichè non fa altro che inizializzare alcuni attributi.


  • private function reset():void
    Azzera l'array che contiene tutte le istanze di Lettera (quindi box) e la stringa che rappresenta il testo da animare.
    Prima dell'azzeramento controlla la lunghezza dell'array e in caso in cui siano presenti degli elementi procede eliminandoli dalla lista di visualizzazione attraverso removeChild().
    private function reset():void
    {
    	if (this.box.length > 0)
    		for (var i:uint = 0; i < this.box.length; i++)
    			this.removeChild(this.box[i]);
    
    	this.box = new Array();
    	this.stringa = new String();
    }

  • public function get testo():String
    Funzione get che restituisce la stringa di testo da animare.
    public function get testo():String
    { return this.stringa; }

  • public function set testo(str:String):void
    Funzione set che inizializza gli attributi della classe istanziando un elemento dell'array per ogni lettera del testo da animare, calcolando automaticamente le coordinate dell'asse x di ogni lettera per evitare che si sovrappongano.
    public function set testo(str:String):void
    {
    	this.reset();
    	this.stringa = str;
    
    	for (var i:uint = 0; i < str.length; i++)
    	{
    		this.box[i] = new Lettera(str.charAt(i), this.format);
    
    		// Dalla seconda lettera in poi aggiungo alla x della lettera corrente la larghezza della precedente
    		if (i > 0) this.box[i].x = this.box[i - 1].x + this.box[i - 1].width;
    	}
    }

  • public function set defaultTextFormat(format:TextFormat):void
    Funzione set che memorizza la formattazione di default per tutte le lettere del testo.
    public function set defaultTextFormat(format:TextFormat):void
    { this.format = format; }

  • public function set intervallo(itv:uint):void
    Funzione set che stabilisce il tempo in millisecondi che deve intercorrere fra l'apparizione di una lettera e la seguente.
    public function set intervallo(itv:uint):void
    {
    	if (itv > 0) this.time = itv;
    	else this.time = 0;
    }

  • private function timerHandler(evt:TimerEvent):void
    Ascoltatore che viene richiamato tante volte quante il numero di lettere che compongono il testo da animare, ogni intervallo di tempo come stabilito dalla funzione "set intervallo", aggiungendo le lettere alla lista di visualizzazione e facendo partire subito dopo la relativa animazione programmata.
    Questo ascoltatore inoltre solleva l'evento TDinamicoEvent.ANI_STARTED.
    private function timerHandler(evt:TimerEvent):void
    {
    	// Se è la prima chiamata al metodo allora invia l'evento di inizio animazione
    	if (evt.currentTarget.currentCount == 1)
    		this.dispatchEvent(new Event(TDinamicoEvent.ANI_STARTED));
    
    	// Aggiunge la lettera alla lista di visualizzazione
    	this.addChild(this.box[evt.currentTarget.currentCount - 1]);
    
    	// Se è stata configurata un'animazione crea un'istanza temporanea per interpolare la lettera
    	if (this.settings)
    	{
    		var ani:Animazione = new Animazione(this.box[evt.currentTarget.currentCount - 1],
    		this.prop, this.func, this.interval, this.duration);
    		ani.anima();
    	}
    
    	/* Se è l'ultima chiamata al metodo, aspetta la durata dell'animazione ossia
    	"this.duration" e poi procede alla chiamata di "endTimer" che solleverà a sua
    	volta l'evento di fine animazione */
    	if (evt.currentTarget.currentCount == this.box.length)
    	{
    		var endTimer:Timer = new Timer(this.duration * 1000, 1);
    		endTimer.addEventListener(TimerEvent.TIMER, this.endHandler);
    		endTimer.start();
    	}
    }

  • private function endHandler(evt:TimerEvent):void
    Utilizzato dall'ascoltatore sopracitato timerHandler per sollevare l'evento di fine animazione TDinamicoEvent.ANI_COMPLETE.
    private function endHandler(evt:TimerEvent):void
    { this.dispatchEvent(new Event(TDinamicoEvent.ANI_COMPLETE)); }

  • public function start():void
    Inizia il processo di animazione attraverso l'ascoltatore timerHandler.
    public function start():void
    {
    	// Da inizio all'animazione avviando il timer gestito da "timerHandler"
    	this.timer = new Timer(this.time, this.box.length);
    	this.timer.addEventListener(TimerEvent.TIMER, this.timerHandler);
    	this.timer.start();
    }

  • public function animazione(prop:String, func:Function, itv:Number, dur:Number):void
    Metodo che consente di configurare l'animazione desiderata memorizzandola negli attributi della classe.
    public function animazione(prop:String, func:Function, itv:Number, dur:Number):void
    {
    	this.settings = true;
    	this.prop = prop;
    	this.func = func;
    	this.interval = itv;
    	this.duration = dur;
    }


In allegato il sorgente della classe TestoDinamico.

4. Eventi

Ho deciso di fornire a questo applicativo un minimo di sembianza professionale, aggiungendo anche degli eventi personalizzati che ci consentiranno di avere degli ascoltatori almeno per l'inizio e per la fine dell'animazione.

Ricordo che ogni lettera viene animata separatamente, di conseguenza intendo come inizio e fine animazione, l'inizio e la fine dell'animazione dell' INTERO testo.

Questo ci consentirà di far interagire la nostra classe con altre e ad associarla a determinati eventi utente.

A questo proposito ho creato una classe pubblica finale (enumerazione), che contiene una collezione di costanti utili a definire senza alcun margine di errore, gli eventi che vogliamo gestire per la nuova classe TestoDinamico che vedremo nel prossimo capitolo.

Classe TDinamicoEvent

package rsinfo.dtext
{
	public final class TDinamicoEvent
	{
		public static const ANI_STARTED:String = "TDAniStarted";
		public static const ANI_COMPLETE:String = "TDAniComplete";
	}
}

A questo punto per inviare l'evento desiderato è sufficiente utilizzare il metodo dispatchEvent() in questo modo :

this.dispatchEvent(new Event(TDinamicoEvent.ANI_STARTED));
this.dispatchEvent(new Event(TDinamicoEvent.ANI_COMPLETE));

In allegato il sorgente della classe TDinamicoEvent.

Nel prossimo capitolo inizieremo finalmente a costruire il nucleo vero e proprio del nostro applicativo, la classe TestoDinamico.

3. Animazione

Lo scopo della classe Animazione è solo quello di semplificare il codice riducendo il numero di parametri per configurare l'animazione vera e propria.

Inoltre ho aggiunto un metodo anima() che consente di far partire l'animazione, è quindi possibile configurarla e solo in un secondo momento riprodurla.

Questo vi consentirà di modificare il codice a vostro piacimento facendo partire l'animazione quando ad esempio l'utente clicca su un bottone e così via.

Prima di introdurre il sorgente della classe vediamo velocemente i parametri che prende il costruttore della classe Tween :

Tween(obj:Object, prop:String, func:Function, begin:Number, finish:Number, duration:Number, useSeconds:Boolean = false)

Nella classe Animazione, i parametri begin e finish vengono sostituiti dal parametro interval.

In pratica viene utilizzato come begin il valore che la proprietà ha prima che cominci l'animazione, poi viene sommato il valore di interval a begin per ottenere finish.

Di conseguenza, nel caso in cui vogliate far apparire le lettere dal nulla giocando sulla trasparenza (alpha), o assegnate da prima l'alpha di ogni lettera a zero, o ripristinate il numero di parametri togliendo interval, in modo da assegnare direttamente begin a zero e finish a cento.


Classe Animazione

package rsinfo.dtext
{
	import fl.transitions.Tween;

	internal class Animazione
	{
		private var obj:Object;
		private var prop:String;
		private var func:Function;
		private var interval:Number;
		private var duration:Number;

		public function Animazione(o:Object, p:String, f:Function, itv:Number, d:Number):void
		{
			this.obj = o;
			this.prop = p;
			this.func = f;
			this.interval = itv;
			this.duration = d;
		}

		public function anima():void
		{
			var myTween:Tween = new Tween(this.obj, this.prop, this.func, this.obj[this.prop],
				(this.obj[this.prop] + this.interval), this.duration, true);
		}
	}
}


2. Lettera

Nella presente lezione analizzeremo il codice della prima classe del pacchetto rinfo.dtext, ossia la classe Lettera.

Come già accennato nel capitolo precedente, lo scopo di questa classe è quello di rappresentare un singolo carattere attraverso la classe nativa TextField, assegnandogli la desiderata formattazione attraverso la classe TextFormat.

In questo modo potremo creare un Array di istanze della classe Lettera, per far si che ogni lettera risieda in un contenitore differente, consentendoci di animarle singolarmente creando l'effetto desiderato.

Prima di introdurre il codice sorgente vediamo al volo le librerie da importare per questa classe :

  • Sprite
    La classe Lettera deriva da Sprite, in modo da poterla sfruttare come contenitore per la Display List.
    Non usiamo MovieClip perchè le animazioni non gireranno sulla linea temporale di Lettera.
  • TextField, TextFormat e TextFieldAutoSize
    Importiamo le tre classi sopracitate per rappresentare e configurare il singolo carattere, principalmente grazie a TextField.

Classe Lettera

package rsinfo.dtext
{
	import flash.display.Sprite;

	import flash.text.TextField;
	import flash.text.TextFormat;
	import flash.text.TextFieldAutoSize;

	internal class Lettera extends Sprite
	{
		private var char:TextField;

		public function Lettera(ch:String, tf:TextFormat = null):void
		{
			this.char = new TextField();
			this.char.autoSize = TextFieldAutoSize.LEFT;
			if (tf != null) this.defaultTextFormat = tf;
			this.char.text = ch.charAt(0);

			this.addChild(this.char);
		}

		public function set defaultTextFormat(format:TextFormat):void
		{
			this.char.defaultTextFormat = format;
		}
	}
}

Come potete osservare dal codice, la classe possiede un solo attributo di tipo TextField.

Il costruttore della classe prende due parametri, il primo è il carattere da memorizzare, da notare che anche se viene specificata una stringa verrà comunque memorizzato solo il primo carattere di questa stringa attraverso il metodo charAt().

Il secondo parametro del costruttore invece è facoltativo, e consente di specificare una formattazione particolare per il nostro carattere.


In ogni caso è possibile specificare la formattazione desiderata anche in un secondo momento grazie al metodo set defaultTextFormat().



Condividi contenuti