Eccoci al secondo appuntamento del nostro viaggio verso la realizzazione di un prototipo di gioco di auto (top view), che ci porterà alla scoperta del magico mondo di CreateJS ed in particolar modo di EaselJS.

La volta scorsa ci siamo lasciati con un bel rettangolo rosso sulla nostra "tela", e ripartiremo proprio da li per far disegnare e far muovere ad EaselJS la nostra prima macchinina (rombante).

Iniziamo subito rimuovendo dal metodo init le righe che abbiamo scritto la scorsa volta per disegnare il rettangolo rosso, e precisamente:

var pseudocar = new createjs.Shape();<br />pseudocar.graphics.beginFill("red").drawRect(10,10,100,200);<br />stage.addChild(pseudocar);<br />stage.update();

La primissima cosa da fare è quindi aggiungere uno Sprite allo stage di EaselJS. Lo Sprite consente di disegnare a video un singolo frame o una sequenza di frame (come se fossero un'animazione) definiti in un'istanza SpriteSheet.


 

Le istanze di classe SpriteSheet rappresentano che una serie di immagini combinati in un'unica immagine (nel nostro caso la nostra automobilina con il fumo dalla marmitta), e nel nostro caso si definisce nel seguente modo:

var newcar = new createjs.SpriteSheet({<br />                "framerate": 10,<br />                "images": ["car.png"],<br />                "frames":<br />                        {<br />                            "height": 82,<br />                            "width":66,<br />                            "regX": 0,<br />                            "regY": 0,<br />                            "count": 8<br />                        },<br />                "animations": {<br />                                 "broom": [0, 7]  <br />                              }<br />                });

I parametri passati al costruttore della classe SpriteSheet sono:

  • framerate – consente di definire la frequenza di aggiornamento dello SpriteSheet (andando a variare la proprietà framerate dell'istanza Sprite), utilizzando il valore indicato come divisore per il framerate dello Stage. Quindi nel caso in cui il framerate dello Stage fosse di 40FP, nel nostro caso andremmo a refreshare lo Sprite ogni 4 frame;
  • images – URI immagine o lista di immagini da utilizzare;
  • frames – definisce la posizione di ogni singolo frame nell'immagine. I frame all'interno dell'immagine possono essere rappresentati come una griglia sequenziale di frame identici in dimensioni, oppure con frame posizionati in maniera irregolare (Nel nostro caso abbiamo un'immagine con griglia sequenziale).
    Nel nostro caso sarà sufficiente indicare l'altezza, la larghezza, le coodinate del punto di registrazione (il punto che fa da cardine in caso di rotazione per farla breve!) ed il numero di frame (questi due parametri non sono obbligatori);
  • animations – una serie di range di frame che vengono "montati" insieme per creare un'animazione. Nel nostro caso ad esempio abbiamo un solo range che indica di disegnare in sequenza dal frame 0 al frame 7. Sarebbe possibile indicare anche una serie di frame ben definiti (e non un range quindi), un eventuale altra animazione da eseguire al termine dell'animazione stessa (per creare delle catene di animazione) e la velocità di riproduzione. Le varie modalità sono indicate nella pagina relativa della documentazione: http://www.createjs.com/Docs/EaselJS/classes/SpriteSheet.html

A questo punto possiamo creare lo Sprite per poter accogliere lo SpriteSheet nello stage, ed indicare dove andare a renderizzare il tutto.

carsprite = new createjs.Sprite(newcar, "run");<br />carsprite.x = 300;<br />carsprite.y = 150;<br />carsprite.rotation = 90;<br />stage.addChild(carsprite);

Dopo aver creato lo Sprite infatti andiamo a determinare le coordinate x e y di partenza ed una rotazione di 90 per far si che l'auto possa essere posizionata in orizzontale. Infine assegniamo lo Sprite allo stage (come avevamo fatto la scorsa volta con il rettangolo).

Adesso arriva il momento di renderizzare sul canvas il nostro Sprite…come abbiamo visto la volta scorsa, per renderizzare qualcosa va chiamato il metodo update dell'oggetto stage, ma nel nostro caso dobbiamo richiamarlo un bel pò di volte al secondo in modo da poter "creare" l'animazione…e quindi che si fa? Usiamo la classe statica Ticker!

Il Ticker consente di definire quante volte deve essere eseguito un tick entro un intervallo di tempo impostato (nel nostro caso l'FPS sarà di 60, e quindi verranno eseguiti 60 tick al secondo), ed ogni oggetto di scena può sottoscrivere l'evento tick in modo da essere avvisato ogni qualvolta che viene eseguito un tick. Cosi facendo possiamo variare le proprietà ed il comportamento di ogni oggetto di scena in modo da animarlo…ecco le semplici righe di codice da inserire nella funzione init:

createjs.Ticker.on("tick", tickFunc);<br />createjs.Ticker.setFPS(60);

In questo caso tramite il metodo on (che è una shortcut del metodo AddEventListener della classe base EventDispatcher) possiamo associare all'evento tick una funzione (nel nostro caso tickFunc) che verrà quindi eseguita ad ogni scattare dell'evento. Successivamente definiamo quante volte per secondo dovrà essere eseguito tramite il metodo setFPS.
N.B. Si può facilmente cambiare il framerate predefinito o impostando un intervallo (il tempo tra i tick per mezzo di setInterval) o un framerate (il numero di tick per frame per mezzo di setFPS).

Scriviamo quindi la funzione tickFunc che verrà eseguita:

function tickFunc(event) {<br />      carsprite.x += event.delta/1000*200;<br />      var cf = newcar.getFrame(carsprite.currentFrame).rect.width;<br />      if (carsprite.x - cf > stage.canvas.width) { carsprite.x =0; }<br />      stage.update(event);<br />}

Spieghiamo cosa abbiamo scritto…facciamo però prima un passo indietro…normalmente per le tue animazioni è un'ottima scelta renderle indipendenti dal frame rate, in modo tale che sia su device potenti che su device meno prestanti si avrà un'animazione costante ed omogenea. Questa tecnica si chiama Time based animation.

Per fare ciò dobbiamo sfuttare il parametro delta del singolo tick, che ci consente di ottenere la quantità di tempo trascorsa dall'ultimo tick. Questo ci consentirà di far muovere di 200px l'oggetto ma in maniera uniforme secondo la formula:

elapsedTimeInMS / 1000msPerSecond * pixelsPerSecond

Quindi a questo punto dovrebbe essere chiara la prima riga della funzione tickFunc, nella quale sommiamo alla coordinata x dello Sprite il numero di pixel di movimento per quel tick!

Successivamente facciamo un'operazione di "abbellimento" prendendo la dimensione in larghezza del frame corrente, in modo tale da controllare con un'operazione condizionale se siamo usciti alla destra del nostro stage…se dovesse essere cosi riporteremo la nostra auto alla coordinata x = 0 in modo tale che riappaia dal lato sinistro dello stage!
N.B. Questa operazione in realtà sarebbe utile nel caso i frames avessero dimensioni diverse l'uno dall'altro…

Infine facciamo l'update dello stage, come fatto la scorsa volta (ma questa volta lo eseguiamo per ogni tick)…

Scarica il codice completo cliccando qui!

A questo punto la nostra auto correrà (smarmittando a più non posso) da destra a sinistra fino all prossimo step realizzativo…

The following two tabs change content below.

Francesco Sciuti

Freelance a Vroom Agency
Amante dello sviluppo web, della grafica 3d e della buona musica (che non guasta mai!), 'web developpa' tutto il giorno...e prova a trovare sempre il bandolo della matassa in questo allegro ma sconfinato mondo.

//life motto
if(sad() === true) {
    sad().stop();
    beAwesome();
}