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

Gravità in flash5

Simulazione della gravità con una pallina che rimbalza
Simulazione della gravità con una pallina che rimbalza
Link copiato negli appunti

Apriamo un nuovo documento flash 550x250, 50 fps di frame rate. Creiamo i layer secondo questo schema:

Livelli

Nel layer azioni settiamo 2 variabili che interpretano il limite destro e il limite inferiore dell'area in cui si muoverà la sfera.

s_width = 550;
s_height = 250;
stop ();

Nel layer sfera disegnamo un cerchio di dimensioni 16x16. Selezioniamo il cerchio e lo convertiamo in pulsante tramite F8 , come nome di libreria diamo "drag" e come coordinate di posizione diamo x, y = -8.0. Convertiamo nuovamente, stavolta in movieclip, sempre con F8, come nome di istanza diamo "sfera" e lo posizioniamo al centro-sinistra dello stage.

Editiamo con un doppio click il mc sfera e associamo al pulsante "drag" il seguente codice che serve a rendere trascinabile il mc sfera.

// alla pressione del mouse
on (press) {
    // setta la variabile dragging come vera
    dragging = true;
    // rendiamo trascinabile questo movieclip
    startDrag (this, true);
}
on (release, releaseOutside) {
    // setta la variabile dragging come falsa
    dragging = false;
    // -fine trascinamento-
    stopDrag();
}

A questo punto abbiamo sullo stage il movieclip sfera che contiene il pulsante drag. Creiamo, tramite il pulsante "+" nella libreria, un nuovo mc chiamato "smile_vuoto", che sarà composto da 17 frames contenenti l'animazione della gif "smile" che sfuma (coordinate x, y = -8.0). Inseriamo un nuovo livello che chiamiamo azioni: al frame 17 di questi associamo il seguente codice, (dove i è la variabile che gestisce il numero di mc duplicati e rimossi) :

// decrementa la i di una unità
_root.i--;
//eliminiamo il duplicato creato
removeMovieClip(this); (*)

Selezioniamo il mc sfera ed associamo le seguenti azioni:

onClipEvent (load) {
    gravity = 12;
    rimbalzo = .6;
    raggio = this._width/2;
}
onClipEvent (enterFrame) {
    vecchiaX = x;
    vecchiaY = y;
    x = this._x;
    y = this._y;
    if (dragging) {
        Lx = (x - vecchiaX) * 10;
        Ly = (y - vecchiaY) * 10;
    } else {
        Ly += gravity;
        x += (Lx / 10);
        y += (Ly / 10);
        if (y < raggio) {
            y = raggio;
            Lx *= rimbalzo;
            Ly *= -rimbalzo;
        }
        if(y > (_root.s_height - raggio)) {
            y = _root.s_height - raggio;
            Lx *= rimbalzo;
            Ly *= -rimbalzo;
        }
        if (x < raggio) {
            x = raggio;
            Lx *= -rimbalzo;
            Ly *= rimbalzo;
        }
        if (x > (_root.s_width - raggio)) {
            x = _root.s_width - raggio;
            Lx *= -rimbalzo;
            Ly *= rimbalzo;
        }
        this._x = x;
        this._y = y;
    }
    _root.i++;
    duplicateMovieClip ("_root.smilevuoto", "sfera" +_root.i, _root.i);
    _root["sfera" + _root.i]._x = x;
    _root["sfera" + _root.i]._y = y;
}

Prima di entrare nel "vivo" dello script, faccio un breve (?) appunto sull'azione dinamica delle forze agenti.

La gravità

Sperimentalmente tutti i corpi assumono, se lasciati liberi, la stessa accelerazione, detta di "gravità", diretta verticalmente verso il suolo. Nella realtà il suo valore è g = 9.8 ms². Nel nostro caso settiamo una forza di gravità pari a 12 (gravity = 12).

Il lancio

Cosa accade quando lanciamo la sfera?

  • La sfera si sposta da un punto A ad un punto B e, indicando con x_a e x_b le ascisse del punto (cioè il valore reale dei punti A e B), il suo spostamento ds è dato da x_b - x_a.
  • Per lanciare la sfera le applichiamo una forza, cioè compiamo un lavoro pari alla forza applicata per lo spostamento compiuto: L = f * ds

Indicando con Lx e Ly il lavoro di ascissa x e y, con f = 10 il valore della forza e con ds = (x_b - x_a) lo spostamento, segue : Lx = (x_b - x_a) * 10; Ly = (y_b - y_a) * 10; (In questo modo "creiamo" la velocità della sfera).

Inoltre da L = f*ds risulta che lo spostamento compiuto è pari a: ds = L/f cioè: dx = Lx/10 e dy = Ly/10

L'urto

Cosa accade quando la sfera entra in contatto con un limite dell'area? ..."Ad ogni azione corrisponde una reazione uguale ed opposta ed agente sulla stessa retta di applicazione..."

Se lancio una sfera contro il soffitto con una certa forza f essa ricadrà con una forza -f opposta al suo asse di simmetria. L'urto modifica la quantità di moto del punto e nel nostro caso "quantità di moto" significa rimbalzo = 0.6.

I rimbalzi della sfera

La velocità (L = f * ds) con cui si muove la sfera dipende dallo spostamento AB quindi, quando (dopo l'urto) tocca il limite inferiore per la prima volta, la velocità con cui riparte varia al variare dello spostamento e quindi la sfera ha una perdita di velocità direttamente proporzionale alle coordinate.

Se invece lasciamo cadere la sfera, l'unica forza agente è la gravità (che spinge l'oggetto in basso), per cui incrementiamo il lavoro lungo la verticale y di un valore di gravità pari a 12: Ly += 12

Il raggio

Il centro della sfera rappresenta la sua posizione _x. Se portiamo questa sfera ai bordi dell'area di delimitazione essa oltrepasserà di metà della sua larghezza il limite , creando un effetto rimbalzo poco realistico ... Per ovviare a ciò creiamo una variabile raggio (raggio=larghezza_sfera/2 ) in modo che, ogni volta che la sfera raggiunge un bordo, aggiungiamo o sottraiamo il raggio alla sua posizione corrente come spiegato nei commenti dello script.

// al caricamento del mc
onClipEvent (load) {
    // settiamo la gravità
    gravity = 12;
    // settiamo il rimbalzo
    rimbalzo = .6;
    // settiamo la variabile raggio
    raggio = this._width/2;
}
// ad ogni riproduzione del movieclip
onClipEvent (enterFrame) {
    // settiamo le variabili dello spostamento
    vecchiaX = x;
    vecchiaY = y;
    // posizione attuale del movieclip sfera
    x = this._x;
    y = this._y;
    // se la variabile dragging è vera ( vedi pulsante drag)
    if (dragging) {
        // calcoliamo il lavoro L = f * ds
        // (che corrisponde alla velocità della sfera di coordinate (x, y))

        Lx = (x - vecchiaX) * 10;
        Ly = (y - vecchiaY) * 10;
        // altrimenti, se lasciamo cadere la sfera
    } else {
        // sommiamo a Ly la gravità
        Ly += gravity;
        // definiamo lo spostamento corrente
        x += (Lx / 10);
        y += (Ly / 10);
        // se y è minore di 8 ( ci troviamo oltre il limite superiore)
        if (y < raggio) {
            // facciamo rientrare y nel valore limite
            y = raggio;
            // definiamo il rimbalzo lungo l'ascissa x
            Lx *= rimbalzo;
            // definiamo il rimbalzo lungo y
            // ... opposto alla direzione iniziale di y

            Ly *= -rimbalzo;
            // in modo analogo gestiamo la condizione y maggiore di 250 - 8 = 242
            // cioè quando la sfera si trova oltre il limite inferiore

        }
        if(y > (_root.s_height - raggio)) {
            y = _root.s_height - raggio;
            Lx *= rimbalzo;
            Ly *= -rimbalzo;
        }
        // se x < 8 (limite sinistro)
        if (x < raggio) {
            // facciamo rientrare x nel limite
            x = raggio;
            // definiamo il rimbalzo lungo x con direzione opposta
            // alla retta di applicazione

            Lx *= -rimbalzo;
            // rimbalzo lungo y
            Ly *= rimbalzo;
        }
        // se x è maggiore di 550 - 8 = 542 (limite destro)
        if (x > (_root.s_width - raggio)) {
            x = _root.s_width - raggio;
            // gestione rimbalzo analoga alla suddetta
            Lx *= -rimbalzo;
            Ly *= rimbalzo;
        }
        // impostiamo la posizione di questo (sfera) mc e
        // diamogli come valore il valore di x e di y

        this._x = x;
        this._y = y;
    }
    // aumentiamo la variabile i di una unità
    _root.i++;
    // duplichiamo il mc "smilevuoto" , diamogli il valore di
    // "sfera[i]" come nome e diamogli profondità "i"

    duplicateMovieClip ("_root.smilevuoto", "sfera" +_root.i, _root.i);
    // impostiamo la posizione del mc "sfera[i] con il valore
    // delle coordinate del mc "sferavuota"

    _root["sfera" + _root.i]._x = x;
    _root["sfera" + _root.i]._y = y;
}

La prima parte dello script, quella relativa al caricamento del mc, oltre ad assegnare un valore alle "forze" che agiscono sulla sfera, setta la variabile raggio che definisce anche il limite sinistro e il limite superiore dell'area di spostamento. Ogni volta che viene caricato il movieclip settiamo i valori delle coordinate, della velocità e a seconda dei casi, dello spostamento e del rimbalzo. Infine creiamo la "scia" duplicando il movieclip . Notiamo che l'azione usata duplica in continuazione il movieclip smile_vuoto e i vari duplicati vengono sostituiti dai nuovi scomparendo.( removeMovieClip (*))


Ti consigliamo anche