JavaScript de animație care funcționează (partea 2 din 4)

În ultimul post, am introdus ideea de Procedeul de spriting poate, o modalitate ușoară de a anima în JavaScript care funcționează în toate browserele. De asemenea, am parcurs modul de a configura sprite ca imagine de fundal pentru a div și apoi utilizați o linie de JavaScript pentru a schimba poziția de fundal pentru ca aceasta să apară ca și cum imaginea sa mutat.

În acest post, vom folosi această tehnică pentru a anima atât mișcările de rulare, cât și de salt. Pentru a crea animația, va trebui să schimbăm rapid poziția de fundal la un interval regulat. Uitați-vă din nou la spritele pe care le folosim.


Meet J, mascota pentru compania mea, Joust Multimedia.

În exemplul nostru, avem zece imagini totale: unul dintre J stând cu fața spre dreapta, trei J mergând spre dreapta și unul J jumping în direcția dreaptă (cu același număr al fiecărui cadru orientat spre stânga). Să începem să-l facem să alerge spre dreapta. Pentru a face ca imaginea să arate ca și cum rulează, va trebui să facem două lucruri: să schimbăm sprite-ul într-o altă imagine și să mutăm div spre dreapta.


A alerga la animația potrivită

Cu siguranță nu vom dori să fim blocați făcând clic pe butoane diferite pentru a parcurge spritele, deci va trebui să creăm câteva funcții care fac acest lucru automat.

Pentru funcția noastră de funcționare, dorim să:

  1. Mută div spre dreapta ușor
  2. Treceți la următorul cadru de animație
  3. Întrerupeți o fracțiune de secundă (pentru a păstra iluzia "persistenței viziunii")
  4. Reactivați din nou funcția

Din fericire, există o modalitate ușoară de a vă bucura de funcții. O comandă nativă în JavaScript numită setTimeout ne va permite să creăm o întârziere temporizată, după care vom apela funcția din nou (din interiorul funcției).

 functie run_right () // Mutati putin spre dreapta ... // Schimbati la urmatorul frame de animatie ... // va apela din nou 'run_right' dupa 200 de milisecunde setTimeout (function () run_right ();, 200); 

Așa că acum avem o funcție care se va reînnoi de cinci ori pe secundă (care va fi suficient de rapidă pentru a crea animație pentru scopurile noastre). Amintiți-vă aici că browserele nu sunt foarte corecte cu cronometrele lor. Puteți specifica calendarul la milisecunde, dar asta nu înseamnă că scriptul dvs. va funcționa exact la acel moment!

Următoarea noastră problemă de a aborda este modul în care funcția noastră va ști ce sprite să se schimbe? În exemplul nostru, vom fi nevoiți să facem cicluri înainte și înapoi prin cele trei imagini (pentru a avea patru cadre totale de animație). Pentru a face acest lucru, vom trece funcția noastră un pic de informație pentru a spune care slide pentru a trece la. Odată ce am fost în funcție, vom face un test care va verifica ce diapozitiv ar trebui să fie pe, apoi trece poziția de fundal la sprite corecte. Când vom apela funcția din nou, vom trece următorul diapozitiv ca argument.

 functie run_right (diapozitiv) // Mutati putin spre dreapta ... comutator (slide) // aceasta declaratie comutator verifica diferite posibilitati pentru cazul 'slide' 1: // if 'slide' este egal cu '1' ... document.getElementById ( 'j'). style.backgroundPosition = "-40px 0px"; setTimeout (funcție () run_right (2);, 200); pauză; cazul 2: // dacă 'slide' este egal cu '2' ... document.getElementById ('j') style.backgroundPosition = "-80px 0px"; setTimeout (funcție () run_right (3);, 200); pauză; cazul 3: // dacă 'slide' este egal cu '3' ... document.getElementById ('j') style.backgroundPosition = "-120px 0px"; setTimeout (funcție () run_right (4);, 200); pauză; cazul 4: // dacă 'slide' este egal cu '4' ... document.getElementById ('j') style.backgroundPosition = "-80px 0px"; setTimeout (funcție () run_right (1);, 200); pauză; 

Iar acum, când sunăm pentru prima dată în funcție, vom avea nevoie să ne asigurăm că vom trece slide-ul inițial.

 

În mod similar, pentru a ne muta div la dreapta ușor, putem trece atributul inițial stânga al div, apoi mutați div ușor de fiecare dată când este apelată funcția.

 funcția run_right (diapozitiv, stânga) left = left + 15; // Creșteți atributul stâng de documentul 15px document.getElementById ('j'). Style.left = left + "px"; comanda (slide) // această instrucțiune comutator verifică diferite posibilități pentru cazul "slide" 1: // if 'slide' este egal cu '1' ... document.getElementById ('j') style.backgroundPosition = "-40px 0px" ; setTimeout (funcție () run_right (2, stânga);, 200); pauză; cazul 2: // dacă 'slide' este egal cu '2' ... document.getElementById ('j') style.backgroundPosition = "-80px 0px"; setTimeout (funcție () run_right (3, stânga); 200); pauză; cazul 3: // dacă 'slide' este egal cu '3' ... document.getElementById ('j') style.backgroundPosition = "-120px 0px"; setTimeout (funcție () run_right (4, stânga);, 200); pauză; cazul 4: // dacă 'slide' este egal cu '4' ... document.getElementById ('j') style.backgroundPosition = "-80px 0px"; setTimeout (funcție () run_right (1, stânga);, 200); pauză; 

Și când suntem numiți inițial funcția, trebuie să ne asigurăm că trecem pe poziția actuală stângă a noastră div.

 

Oprirea animației

Deci, acum avem o funcție care, atunci când este chemată, o va anima pe J pentru a alerga spre dreapta. Din păcate, nu avem cum să o oprim. Mai întâi de toate, va trebui să facem ca funcția să nu se mai numească dacă J merge la marginea scenei noastre. Pentru a face acest lucru, de fiecare dată când funcționează funcția, vom verifica un mesaj dacă declarație pentru a vedea dacă J are loc pentru a continua să ruleze. Dacă da, vom executa funcția ca în mod normal. Dacă nu, vom înceta să apelați funcția și să-l returnați spriteului în picioare.

 funcția run_right (diapozitiv, stânga) // Dacă putem adăuga 15 pixeli la stânga și avem marginea dreaptă a lui J nu se află la marginea dreaptă a scenei ... dacă ((la stânga + 15) < (document.getElementById('stage').offsetWidth - document.getElementById('j').offsetWidth)) // We have room! Continue like normal here  else  // if we are on the right edge, we need to stop calling the function and return to standing document.getElementById('j').style.backgroundPosition = "0px 0px";  

În cele din urmă, vom dori să avem o modalitate de a opri funcția, atunci când este necesar. Putem seta setTimeout () comanda la o variabilă, apoi opriți-o cu clearTimeout () comanda. Pentru a face acest lucru, va trebui să declarăm această variabilă în afara funcției, astfel încât să ne putem referi mai târziu la aceasta. Pentru moment, o vom declara ca o variabilă globală. Aceasta este o practică teribilă de codificare, dar vom corecta acest lucru în următorul post. Acesta este modul în care arată funcția noastră.

 var timer; funcția run_right (diapozitiv, stânga) if ((la stânga + 15) < (document.getElementById('stage').offsetWidth - document.getElementById('j').offsetWidth)) left = left + 15; // Increase his left attribute by 15px document.getElementById('j').style.left = left+"px"; switch (slide) // this switch statement checks for different possibilities for 'slide' case 1: // if 'slide' equals '1'… document.getElementById('j').style.backgroundPosition = "-40px 0px"; setTimeout(function()run_right(2, left);, 200); break; case 2: // if 'slide' equals '2'… document.getElementById('j').style.backgroundPosition = "-80px 0px"; setTimeout(function()run_right(3, left);, 200); break; case 3: // if 'slide' equals '3'… document.getElementById('j').style.backgroundPosition = "-120px 0px"; setTimeout(function()run_right(4, left);, 200); break; case 4: // if 'slide' equals '4'… document.getElementById('j').style.backgroundPosition = "-80px 0px"; setTimeout(function()run_right(1, left);, 200); break;   else  document.getElementById('j').style.backgroundPosition = "0px 0px";  

Și putem crea o altă funcție pentru a opri cronometrul de funcționare și pentru a readuce sprite-ul pe imaginea în picioare.

 funcția stop_running () document.getElementById ('j') style.backgroundPosition = "0px 0px"; clearTimeout (temporizator); 

A alerga la Animația stângă

Acum, prin împrumutarea codului de la noi run_right funcția, putem crea o altă funcție pentru a face run_left funcție, cu doar câteva modificări.

 funcția run_left (stadiu, stânga) if ((left - 15)> 0) left = left - 15; document.getElementById ('j'). style.left = stânga + "px"; comutator (scenă) caz 1: document.getElementById ('j') style.backgroundPosition = "-40px -50px"; timer = setTimeout (funcție () run_left (2, stânga);, 200); pauză; cazul 2: document.getElementById ('j') style.backgroundPosition = "-80px -50px"; timer = setTimeout (funcție () run_left (3, stânga) ;, 200); pauză; cazul 3: document.getElementById ('j') style.backgroundPosition = "-120px -50px"; timer = setTimeout (funcție () run_left (4, stânga);, 200); pauză; cazul 4: document.getElementById ('j') style.backgroundPosition = "-80px -50px"; timer = setTimeout (funcția () run_left (1, stânga) ;, 200); pauză;  altfel document.getElementById ('j') style.backgroundPosition = "0px -50px"; 

Jumping Animație

În cele din urmă, trebuie să creăm o funcție de salt. Vom trece două argumente la această funcție, una care va urmări dacă div este în prezent în mișcare în sus sau în jos și un alt care va urmări atributul curent de top al div. Între cele două, vom determina ce direcție div trebuie să se miște în continuare, și cât de departe (vom muta div mai mică distanță în apropierea arcului de salt pentru a simula accelerația cu gravitatea).

 funcția săritură (sus, sus) / * * Schimbați J la sprite lui săritură ... * / document.getElementById ('j') style.backgroundPosition = "-160px 0px"; / * * Aici trebuie sa decidem daca ar trebui sa calatoreasca in sus sau in jos ... * / daca (up && (document.getElementById ('j') offsetTop> 20)) // daca se misca in sus si el este mai mult de 20 de pixeli din partea de sus a etapei ... top = sus - (sus * .1); // Aceasta ne dă un ușor arc în salt, mai degrabă decât o mișcare constantă, cum ar fi rulând document.getElementById ('j') style.top = top + "px"; // Schimbați temporizatorul poziției sale = setTimeout (funcția () salt (sus, sus);, 60); // Apoi apelați din nou funcția altceva dacă (sus) // dacă se mișcă în prezent, dar este aproape la vârful scenei și trebuie să revină jos ... sus = false; // comutați variabila "sus" astfel încât el va cădea în următorul buclă timer = setTimeout (funcția () salt (sus, sus);, 60);  altfel dacă (! up && (document.getElementById ('j') < 115)) // if he is moving down, but is more than 5px from the ground, he will continue to fall… top = top + (top * .1); // His fall will slightly accelerate document.getElementById('j').style.top = top+"px"; timer = setTimeout(function()jump(up, top);, 60);  else  // If he is moving down, and he is within 5px of the ground… document.getElementById('j').style.top = "120px"; // Place him on the ground document.getElementById('j').style.backgroundPosition = "0px 0px"; // return to standing sprite // We do not call the loop anymore since he is standing still at this point  

Acum putem pune toate cele patru funcții în butoane și avem un prototip activ de animație care rulează și sărituri! Vă rugăm să verificați codul sursă pentru această pagină cu comentarii și să descărcați foaia de sprite pe care am folosit-o, dacă doriți.


Concluzie

Acum, deși avem un prototip de lucru aici, este posibil să observați că este un mic buggy. Când faceți clic pe mai multe butoane simultan, scriptul va încerca să ruleze simultan. Sau dacă faceți clic din nou pe butonul de salt pe drum, J va continua să scadă pentru totdeauna. De asemenea, așa cum am menționat mai devreme, avem variabile globale în scriptul nostru, ceea ce înseamnă că ar fi dificil să adăugați acest cod într-o pagină existentă fără a crasa alt JavaScript (de aceea nu am încercat să rulez acest cod în acest blog pagină). În următoarea noastră postare, vom curăța toate aceste bug-uri și vom vorbi despre conceptul de încapsulare și de ce este important să scriem un cod bun în lumea reală.

Cod