E-learn.ro
Panou utilizatori
Utilizator Parola
Creeaza cont nou    Recupereaza parola
Login
Newsletter
Introdu adresa ta de email
Inscrie-te
Inchide panoul de utilizatori
Add to Google

Tutoriale Adobe Flash

Descarca toolbar

Toolbar E-learn.ro Facebook Twitter

GRAFICA 2D  /  Adobe Flash  /  ActionScript (14)

Simularea gravitatiei in flash

04.11.2008
Simularea gravitatiei in flash

Pentru a realiza simularea gravitatiei in flash se recurge la modificari ale legilor fizicii, la rezolvarea de ecuatii si la scripting.

Total vizualizari: 7745 7745 afisari   |   Comentarii  0   |   Rating   |   (3 voturi)   |   Timp necesar: 35 min 35 min   |   Nivel de cunostiinte necesar: Avansat  Avansat

Sursa:  www.prodevtips.com  
Autor:  www.prodevtips.com
Download
Adauga la tutoriale favorit Adauga la tutoriale favorite
Pagina:
1 2 »
comenteaza printeaza

Pentru a realiza simularea gravitatiei in flash se recurge la modificari ale legilor fizicii, la rezolvarea de ecuatii si la scripting. Sa incepem cu AS-ul din fisierul .fla (de sus in jos).

var oldPoint = new V2D(0, 0); 
var curPoint = new V2D(0, 0); 
var mouseSpeed = new V2D(0, 0); 
var maxSpeed = 8; 
var moveInterval = 50;

In primul rand, trebuie sa initializam cateva variabile globale pentru a controla diverse lucruri:

oldPoint: Pozitia pe care cursorul o avea in frame-ul precedent. Variabila care retine aceasta informatie este V2D, de la "2 Dimensional Vector". Un vector este de fapt o pereche (X,Y) din care putem deduce o directie si o lungime/putere. Iti voi explica mai detaliat pe masura ce avansam.

curPoint: Pozitia actuala a cursorului

mouseSpeed: Cu ajutorul primelor doua variabile poti calcula viteza si directia cursorului si poti stoca rezultatul in mouseSpeed. Acest rezultat va fi folosit pentru a calcula in ce directie si cu ce viteza se vor misca obiectele de tip sfera dupa ce sunt atinse de cursor.

maxSpeed: Cu putina imaginatie aceasta valoare ar putea fi considerata drept viteza luminii. Ea reprezinta o variabila care va fi aplicata obiectelor aflate in miscare pentru a le diminua oscilatiile.
moveInterval: Se refera la perioada de timp calculata ca numar de frame-uri, care trebuie sa treaca inainte ca mouse-ul sa atinga din nou o anumita sfera. Ea trebuie setata la 1 si vei vedea si de ce.

var objects = new Array( 
    new AdvObj(circle0),  
    new AdvObj(circle1) 
); 
 
var wells = new Array(); 
for(i in objects){ 
    wells[i] = (new GravityWell(objects[i], _root["well"+i]._x, _root["well"+i]._y, 2, 1e9, 1000)); 
    objects[i].moving = -1; 
}

Vom stoca sferele afectate de obiectele de tip gravity well intr-un array pe care il vei numi objects. Aceste obiecte vor fi de tipul AdvObj. Circle0 si 1 se refera la instantele movie clip-ului de pe scena, care au fost denumite astfel utilizand paleta Properties. In continuare vei crea obiectele GravityWells parcurgand array-ul de obiecte de tip sfera, transmitandu-le drept primul argument constructorului GravityWell (despre care voi vorbi in curand).

Aceste obiecte vor avea pozitia a doua movieclip-uri invizibile aflate pe scena, numite well0 si 1, in timp ce ultimele 3 argumente sunt: factorul de reducere a gravitatiei ca functie de distanta; cel de al 2-lea ar reprezinta m1*m2 in formula gravitatiei, iar ultimul argument consta intr-o valoare cu care vei controla comportamentul gravitatiei, aceasta ultima valoare avand rolul de a modifica ordinea naturala a lucrurilor.Vei vedea ca totul se leaga, ai putina rabdare...

this.onEnterFrame = function(){ 
    curPoint.set(_xmouse, _ymouse); 
    mouseSpeed = curPoint.subtract(oldPoint); 
    handleObjects(); 
    oldPoint.from(curPoint); 
}

Acesta este codul executat la fiecare 25 fps. Toate instructiunile, excluzand functia handleObjects(), au rolul de a calcula viteza de deplasare a mouse-ului.

function handleObjects(){ 
    for(i in objects){ 
        var o = objects[i]; 
        if(o.clip.hitTest(_xmouse, _ymouse, true) && o.moving < 0){ 
            o.speedFrom(mouseSpeed); 
            o.moving = moveInterval; 
            o.started = true; 
        }else if(o.started == true){ 
            wells[i].pull(); 
            o.simulate(); 
            o.moving--; 
            if(o.speed.length() > maxSpeed){ 
                o.speed.lengthTo(maxSpeed - 0.1); 
                o.acc.fromOne(0); 
            } 
        } 
    } 
}

Dupa cum ti-ai dat seama vei parcurge toate obiectele afectate si le vei stoca in variabila temporara o, la fel ca in exemplul de sus. Apoi verifici daca cursorul se afla deasupra lor si daca contorul moving are o valoare negativa sau pozitiva. Daca aceste conditii sunt indeplinite, este ca si cum am fi lovit obiectul, deci ii asociem acestuia aceeasi viteza ca si mouse-ului, initializam intervalul de miscare cu variabila globala moveInterval  despre care am vorbit mai devreme si setam started ca true.

Daca started e adevarat putem incepe simularea. Fiecare well va atrage obiectul care ii este desemnat, ceea ce inseamna ca afecteaza cate unul odata, nefiresc, nu? Totusi, simularea atractiei din partea mai multor obiecte GravityWell in acelasi timp poate deveni extrem de dificila din punct de vedere computational.

Prin urmare, fiecare obiect e responsabil de simularea propriei sale miscari, de unde si apelul o.simulate(). Urmeaza partea de incetinire a miscarii, deoarece avand valoarea 50 pentru interval, sferele sunt lovite numai la fiecare 2 secunde.

In continuare trebuie sa verifici daca viteza actuala a fiecarui obiect e mai mare decat cea maxima. Daca da, o vei face sa fie putin mai scazuta decat valoarea vitezei maxime si vei reseta acceleratia complet. Nu are rost sa pastram aceeasi acceleratie intrucat aceasta va afecta viteza pe care incercam sa o miscoram. Daca nu ai face acest lucru, obiectele ar oscila puternic si ar disparea din zona vizibila foarte rapid.

Sa ne concentram acum la clasa GravityWell si la metoda pull:

class GravityWell{ 
    var pos:V2D; 
    var tgt:AdvObj; 
    var power:Number; 
    var factor:Number; 
    var modifier:Number; 
    function GravityWell(tgt:AdvObj, x, y, power:Number, 
        factor:Number, modifier:Number){ 
        this.pos = new V2D(x, y); 
        this.tgt = tgt; 
        this.power = power; 
        this.factor = factor; 
        this.modifier = modifier; 
    } 
     
    function pull(){ 
        var acc:V2D = this.pos.subtract(tgt.ctrlPoint); 
        var dist:Number = tgt.ctrlPoint.dist(this.pos); 
        acc.divideScal(Math.pow(dist, this.power)); 
        acc.multi(this.factor * 6.67e-11); 
         
        /* Incepe modificarea care se abate de la reguli */ 
        if(HSMath.alike(acc.x, tgt.acc.x) == false) 
            acc.x *= modifier; 
             
        if(HSMath.alike(acc.y, tgt.acc.y) == false) 
            acc.y *= modifier; 
        /* se opreste */ 
         
        tgt.accMe(acc); 
    } 
}

In functia pull() vei crea vectorul acceleratie curent prin scaderea pozitiei tintei afectate (tgt.ctrlPoint) din pozitia obiectului de tip well, rezultand un vector care va indica catre well si care va fi adaugat la acceleratia totala a obiectului din acest frame. De asemenea, vei obtine si distanta dintre doua obiecte.

In etapa ulterioara vei calcula ecuatia gravitatiei prin descresterea acceleratiei ca functie de distanta si variabila putere trimisa ( in cazul nostru e 2). Trebuie sa si maresti acceleratia ca functie a masei obiectului si well-ului ( in acest caz 1e9); constanta gravitationala e 6.67e-11.

Urmeaza modificarea legilor naturale; de fapt, trebuie sa verifici daca te apropii sau indepartezi de obiect, daca te indepartezi, atunci ii vei mari forta gravitationala ( in cazul nostru cu un factor 1000). Daca nu ai face acest lucru, sansele ca un obiect sa ramana pe orbita, el s-ar pierde in spatiu In cele din urma, mareste/micsoreaza acceleratia obiectului cu cea a timeframe-ului.

De fapt, nici asa nu e bine. Incearca sa te joci cu codul schimband tgt.accMe(acc); cu tgt.acc.from(acc); Daca faci asta, trebuie sa modifici ultimii 3 parametri alegand una din valorile: 2, 1e12 si 1. Una dintre ele va anula complet comportamentul anormal si astfel vei avea o simulare adevarata a gravitatiei.

Pagina:
1 2 »
comenteaza printeaza
Alte tutoriale Adobe Flash:
Noteaza acest tutorial
Rating tutorial
 
(3 voturi)
Pentru a nota acest tutorial, trebuie sa fii logat!
Posteaza un comentariu
Pentru a posta un comentariu, trebuie sa fii logat!
0 TOP UTILIZATORI* 0 0
Tutoriale scrise de claibornelara
claibornelara Rang utilizator claibornelara - Incepator
5310
Tutoriale scrise de mcuemica
mcuemica Rang utilizator mcuemica - Incepator
5270
Tutoriale scrise de ellarichards
ellarichards Rang utilizator ellarichards - Incepator
5115
Tutoriale scrise de emonclercheap
emonclercheap Rang utilizator emonclercheap - Incepator
5100
Tutoriale scrise de beacherrosa
beacherrosa Rang utilizator beacherrosa - Incepator
4845
* Acest top reprezinta punctajele acumulate in ultimele 30 de zile.
Action Script CSS Ruby on Rails Bridge Fotografie StyleSheet Python Excel Verilog Powerpoint Word JSON SEO AJAX SWF Gimp Sony Vegas MySQL Vista Illustrator Photoshop PHP XML Fireworks Lightroom Flash Javascript RoR PSD Dreamweaver COREL DRAW Java Swift 3D HTML Outlook XHTML
Promovare:
Daca faci parte din comunitatea E-learn.ro si doresti promovarea acesteia, poti accesa pagina de promovare.
Arhiva newsletter:
Daca ai ratat un numar mai vechi, sau vrei sa revezi care au fost noutatile E-learn.ro la un moment dat, poti accesa arhiva de newslettere.
  Copyright © 2008-2013 E-LEARN.ro. Toate drepturile rezervate. Termeni si conditii.
Conceput si realizat de Neokinetics Software