Movimento 5 Stelle
 

24. Display List


Con ActionScript 3 è stato introdotto un nuovo sistema di visualizzazione in Flash, molto più simile a JavaScript piuttosto che ad ActionScript 2.

Come nel suo predecessore abbiamo un elemento radice (root) in cui ha origine la Display List, che in ActionScript 3 viene identificato dallo Stage.

Lo Stage conterrà l'istanza della Classe Documento che a sua volta conterrà oggetti da visualizzare o altri contenitori di oggetti da visualizzare, ossia sottoclassi delle classi native DisplayObject e DisplayObjectContainer.

Per rendere un oggetto compatibile con la Display List quindi, questo oggetto dovrà appartenere ad una classe che deriva dalle classi native sopracitate, attraverso le classi più complesse che ActionScript 3 ci mette a disposizione :

Derivate da DisplayObject

  • AVM1MovieBitmap
  • InteractiveObject
  • MorphShape
  • Shape
  • StaticText
  • Video

Derivate da DisplayObjectContainer

  • Loader
  • Sprite
  • Stage

Ovviamente sarà possibile inserire nella Display List, anche oggetti che non derivano direttamente da queste classi, ma da classi che derivano a loro volta da quelle sopracitate, come nel caso della classe MovieClip che deriva dalla classe Sprite.
Sarà quindi sufficiente creare una classe Filmato che deriva direttamente da MovieClip, poichè anche quest'ultima possiederà le proprietà necessarie essendo derivata di Sprite.

La Display List è una struttura gerarchica ad albero, quindi se un ramo è collegato alla radice diviene visibile.
Potremo aggiungere nuovi elementi creando nuovi "rami" collegati alla radice o collegati direttamente ad altri "rami" collegati a loro volta alla radice.

Sarà comunque possibile aggiungere degli elementi a dei rami non collegati alla radice, quindi fuori dalla Display List, che diverranno visibili non appena il contenitore di questi elementi (ramo) verrà inserito in elenco.

Vediamo le funzioni principali che ci consentono di aggiungere e di rimuovere degli elementi (istanze di classi) dalla Display List, disponibili per tutte le classi derivate da DisplayObjectContainer :

  • addChild(child) - aggiunge un'istanza all'istanza DisplayObjectContainer da cui viene chiamato il metodo
  • addChildAt(child, index) - come addChild() ma posiziona l'elemento all'indice specificato
  • removeChild(child) - rimuove l'istanza specificata dal contenitore
  • removeChildAt(index) - rimuove l'istanza presente nella posizione indicata

Per concludere vediamo un semplice esempio che sfrutta i metodi sopra indicati.
L'esempio è composto da 3 classi :

  • HelloWorld - La classe documento che inizializzerà l'istanza principale dell'SWF. Quest'ultima viene automaticamente aggiunta alla Display List da Flash, collegandola allo Stage a inizio filmato.
  • Rettangolo - Classe contenitore che una volta inizializzata disegna un rettangolo alla posizione indicata e delle dimensioni specificate nel costruttore, e poi aggiunge il rettangolo alla propria Display List.
  • Disegnatore - Classe che disegna N rettangoli e li aggiunge alla propria Display List.

disegno/Rettangolo.as

package disegno
{
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.MouseEvent;

	public class Rettangolo extends Sprite // estende Sprite, deriva quindi da DisplayObjectContainer
	{
		private var figura:Shape; // Shape deriva da DisplayObject

		public function Rettangolo(X:uint, Y:uint, W:uint, H:uint):void
		{
			this.figura = new Shape();

			this.figura.graphics.beginFill(0x00FF00);
			this.figura.graphics.lineStyle(1, 0x0000FF);
			this.figura.graphics.drawRect(X, Y, W, H);
			this.figura.graphics.endFill();

			/* Aggiungiamo un listener che rimuoverà "figura" dalla
			DisplayList quando l'utente vi cliccherà sopra */
			this.addEventListener(MouseEvent.CLICK, rimuovi);
			this.addChild(this.figura);
		}

		private function rimuovi(evt:MouseEvent):void
		{
			this.removeChild(this.figura);
		}
	}
}

disegno/Disegnatore.as

package disegno
{
	import disegno.Rettangolo;
	import flash.display.Sprite;

	public class Disegnatore extends Sprite
	{
		private var rettangoli:Array;

		public function Disegnatore(num:uint):void
		{
			this.rettangoli = new Array();

			for (var i:uint = 0; i < num; i++)
			{
				this.rettangoli[i] = new Rettangolo(i * 60 + 10, 10, 50, 50);
				this.addChild(this.rettangoli[i]);
			}
		}
	}
}

HelloWorld.as

package
{
	import disegno.Disegnatore;
	import flash.display.MovieClip;

	public class HelloWorld extends MovieClip
	{
		public function HelloWorld():void
		{
			/* Creiamo 3 rettangoli e li aggiungiamo ad un contenitore "disegno" che sarà
			un'istanza della classe "Disegnatore" derivata da Sprite (DisplayObjectContainer) */
			var disegno:Disegnatore = new Disegnatore(3);

			// Ora aggiungiamo il contenitore "disegno" alla Display List collegata allo Stage
			this.addChild(disegno);
		}
	}
}

Sostituite il codice all'interno del costruttore della classe Disegnatore con i due blocchi seguenti per studiarne gli effetti.

this.rettangoli = new Array();

for (var i:uint = 0; i < num; i++)
{
	this.rettangoli[i] = new Rettangolo(i * 20 + 10, 10, 50, 50);
	this.addChild(this.rettangoli[i]);
}

Il blocco soprastante fa sovrapporre i 3 rettangoli riducendo la coordinata x per ognuno.
Come potete osservare eseguendo il codice, i rettangoli vengono inseriti uno dopo l'altro portando in primo piano l'ultimo inserito.

this.rettangoli = new Array();

for (var i:uint = 0; i < num; i++)
{
	this.rettangoli[i] = new Rettangolo(i * 20 + 10, 10, 50, 50);
	this.addChildAt(this.rettangoli[i], 0);
}

Il codice soprastante usa addChildAt() al posto di addChild(), aggiungendo i rettangoli sempre alla posizione 0.

La funzione addChildAt() infatti, se trova un altro elemento già presente nella posizione indicata, lo sposta in alto nell'elenco di visualizzazione.