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.
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.
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.
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.