CocaDozzer
Moderator
Din: Garda de Fier
Inregistrat: acum 16 ani
Postari: 197
|
|
La rotazione lungo l'asse Y (Y-rotation). Pensate ad un giradischi o ad un hoola hop. La sua posizione Y non varia, ma la X (destra verso sinistra o viceversa) e la profondità Z cambiano. La rotazione lungo l'asse X (X-rotation). Pensate ad una lama di una sega circolare. La profondità Z e la posizione verticale Y cambiano, ma non varia la sua posizione orizzontale, ossia la X rimane fissa.
Flash supporta la Z-rotation, tramite la proprietà _rotation. Ma è semplicemente una rotazione, l'oggetto gira semplicemente intorno al proprio centro. Se volessimo far compiere un'orbita, un movimento di rotazione rispetto ad un punto centrale esterno all'oggetto, come per esempio il nostro pianeta intorno al sole, dobbiamo usare un metodo un po' più avanzato.
Dato che la Z-rotation è la più semplice, inizieremo da questa, anche se per il momento non è una vera orbita 3D.
Il problema principale è il COME far muovere un oggetto intorno ad un punto centrale esterno. La distanza tra l'oggetto e il centro sarà sempre la stessa, per esempio 100 pixels. Quindi ora noi abbiamo un raggio di 100 e un angolo che va da 0 a 360°. Da questi dati dobbiamo ricavare le posizioni _x e _y. questa è la formula:
_x=Math.cos(angle)*radius+xcenter; _y=Math.sin(angle)*radius+ycenter; Una cosa molto importante da sapere è che gli angoli devono essere espressi in "radianti". Questo è un sistema differente dai 360° che si usano comunemente. Dato che è molto più semplice pensare in gradi che in radianti, dovremo convertirli.
Questa è la formula:
rad=degree*Math.PI/180;
Ora dobbiamo solo creare un loop che aumenti l'angolo da 0 a 360 ed avremo un moto circolare. Per mettere tutto insieme, create un movieclip con una forma qualsiasi e dategli queste azioni:
Code:
onClipEvent(load){
speed=5;
radius=100;
xcenter=250;
ycenter=200;
angle=0;
}
onClipEvent(enterFrame){
_x = Math.cos(angle*Math.PI/180)*radius+xcenter;
_y = Math.sin(angle*Math.PI/180)*radius+ycenter;
angle += speed;
if (angle>359) {
angle -= 360;
}
} |
Provatelo e dovreste avere il vostro movieclip che si muove circolarmente. Non è ancora un movimento tridimensionale, ma è un primo passo verso il risultato finale.
OK. Appurato che funziona, proviamo con la Y-rotation. Immaginate il cerchio del movimento precedente, ma questa volta immaginatelo in linea con il vostro sguardo fino a vedere solo una linea orizzontale. La sua Y è ora la Z ma la X rimane invariata. Quindi tutto quel che dobbiamo fare è sostituire _y con z:
Code:
onClipEvent (load){
y=0;
speed=5;
radius=100;
xcenter=250;
ycenter=200;
zcenter=100;
angle=0;
}
onClipEvent(enterFrame){
_x=Math.cos(angle*Math.PI/180)*radius+xcenter;
_y=y+ycenter;
z=Math.sin(angle*Math.PI/180)*radius+zcenter;
angle += speed;
if (angle>359) {
angle -= 360;
}
} |
Notate che abbiamo aggiunto il valore zcenter all'evento load e cambiato ycenter in zcenter nell'evento enterFrame. Possiamo provare a cambiare questo valore. Un valore maggiore farà apparire l'intera animazione più lontana mentre un valore minore ovviamente la farà avvicinare. Ho anche eseguito il calcolo per _y, altrimenti il suo valore sarebbe stato 0 e l'animazione sarebbe stata posizionata nel margine superiore dello schermo.
Se lo testate ora, il movieclip si muoverà semplicemente da destra verso sinistra. Anche se abbiamo già aggiunto il calcolo di Z, non l'abbiamo ancora utilizzato. Lo useremo ora per scalare l'oggetto ed aver un piccolo effetto 3D.
Domanda: quanto dobbiamo scalare l'oggetto per avere un effetto prospettico realistico ? Ora dobbiamo sconfinare nel campo dell'ottica, che ci crediate o no...
Prima dobbiamo settare una lunghezza focale (focal length), che è la distanza teorica tra l'osservatore e lo schermo. Il valore della lunghezza focale determina quanta prospettiva hanno le cose, quanto rapidamente le dimensioni crescono o diminuiscono e quanto gli oggetti si muovono verso di noi o verso l'orizzonte. Settiamo questo valore a 150 per il momento. Potrete divertirvi a cambiarlo in seguito, per ottenere l'effetto desiderato. La lunghezza focale è un valore fisso, quindi la setteremo nell'evento load.
fl=150;
Dopo ci serve il valore della scala. Questo si ottiene tramite i valori della lunghezza focale e di Z. Questa è la formula:
scale=fl/(fl+z);
Potete anche cambiare un po' questa formula, ma dovete tenere presente che il valore ottenuto dovrà essere un decimale compreso tra 0 e 1 inclusi. Quando z=0, scale dovrà essere 1.0, all'incrementare di z verso l'infinito, ossia all'allontanamento dell'oggetto rispetto all'osservatore, scale dovrà decrescere gradualmente verso 0.0. Ora possiamo usare qusta formula per calcolare le _xscale e _yscale del nostro movie clip:
_xscale = _yscale = scale*100;
L'action completa sarà:
Code:
onClipEvent(load){
y=0;
speed=5;
radius=100;
xcenter=250;
ycenter=200;
zcenter=100;
angle=0;
fl=150;
}
onClipEvent(enterFrame){
_x=Math.cos(angle*Math.PI/180)*radius+xcenter;
_y=y+ycenter;
z=Math.sin(angle*Math.PI/180)*radius+zcenter;
scale=fl/(fl+z);
_xscale=_yscale=scale*100;
angle+=speed;
if(angle>359){
angle-=360;
}
} |
Provatelo. Siamo a buon punto ma possiamo ancora migliorarlo per rendere il tutto ancora più realistico.
Prima avevo menzionato il fatto che se un oggetto si allontana dall'osservatore, tende ad andare verso il punto di fuga. Nell'esempio precedente avevamo y=0, che è sia l'altezza dell'osservatore che l'altezza dell'orizzonte (e quindi del punto di fuga), per cui non si notano cambiamenti. Ma se mettiamo y=100, ora il movimento avviene più in basso rispetto l'osservatore e ci si aspetterebbe che l'oggetto man mano che si allontana da noi si muova verso il punto di fuga; allo stesso modo mettendo y minore di zero il movimento avverrebbe sopra la linea di orizzonte e che quindi muovendosi verso la fuga l'oggetto dovrebbe scendere fino all'orizzonte.
Lo stesso discorso vale per la x. Quando il movie clip si muove verso l'orizzonte, dovrebbe spostarsi orizzontalmente verso il centro. In questo caso non lo si nota molto, perchè l'oggetto si muove già di per se a destra e a sinistra.
Ma facciamo i perfezionisti.
Per _x, dobbiamo prima calcolare la posizione del cerchio, assegnadola a x, aggiustando la prospettiva e successivamente assegnando il valore a _x :
Code:
onClipEvent(load){
y=100;
speed=5;
radius=100;
xcenter=250;
ycenter=200;
zcenter=100;
angle=0;
fl=150;
}
onClipEvent(enterFrame){
z=Math.sin(angle*Math.PI/180)*radius+zcenter;
scale=fl/(fl+z);
x=Math.cos(angle*Math.PI/180)*radius;
_x=x*scale+xcenter;
_y=y*scale+ycenter;
_xscale= _yscale = scale*100;
angle+=speed;
if(angle>359){
angle-=360;
}
} |
Notate che come prima cosa abbiamo bisogno di calcolare i valori di z e scale, per poi calcolare i valori successivi. Provate a cambiare il valore di y nell'evento load per far ruotare l'oggetto a differenti altezze (provate pure con valori negativi).
Questo è quanto di più realistico potete avere per quanto riguarda posizione e scala.
Ora passiamo al tocco definitivo: l'effetto dell'atmosfera, calcolando un valore di _alpha in base alla scala. Semplicemente aggiungiamo questa riga nell'evento enterFrame:
_alpha=scale*100;
Potete variare la visibilità semplicemente aggiustanto il valore 100.
Il prossimo passo logico è quello di aggiungere oggetti multipli alla rotazione. Per ottenere la medesima distanza tra gli oggetti, bisogna aggiustare il valore dell'angolo di partenza per ogni oggetto. Dividete 360 per il numero di oggetti e aggiungetelo ad ogni movie clip:
Per esempio: Abbiamo 10 oggetti. 360/10=36. Quindi 36 sarà l'angolo iniziale per ogni oggetto:
Oggetto1: angle=36; Oggetto2: angle=72; Oggetto3: angle=108; ecc...
Si può fare questo sia manualmente, che automaticamente con un loop for().
Nota aggiuntiva: Queste action sono state messe tramite onClipEvent() per semplicità di spiegazione, io raccomando di inserirle dentro il movie clip, nella sua timeline. Per esempio mettendo tutte le costanti (quelle dell'evento load) nel primo frame, le azioni (quelle dell'evento enterFrame) nel frame 2, e nel frame 3 mettere un semplice gotoAndPlay(2); in questo modo il codice è costruito dentro l'oggetto e potrete prendere quante istanze vorrete dalla libreria senza dover riscrivere tutte le actions.
In ogni caso, se volete effettuare una rotazione sull'asse x, semplicemente cambiate ogni riferimento a y con x e ogni x con y.
_______________________________________ PM-URI
JUST SAY THANKS-it only takes a second!!!!
|
|