Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Strumenti ed effetti 3D con Flash CS4

Esaminiamo gli strumenti forniti nativamente da Flash CS4 per il 3D
Esaminiamo gli strumenti forniti nativamente da Flash CS4 per il 3D
Link copiato negli appunti

Una delle novità più interessanti di Flash CS4 è la possibilità di creare alcuni effetti 3D in modo nativo, limitando la necessità di affidarsi a librerie esterne come Sandy o Papervision3D per operazioni semplici.

Per la manipolazione di modelli 3d complessi importati da programmi esterni, o creare effetti tridimensionali complessi è comunque necessario l'uso di librerie, che però si giovano delle nuove potenzialità del Flash Player 10.

A livello pratico, in Flash CS4 oltre agli assi x (orizzontale) e y (verticale) abbiamo a disposizione anche l'asse z (profondità), che possiamo sfruttare sia manualmente tramite gli strumenti di disegno di Flash oppure tramite ActionScript, grazie alle nuove proprietà .z e .rotationZ, aggiunte per gli elementi di tipo MovieClip.

In questo articolo vedremo alcuni esempi pratici di utilizzo dell'asse Z, analizzando anche i limiti del Flash Player 10.

Il sistema di coordinate

Per stabilire le coordinate Flash usa il classico sistema cartesiano costituito da 3 assi.

Figura 1. I tre assi x,y,z nel sistema cartesiano
Assi x,y e z nel sistema cartesiano e rappresentazione di un punto al suo interno

Il sistema usato da Flash è leggermente diverso: il punto di origine corrisponde al punto in alto a sinistra dello stage e l'asse Z è rivolto verso lo schermo. Quindi aumentando il valore di z otterremo un allontanamento. Vediamo un esempio:

Figura 2. Clip a diverse profondità
Clip con diverso valore per la proprietà z

I tre quadrati sono istanze di uno stesso MovieClip con il centro del MovieClip al centro della figura; il primo quadrato a sinistra in figura ha la proprietà z = 0 (valore di default), il secondo ha z = 100, il terzo ha z = -100: nessun'altra proprietà delle clip è stata modificata. La seconda clip (z > 0) appare più lontana mentre la terza (z < 0) appare più vicina rispetto alla prima.

Vediamo allora come regolare la posizione di una clip sull'asse Z, sia manualmente in fase di disegno sullo stage, sia tramite ActionScript.

Traslare sull'asse Z nello stage

Per gli spostamenti sui tre assi sono stati introdotti due nuovi strumenti: se utilizziamo il normale strumento di selezione infatti potremo muovere l'oggetto solo sugli assi x ed y, analogamente usando il classico transform tool non avremo a disposizione la rotazione sull'asse z.

È quindi necessario usare i due appositi strumenti, posti sotto allo strumento di sotto-selezione e sopra allo strumento lazo; è possibile, in alternative, agire tramite il pannello Proprietà.

Figura 3. Strumenti per il 3D
Strumenti di traslazione e rotazione 3D

La proprietà Z è disponibile solo per i MovieClip sullo stage, quindi se selezioniamo Strumento Traslazione 3D e proviamo a selezionare una forma sullo stage, non otteniamo nulla. Dovremo convertire prima il nostro oggetto (forma vettoriale, immagine o altro) in clip filmato; analogamente per gli oggetti di tipo diverso, il pannello proprietà non mostrerà le opzioni relative agli spostamenti sull'asse Z.

Quando selezioniamo un clip filmato con lo strumento di traslazione 3D, appre un cursore indicante i 3 assi designati da diversi colori:

  • in verde l'asse y
  • in rosso l'asse z
  • in blu l'asse z (anche se risulterà poco visibile poichè abbiamo a disposizione solo una visuale frontale)

Avvicinando il mouse a queste frecce il cursore ci informa dell'asse su cui stiamo per agire. È anche possibile spostare l'intero cursore per modificare il centro di trasformazione del MovieClip.

Figura 3. Il 3D Translation Tool
Lo strumento di traslazione 3D dopo aver selezionato un MovieClip

Selezionando l'asse Z e muovendo il cursore del mouse l'oggetto si avvicina o allontana dalla visuale.

Traslare sull'asse Z tramite ActionScript

Come accennato in precedenza, in Flash CS4 è stata introdotta la nuova proprietà z. Per impsotare la profondità di un MovieClip, basterà quindi dargli un nome istanza (ad esempio mc) e utilizzare un'istruzione simile a questa:

mc.z = valore

Tale proprietà è stata introdotta anche nelle classi di tweening, risulta quindi semplicissimo eseguire un'animazione che coinvolga l'asse Z. Ecco un esempio:

new Tween(mc, "z", Strong.easeOut, 0, 300, 3, true);

mc è l'istanza del MovieClip da animare, z la proprietà da animare, Strong.easeOut è il tipo di easing scelto per il movimento, 0 e 300 sono i valori iniziale e finale della proprietà selezionata, 3 è la durata dell'animazione (true indica che il valore 3 va considerato in secondi, altrimenti sarebbero considerati 3 fotogrammi).

Così come la classe Tween di Flash molte librerie esterne sono state aggiornate per supportare la proprietà z, come ad esempio le TweenLite o Tweener, questo è un aspetto interessante dato che solitamente queste librerie offrono prestazioni migliori di quelle offerte nativamente da Flash.

Aggiornare la profondità

Quando abbiamo più di un MovieClip sullo stage, la profondità non è gestita in maniera automatica, questo comportamento può generare errori a livello visivo e concettuale.

L'asse z gestisce di fatto la distanza di una clip in "profondità", con valori crescenti man mano che si prosegue "verso" lo schermo, un clip con z=500 dovrebbe stare sempre "dietro" a un clip che abbia ad esempio z=400. Questo putroppo non avviene e bisogna riconoscere che è un difetto piuttosto "seccante".

Figura 5. Clip disposte in maniera errata
Clip disposte erroneamente

I valori di profondità degli oggetti in figura sono:

  • quadrato blu: 0
  • quadrato rosso: 400
  • quadrato verde: -10

L'ordine di profondità dovrebbe essere verde, blu, rosso (i valori negativi hanno la precedenza su quelli positivi, essendo l'asse X puntato verso "l'interno" dello schermo). Vengono invece mantenute le profondità stabilite sullo stage.

Per ottenere il corretto ordine di profondità dovremmo aggiungere qualche riga di codice:

setChildIndex(c1,2)
setChildIndex(c3,1)
setChildIndex(c2,0) 

Per situazioni con più clip o maggiormente dinamiche (ad esempio dove vi fossero delle animazioni) dobbiamo creare funzioni o classi che controllino la posizione z di ogni clip e le dispongano di conseguenza, una soluzione non esattamente comoda.

Ovviamente non ci sono problemi nel caso in cui le diverse clip non si sovrappongano, ma è sicuramente frequente voler creare effetti tridimensionali che prevedano l'interazione tra più clip e questa mancata gestione della profondità può obiettivamente risultare fastidiosa.

Ruotare sull'asse Z sullo stage

Come abbiamo visto esiste un apposito strumento per la rotazione sui tre assi; differentemente da quanto visto per le traslazioni, dove anche dal pannello proprietà era possibile impostare i diversi valori, per la rotazione possiamo usare soltanto lo strumento presente nella toolbar.

Benchè l'aspetto sia diverso (abbiamo dei cerchi disposti intorno al MovieClip selezionato) il funzionamento di questo strumento è affine a quello per la traslazione: avvicinando il mouse ad uno dei cerchi apparirà la lettera relativa all'asse su cui stiamo per agire e muovendo il mouse ruoteremo in senso orario o antiorario l'oggetto; selezionando il cerchio arancione, quello più esterno, agiremo contemporaneamente su tutti gli assi.

Purtroppo non avendo a disposizione valori numerici modificabili nel pannello proprietà può essere leggermente complesso associare all'oggetto una rotazione precisa, magari in correlazione con altri MovieClip presenti sullo stage.

Figura 6. Strumento per le rotazioni 3D
Strumento per la rotazione 3D

Ruotare sull'asse Z tramite ActionScript

Dal punto di vista delle rotazioni abbiamo novità interessanti, infatti se fino a Flash CS3 l'unica proprietà disponibile era rotation e per ottenere effetti di prospettiva tramite ActionScript bisognava spesso affidarsi a formule non sempre semplici, Flash CS4 introduce oltre al comando rotationZ anche gli affini rotationX e rotationY. Questo permette un completo controllo della rotazione sui 3 assi tramite codice, in questo caso oltretutto abbiamo il controllo dei valori che manca invece per la soluzione via stage.

Proprio le rotazioni sono l'aspetto che più si può apprezzare tra le novità relative alla tridimensionalità in flash, poichè consentono di realizzare molto rapidamente effetti di prospettiva e distorsione.

Un 3D simulato

Il 3D di Flash è in realtà "simulato", per cui ruotando un MovieClip ad esempio sull'asse Y, quando questo avrà superato i 180 gradi lo vedremo "specchiato", non ne vedremo invece un "retro", un semplice sfondo "nero" (o magari personalizzabile) che renda più credibile la rotazione. Certamente anche con l'attuale implementazione si possono ottenere risultati accattivanti, ma il realismo della scena in caso di rotazioni "complete" di un oggetto sarebbe in molti casi compromesso.

Più di tridimensionalità la stessa Adobe parla di "trasformazioni di oggetti 2D in uno spazio 3D", questo spiega alcune carenze funzionali quali ad esempio l'assenza una camera per variare la visuale dello stage, o l'impossibilità di disegnare tramite ActionScript un clip già ruotato/inclinato dato che il metodo lineTo supporta ancora solo le coordinate x ed y.

Rotazione di un oggetto

Pensiamo al classico gioco "Memory", dove bisogna abbinare le varie coppie di carte uguali: un effetto spesso utilizzato è quello di far "ruotare" la carta come se avesse effettivamente due facce (dorso e fronte): in realtà si tratta di due fotogrammi di un medesimo movieclip.

Per creare un effetto di "finta rotazione", senza le proprietà 3D, si ricorreve alle proprietà di _xscale e _yscale applicate al comando Math.sin(); in Flash CS4 diventa tutto molto semplice e possiamo ottenere un ottimo risultato con poche righe di codice:

import fl.transitions.Tween
import fl.transitions.easing.*

var c = new Tween(carta, "rotationY", Strong.easeOut, 0, 360, 5, true);
carta.addEventListener(Event.ENTER_FRAME,checkRot)

function checkRot(evt:Event){
  trace(evt.target.rotationY)
  if(evt.target.rotationY > 90 && evt.target.rotationY < 270){
    evt.target.gotoAndStop(2)
  }else if(evt.target.rotationY > 270){
    evt.target.gotoAndStop(1)
  }
  if(evt.target.rotationY > 350){
    evt.target.rotationY = 0
    var c = new Tween(evt.target, "rotationY", Strong.easeOut, 0, 360, 5, true);
  }
}

Per eseguire questo codice è necessario avere un movieclip (nome istanza carta) con al suo interno due fotogrammi. Avviando il filmato noteremo come il clip ruoterà intorno al proprio asse verticale, cambiando fotogramma a seconda della sua rotazione.

Movieclip che ruota sul suo asse verticale cambiando fotogramma

In questo caso è stato creato un movimento perpetuo poiché ogni volta che la clip arriva a 350 gradi di rotazione viene resettato a zero il valore e viene avviato un nuovo Tween, ma sarebbe stato possibile associare la rotazione al click del mouse:

import fl.transitions.Tween
import fl.transitions.easing.*

carta.addEventListener(MouseEvent.CLICK,avviaRotazione)

function avviaRotazione(evt:MouseEvent){
  if(carta.rotationY < 170 || carta.rotationY > 300){
    var cf = new Tween(carta, "rotationY", Strong.easeOut, 0, 180, 5, true);
    carta.addEventListener(Event.ENTER_FRAME,checkRotFront)
  }else{
    var cr = new Tween(carta, "rotationY", Strong.easeOut, 180, 360, 5, true);
    carta.addEventListener(Event.ENTER_FRAME,checkRotRear)
  }
}

function checkRotFront(evt:Event){
  if(evt.target.rotationY > 90){
    evt.target.gotoAndStop(2)
  }
  if(evt.target.rotationY > 179){
    carta.removeEventListener(Event.ENTER_FRAME,checkRotFront)
  }
}

function checkRotRear(evt:Event){
  if(evt.target.rotationY > 270){
    evt.target.gotoAndStop(1)
  }
  if(evt.target.rotationY > 350){
    carta.rotationY = 0
    carta.removeEventListener(Event.ENTER_FRAME,checkRotRear)
  }
}

Movieclip che ruota sul suo asse verticale cambiando fotogramma

Zoom alternato tra gli oggetti

Abbiamo già accennato a come traslare un movieclip sull'asse Z, ma se l'effetto preso singolarmente non risultasse particolarmente accattivante, applicando l'effetto a più movieclip, e "alternando" lo spostamento (in modo che solo l'ultimo movieclip cliccato risulti in primo piano), il risultato sarebbe piuttosto gradevole:

Movieclip con traslazione alternata sull'asse Z

Avendo i tre quadrati sullo stage con nomi istanza c1, c2 e c3 è stato usato il seguente actionscript:

import fl.transitions.Tween
import fl.transitions.easing.*

c1.addEventListener(MouseEvent.CLICK,zooma)
c2.addEventListener(MouseEvent.CLICK,zooma)
c3.addEventListener(MouseEvent.CLICK,zooma)

function zooma(evt:MouseEvent){
  for(var n:int = 1; n<= 3; n++){
    if(n == evt.target.name.substr(1,1)){
      var muoviT:Tween = new Tween(evt.target,"z",Strong.easeOut,evt.target.z,-100,1,true)
    }else{
      var muoviA:Tween = new Tween(getChildByName("c"+n),"z",Strong.easeOut,getChildByName("c"+n).z,0,1,true)
    }
  }
}

Notiamo come grazie all'uso della classe Tween e alla proprietà z basti ben poco per ottenere il risultato visto nel filmato di esempio.

Con le versioni precedenti di Flash un risultato di questo tipo sarebbe comunque stato ottenibile tramite le proprietà di ridimensionamento (_xscale e _yscale per Actionscript 2, scaleX e scaleY per Actionscript 3).

Con Flash CS4 però basta inserire poche righe di codice in più per migliorare l'effetto.

import fl.transitions.Tween
import fl.transitions.easing.*
c1.rotationY = c2.rotationY = c3.rotationY = 40

c1.addEventListener(MouseEvent.CLICK,zooma)
c2.addEventListener(MouseEvent.CLICK,zooma)
c3.addEventListener(MouseEvent.CLICK,zooma)

function zooma(evt:MouseEvent){
  for(var n:int = 1; n<= 3; n++){
    if(n == evt.target.name.substr(1,1)){
      var muoviT:Tween = new Tween(evt.target,"z",Strong.easeOut,evt.target.z,-100,1,true)
      var ruotaT:Tween = new Tween(evt.target,"rotationY",Strong.easeOut,evt.target.rotationY,0,1,true)
    }else{
      var muoviA:Tween = new Tween(getChildByName("c"+n),"z",Strong.easeOut,getChildByName("c"+n).z,0,1,true)
      var ruotaA:Tween = new Tween(getChildByName("c"+n),"rotationY",Strong.easeOut,getChildByName("c"+n).rotationY,40,1,true)
    }
  }
}

Movieclip con traslazione alternata sull'asse Z e rotazione sull'asse Y

Per ottenere questo stesso risultato, con le versioni precedenti, avremmo dovuto impiegare le matrici di trasformazione, complicando quindi notevolmente il codice e i vari passaggi, mentre grazie alla proprietà rotationY abbiamo ottenuto un risultato accattivante con sole 5 righe di codice in più rispetto alla versione senza rotazione.

Effetti su movieclip annidati

È possibile applicare diversi effetti 3D a più movieclip contenuti l'uno dentro l'altro; supponiamo di avere un movieclip contenitore con al suo interno 4 clip: il contenitore eseguirà un'animazione iniziale, mentre ognuno dei clip contenitori potrà eseguire delle animazioni al passaggio del mouse.

Movieclip contenitore animato con al suo interno altri clip animati al rollover

Sebbene vi siano diversi effetti (cliccando con il mouse è anche possibile cambiare la rotazione del contenitore sull'asse Z, e di conseguenza quella dei clip in esso contenuti) il codice è abbastanza ridotto:

import fl.transitions.Tween
import fl.transitions.easing.*

contenitore.rotationX = 90
contenitore.rotationZ = -30

stage.addEventListener(MouseEvent.CLICK,spostaContenitore)
function spostaContenitore(evt:MouseEvent){
  contenitore.rotationZ = Math.random()*180
}
// animazione del contenitore
var cf = new Tween(contenitore, "rotationX", Strong.easeOut, 90, 0, 5, true);
// associazione eventi alle clip del contenitore
contenitore.c1.addEventListener(MouseEvent.MOUSE_OVER,avanti)
contenitore.c1.addEventListener(MouseEvent.MOUSE_OUT,indietro)
contenitore.c2.addEventListener(MouseEvent.MOUSE_OVER,avanti)
contenitore.c2.addEventListener(MouseEvent.MOUSE_OUT,indietro)
contenitore.c3.addEventListener(MouseEvent.MOUSE_OVER,avanti)
contenitore.c3.addEventListener(MouseEvent.MOUSE_OUT,indietro)
contenitore.c4.addEventListener(MouseEvent.MOUSE_OVER,avanti)
contenitore.c4.addEventListener(MouseEvent.MOUSE_OUT,indietro)

// funzioni di avanti e indietro delle clip
function avanti(evt:MouseEvent){
  var ca = new Tween(evt.target,"z",Strong.easeOut,evt.target.z,-100,2,true)
}

function indietro(evt:MouseEvent){
  var ci = new Tween(evt.target,"z",Strong.easeOut,evt.target.z,0,2,true)
}

Ecco un breve video che riassume alcuni concetti visti nell'articolo:

Ti consigliamo anche