Prosegue la serie di articoli / tutorials sulla trigonometria applicata ad Actionscript 3.0 .
Entriamo nel cuore dell' argomento trigonometria usando angoli, raggi, seni e coseni.
In questo esempio vedremo come far muovere una semplice pallina con la trigonometria.
Vedremo come creare un effetto con più palline utilizzando l' identificatore di una MovieClip in libreria per istanziare la MovieClip stessa. Il tutto sotto intervallo.
Infine vedremo come applicare questo effetto ad una maschera.
Guarda SWF 1
Guarda SWF 2
Guarda SWF 3
Vediamo il codice...
Primo esempio:
Creo un FLA che salvo con nome ' trigonometria_3.fla '.
Al suo interno creo una MovieClip di forma circolare a cui assegno nome istanza ball_mc.
Creo la Document Class, un file AS che salvo con nome ' Trigonometria.as ', implementata in questo modo:
Code:
package
{
import flash.display.MovieClip;
import flash.events.Event;
public class Trigonometria extends MovieClip
{
private var centroY:Number;
private var angolo:Number=0;
private const raggio:Number=150;
private const velocita:Number=1;
public function Trigonometria()
{
init();
}
private function init():void
{
stage.frameRate=31;
ball_mc.x=0;
ball_mc.y=stage.stageHeight/2;
centroY=ball_mc.y;
ball_mc.addEventListener(Event.ENTER_FRAME,muovi);
}
private function muovi(e:Event):void
{
ball_mc.y=centroY+Math.sin(angolo)*raggio;
ball_mc.x+=velocita;
angolo+=.1;
if(ball_mc.x>=stage.stageWidth+ball_mc.width)
ball_mc.x=0;
}
}
}
Analizziamo il codice
Classe Trigonometria.as
Proprietà:
una variabile numerica che conterrà il valore Y del centro della circonferenza
private var centroY:Number;
una variabile numerica che contiene il valore dell' angolo ( che verrà poi incrementato )
private var angolo:Number=0;
una costante che contiene la dimensione del raggio della circonferenza
private const raggio:Number=150;
una variabile numerica che contiene la velocità della X di ball_mc
private const velocita:Number=1;
Metodi:
init();
imposto la velocità del frame rate
stage.frameRate=31;
posiziono la MovieClip
ball_mc.x=0;
ball_mc.y=stage.stageHeight/2;
assegno un valore Y alcentrodella circonferenza ( in questo caso uguale alla Y di ball_mc )
centroY=ball_mc.y;
aggiungo un listener che chiama la funzione muovi() con intervallo ENTER_FRAME
ball_mc.addEventListener(Event.ENTER_FRAME,muovi);
muovi();
assegno alla Y della clip un valore pari a: il centro Y della circonferenza più il seno della variabile angolo moltiplicato per il valore della variabile raggio
ball_mc.y=centroY+Math.sin(angolo)*raggio;
incremento la X di ball_mc del valore della variabile velocita
ball_mc.x+=velocita;
incremento il valore della variabile angolo di 0,1
angolo+=.1;
se la X di ball_mc supera la larghezza dello stage più il suo width
if(ball_mc.x>=stage.stageWidth+ball_mc.width)
riporto la X di ball_mc a zero
ball_mc.x=0;
Secondo esempio
Creo un FLA che salvo con nome ' trigonometria_3_a.fla '.
Al suo interno ho la stessa MovieClip a forma circolare ma non la istanzio sullo stage. La tengo in liberia e gli assegno come identificatore ' Ball.as ' , esattamente la classe che andrò a creare.
Creo la Document Class, un file AS che salvo con nome ' Trigonometria2.as ', implementata in questo modo:
Code:
package
{
import flash.display.MovieClip;
import flash.utils.Timer;
import flash.events.Event;
import flash.events.TimerEvent;
public class Trigonometria2 extends MovieClip
{
private var timer:Timer;
private const velocitaTimer:int=150;
public function Trigonometria2():void
{
init();
}
private function init():void
{
stage.frameRate=31;
startTimer();
}
private function startTimer():void
{
timer=new Timer(velocitaTimer,0);
timer.addEventListener(TimerEvent.TIMER,attaccaBall);
timer.start();
}
private function attaccaBall(t:TimerEvent):void
{
var ball:Ball=new Ball();
addChild(ball);
ball.muoviti();
}
}
}
Creo la classe Ball, un fial AS che salvo con nome ' Ball.as ' ( la classe che è identificatore di mc_ball che è in libreria ), implementata in questo modo:
Code:
package
{
import flash.display.MovieClip;
import flash.events.Event;
public class Ball extends MovieClip
{
private var centroY:Number;
private var angolo:Number=0;
private var raggio:Number;
private var velocita:Number;
public function Ball():void
{
init();
}
private function init():void
{
x=0;
}
public function muoviti():void
{
y=this.parent.parent.stage.stageHeight/2;
centroY=y;
raggio=10+Math.random()*(y/2);
velocita=.5+Math.random()*4.5;
scaleX=scaleY=.2+Math.random();
alpha=.1+Math.random();
addEventListener(Event.ENTER_FRAME,go);
}
private function go(e:Event):void
{
y=centroY+Math.sin(angolo)*raggio;
x+=velocita;
angolo+=.1;
if(x>this.parent.parent.stage.stageWidth+width+10)
{
fermaIntervallo();
rimuovimi();
}
}
private function fermaIntervallo():void
{
removeEventListener(Event.ENTER_FRAME,go);
}
private function rimuovimi():void
{
this.parent.removeChild(this);
}
}
}
Analizziamo il codice
Classe Trigonometria2.as
Proprietà
Un timer ( istanza della classe Timer )
private var timer:Timer;
una costante col valore della velocità del timer
private const velocitaTimer:int=150;
Metodi
init();
imposto la velocita del frame rate
stage.frameRate=31;
chiamo la funzione startTimer()
startTimer();
startTimer();
istanzio il timer passandogli come valore di velocità il valore della costante velocitaTimer e zero ( infinito )
timer=new Timer(velocitaTimer,0);
aggiungo un listener al timer che chiamerà ogni tot centesimi di secondo ( pari al valore della costante velocitaTimer ) la funzione attaccaBall()
timer.addEventListener(TimerEvent.TIMER,attaccaBal l);
faccio partire il timer
timer.start();
attaccaBall();
istanzio la classe Ball ( che vediamo quì di seguito )
var ball:Ball=new Ball();
dato che la classe Ball estende la classe MovieClip, aggiungo l' istanza della classe Ball ( ball ) al DisplayObject ( altrimenti non sarebbe visibile )...ex attachMovie con ball_mc che ha come identificatore Ball
addChild(ball);
chiamo il metodo muoviti() della classe Ball
ball.muoviti();
Classe Ball.as ( ricordiamoci che scrivere codice quì dentro è come riferirsi direttamente alla MovieClip che verrà 'attaccata ' allo stage )
Proprietà
una variabile numerica che conterrà il valore Y del centro della circonferenza
private var centroY:Number;
una variabile numerica che contiene il valore dell' angolo ( che verrà poi incrementato )
private var angolo:Number=0;
una costante che contiene la dimensione del raggio della circonferenza
private const raggio:Number=150;
una variabile numerica che contiene la velocità della X di ball ( la MovieClip che verrà ' attaccata ' allo stage )
private const velocita:Number=1;
Metodi
init();
impostola x pari a zero
x=0;
muoviti();
imposto la y pari al valore della metà dell' altezza dello stage
y=this.parent.parent.stage.stageHeight/2;
imposto il centro Y della circonferenza ( in questo caso pari a y di ball )
centroY=y;
imposto un valore random al raggio della circonferenza
raggio=10+Math.random()*(y/2);
imposto un valore random alla velocita della x
velocita=.5+Math.random()*4.5;
imposto un valore random alle proprietà scaleX e scaleY
scaleX=scaleY=.2+Math.random();
imposto un valore random alla proprietà alfa
alpha=.1+Math.random();
chiamo la funzione go() sotto intervallo ENTER_FRAME
addEventListener(Event.ENTER_FRAME,go);
go();
imposto un valore alla y pari al centro Y della circonferenza più il seno ricavato dal valore della variabile angolo moltiplicato per il valore della variabile raggio
y=centroY+Math.sin(angolo)*raggio;
incremento la x del valore della variabile raggio
x+=velocita;
incremento l'angolo di 0,1
angolo+=.1;
ora, bisogna fare in modo che la clip, quando arriva ad un certo punto che non sarà più visibile, di fermare il suo intervallo ENTER_FRAME e di toglierla in modo da non fare carico sulla CPU dell' utente. Quindi se la sua x supera la larghezza dello stage più il suo width
if(x>this.parent.parent.stage.stageWidth+width+10)
{
chiamo le funzioni fermaIntervallo() e rimuovimi()
fermaIntervallo();
rimuovimi();
}
fermaIntervallo();
fermo l'ntervallo ENTER_FRAME
removeEventListener(Event.ENTER_FRAME,go);
rimuovimi();
dico a Trigonometria_2.as ( che era quella che ha istanziato questa clip ) di rimuovere appunto la clip
this.parent.removeChild(this);
Terzo esempio
Creo un FLA che salvo con nome ' trigonometria_3_b.fla '.
Al suo interno ho in libreria la stessa MovieClip circolare ( mc_ball ) però con identificatore Ball2 ( una classe che sto per creare ).
Sullo stage ho un' altra MovieClip della stessa forma e stesse misure dello stage e molto colorata a cui assegno nome istanza image_mc.
Creo al Document class, un file AS che salvocon nome ' Trigonometria3.as ', implementata in questo modo:
Code:
package
{
import flash.display.MovieClip;
import flash.utils.Timer;
import flash.events.Event;
import flash.events.TimerEvent;
public class Trigonometria3 extends MovieClip
{
private var contenitore_mc:MovieClip;
private var timer:Timer;
private const velocitaTimer:int=100;
public function Trigonometria3():void
{
init();
}
private function init():void
{
stage.frameRate=31;
contenitore_mc=new MovieClip();
addChild(contenitore_mc);
startTimer();
}
private function startTimer():void
{
timer=new Timer(velocitaTimer,0);
timer.addEventListener(TimerEvent.TIMER,attaccaBall);
timer.start();
}
private function attaccaBall(t:TimerEvent):void
{
var ball:Ball2=new Ball2();
contenitore_mc.addChild(ball);
image_mc.mask=contenitore_mc;
ball.muoviti();
}
}
}
Creo la classe Ball2, un file AS che slavo con nome ' Ball2.as ', implementata inquesto modo:
Code:
package
{
import flash.display.MovieClip;
import flash.events.Event;
public class Ball2 extends MovieClip
{
private var centroY:Number;
private var angolo:Number=0;
private var raggio:Number;
private var velocita:Number;
public function Ball2():void
{
init();
}
private function init():void
{
x=0;
}
public function muoviti():void
{
y=this.parent.parent.stage.stageHeight/2;
centroY=y;
raggio=10+Math.random()*(y-10);
velocita=.5+Math.random()*4.5;
scaleX=scaleY=.2+Math.random();
//alpha=.1+Math.random();
addEventListener(Event.ENTER_FRAME,go);
}
private function go(e:Event):void
{
y=centroY+Math.sin(angolo)*raggio;
x+=velocita;
angolo+=.1;
if(x>this.parent.parent.stage.stageWidth+width+10)
{
fermaIntervallo();
rimuovimi();
}
}
private function fermaIntervallo():void
{
removeEventListener(Event.ENTER_FRAME,go);
}
private function rimuovimi():void
{
this.parent.removeChild(this);
}
}
}
Analizziamo il codice
Classe Trigonometria3.as
Proprietà
una MovieClip che conterrà tutte la istanze della classe Ball2.as ( praticamente invece di ' attaccare ' le clip allo stage le ' attaccherò ' all' interno diuna MovieClip vuota che a sua voltafungerà da maschera per image_mc)
private var contenitore_mc:MovieClip;
Un timer ( istanza della classe Timer )
private var timer:Timer;
una costante col valore della velocità del timer
private const velocitaTimer:int=150;
Metodi
init();
imposto la velocita del frame rate
stage.frameRate=31;
creo la MovieClip vuota
contenitore_mc=new MovieClip();
aggiungo la MovieClip vuota al DisplayObject ( altrimenti non sarebbe visibile )
addChild(contenitore_mc);
chiamo la funzione startTimer()
startTimer();
startTimer();
istanzio il timer passandogli come valore di velocità il valore della costante velocitaTimer e zero ( infinito )
timer=new Timer(velocitaTimer,0);
aggiungo un listener al timer che chiamerà ogni tot centesimi di secondo ( pari al valore della costante velocitaTimer ) la funzione attaccaBall()
timer.addEventListener(TimerEvent.TIMER,attaccaBal l);
faccio partire il timer
timer.start();
attaccaBall();
istanzio la classe Ball2 ( che vediamo quì di seguito )
var ball:Ball2=new Ball2();
dato che la classe Ball2 estende la classe MovieClip, aggiungo l' istanza della classe Ball2 ( ball ) alla MovieClip vuota ( contenitore_mc )
contenitore_mc.addChild(ball);
assegno contenitore_mc come maschera di image_mc
image_mc.mask=contenitore_mc;
chiamo il metodo muoviti() della classe Ball2
ball.muoviti();
Classe Ball2.as
Stesso procedimento di Ball.as
Allego i files sorgente: