Creare l’effetto Time Machine di Leopard in Actionscript 3.0

28 ottobre 2011

Per applicazioni 3D con poche funzionalità esistono dei motori, meno complessi e strutturati di PaverVision 3D 2.0 oppure Sandy3D engine, che sono più veloci in esecuzione come, per esempio, il pacchetto Novio Simple 3D che permette di gestire degli oggetti su di una superficie multipiano sufficiente a realizzare l’effetto Time Machine di Leopard, il sistema operativo di Mac.

Questo effetto vede un treno di contenuti visuali, uno dietro l’altro, distribuiti in profondità, permettendoci di avvicinarci o allontanarci ad ogni singolo contenuto, portandolo in primo piano e riposizionando gli altri. È dunque un effetto utilizzabile per gallerie di immagini o video e, volendo, integrabile con un menu che punta direttamente ai vari contenuti.

Per la stesura di questo articolo useremo come ambiente di sviluppo, Flash Builder 4.0.

Lo sviluppo

Per iniziare scarichiamo il pacchetto Novio Simple 3D dal sito e poi, premesso che l’esigenza è quella di creare una galleria dinamica che interfaccia un flusso dati XML, caricando immagini esterne, creiamo un ambiente di file system adeguato a questo scopo.

Figura 1 – Time Machine Gallery

Time Machine Gallery

Creiamo ora una cartella immagini che chiameremo img, nella quale inseriremo tutte le immagini vogliamo mostrare, e una cartella xml ,nella quale metteremo il file items.xml che formatteremo nel seguente modo:

<?xml version="1.0" encoding="UTF-8"?>
	<ITEMS>
		<ITEM url="img/0.jpg"/>
		<ITEM url="img/1.jpg"/>
		<!-- ..e così via.. -->
	</ITEMS>

Ogni nodo ITEM rappresenta un’immagine e riporta l’attributo url.

Ora che il file system è pronto, avviamo lo sviluppo in AS3. Avviamo Flash Builder e creiamo un nuovo progetto Actionscript nominandolo TimeMachine e scegliamo dove salvarlo.

Figura 2 – Nuovo progetto in Flash Builder

Nuovo progetto in Flash Builder

Dopo che Flash Builder avrà creato la struttura delle cartelle, copiamo il pacchetto Novio scaricato dentro la cartella src in modo da poterlo importare in seguito.

TimeMachine.as è la classe principale, che interfaccia l’SWF. Specifichiamo al suo interno i settaggi di pubblicazione dell’SWF come la dimensione, colore dello sfondo e frame rate subito sotto gli import:

[SWF(width="800",height="600",backgroundColor="0x000000",frameRate="24")]

Dentro un pacchetto app creiamo due classi che serviranno per il nostro applicativo: Gallery, che avrà funzione di manager degli oggetti sottoposti, e GalleryItem rappresentativa di questi ultimi.

Figura 3 – Struttura delle cartelle

Struttura delle cartelle

Inziamo dalla classe pricipale, TimeMachine.as, e carichiamo in cache l’XML che ci servirà da sorgente dati per i vari caricamenti di immagini esterne.

Sviluppiamo una funzione loadData che richiameremo direttamente nel costruttore TimeMachine e definiamo che, a caricamento avvenuto, debba essere creato e aggiunto alla DisplayList un oggetto di tipo Gallery.

private function loadData():void{ 
	//carico i dati da xml
	var _xmlLoader:URLLoader = new URLLoader();
	_xmlLoader.addEventListener(Event.COMPLETE, onDataLoaded);
	_xmlLoader.load(new URLRequest("../xml/items.xml"));
}

private function onDataLoaded(e_:Event):void {			
	e_.target.removeEventListener(Event.COMPLETE, onDataLoaded);
	XML.ignoreWhitespace = true;
	var _xml:XML = new XML(e_.target.data);

    //creo oggetto galleria
    gallery = new Gallery(_xml.ITEM)
    gallery.x = 800/2
    gallery.y = 100
    //aggiungo l'oggetto alla DisplayList
    addChild(gallery)
}

Definiamo ora il comportamento di Gallery.as nella quale dovremo, analizzando l’XML caricato e proveniente da TimeMachine.as, istanziare gli oggetti GalleryItem.

public function Gallery(xmlList_:XMLList){
	//prelevo l'xml dal costruttore
	xmlList = xmlList_;

	//creo gli oggetti della gallery e li archivio in un array
	sceneObjects = [];
	for (var _i:uint = 0; _i < xmlList.length(); _i++){
		var _galleryItem:GalleryItem = new GalleryItem(xmlList[_i])
		//definisco la profondità dell'oggetto nella scena
		_galleryItem.zpos = _i * zOffset;
		sceneObjects.push(_galleryItem);
			
		//definisco la lunghezza del campo focale, ovvero la profondità della vista della mia camera
		var $focalLength:Number = 200;
		//creo una camera multipiano, classe messa a disposizione dal pacchetto Novio
		cameraView = new MultiplaneCamera(0, 0, 0, 0, $focalLength); 
		//do delle dimensioni alla camera creata in larghezza, altezza e profondità, 
        //per cui la camera mostrerà solo gli oggetti presenti all'interno di questi confini
		cameraView.setBounds(-1500, 800, 0, sceneObjects.length * $focalLength*2); 
		
        //creo un controller per la camera che, per questo esempio sfrutta l'interazione da tastiera con 
        //le frecce su e giù, ma per un'applicazione più complessa potrebbe vedere l'interazione da un menu per esempio
		cameraController = new CameraController(cameraView);
        
		//creao una scena, classe del pacchetto Novio, alla quale assegno la camera creata, 
        //il controller e tutti gli oggetti che voglio rappresentare nella scena stessa			
		scene = new MultiplaneScene(cameraView, cameraController, sceneObjects);
	
		//aggiungo la scena alla DisplayList	
		addChild(scene);
	}
}

Ora passiamo al comportamento di GalleryItem.as che dovrà caricare l'immagine esterna e esistere nella mia scena pseudo 3D. Per quest'ultimo motivo questa classe non estenderà semplicemente Sprite ma Figure, una classe del pacchetto Novio che è in pratica uno Sprite con l'attributo profondità.

public class GalleryItem extends Figure

inoltre definiamo il metodo di caricamento dell'immagine e la sua visualizzazione una volta caricata. Affidiamo sempre il serverPath ad una variabile statica che centralizziamo in una classe di servizio Globals.as per elasticità dell'applicativo.

private function loadPic():void{
	//carico l'immagine creando prima la request e poi il loader cui darla in pasto
	loader = new Loader()
	var _rew:URLRequest = new URLRequest(Globals.serverPath + String(xmlData.@url))
	loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onPicLoaded)
	loader.load(_rew)
}

//definisco cosa succede una volta caricata
private function onPicLoaded(e_:Event):void{
	loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onPicLoaded)
			
	//centro l'immagine spostandola in alto e a sinistra per le sue due metà
	loader.x = - loader.width/2
	loader.y = - loader.height/2
	
	//la aggiungo alla DisplayList			
	addChild(loader)
}

Con questo ultimo passaggio concludiamo la mostra Time Machine, invitandovi a visualizzare la demo.

Se vuoi aggiornamenti su Creare l'effetto Time Machine di Leopard in Actionscript 3.0 inserisci la tua e-mail nel box qui sotto:
 
X
Se vuoi aggiornamenti su Creare l'effetto Time Machine di Leopard in Actionscript 3.0

inserisci la tua e-mail nel box qui sotto:

Ho letto e acconsento l'informativa sulla privacy

Acconsento al trattamento di cui al punto 3 dell'informativa sulla privacy