Dezvoltarea HTML5 și Flash poate avea multe în comun, dar, în calitate de dezvoltator Flash, am găsit încă o sarcină monumentală de a-mi reînvia cunoștințele vechi în HTML5. În acest tutorial, vă voi arăta cum am creat un meniu animat și o tranziție de ecran pentru un joc HTML5 shoot-'em-up.
Uitați-vă la rezultatul pe care îl vom face:
Rețineți fundalul de defilare, navele care apar și se rotesc pe fiecare parte a fiecărui element de meniu și modul în care ecranul se estompează la negru atunci când selectați o opțiune.
HTML5 și JavaScript sunt similare cu ActionScript în multe feluri; există o mulțime de suprapuneri în sintaxă, ascultători de evenimente și metode. Cu toate acestea, există unele diferențe foarte diferite pe care le voi acoperi în acest tutorial:
Ceva de remarcat este că acest tutorial folosește în principal imagini care pot fi descărcate cu sursa sau puteți folosi propriile imagini dacă vă place (va trebui să cunoașteți lățimile și înălțimile).
Primul lucru pe care trebuie să-l facem este să adăugăm
Impusca-i
Liniile evidențiate inserați elementul de panza, care va face meniul nostru real. Consultați acest tutorial pentru un ghid de pânză de la zero.
Este deja aproape timpul să începeți codarea JavaScript! Avem două opțiuni cu privire la locul în care poate merge codul; Acesta poate fi scris în interiorul HTML-ului
Următorul pas va fi crearea a patru variabile pentru a face referire la elementul de panza cu ușurință.
var canvas = document.getElementById ("myCanvas"); var context = canvas.getContext ("2d"); var width = canvas.getAttribute ("lățimea"); var height = canvas.getAttribute ("înălțime");
Am menționat mai întâi myCanvas
și setați-o să indice elementul HTML canvas. O altă variabilă numită context
a fost creat pentru a obține dimensiunile canalului (2D). Similar cu Flash, suntem creați ultimele două variabile, lăţime
și înălţime
, pentru a simplifica procesul de accesare a proprietăților lățimii și înălțimii panzei.
La fel ca în ActionScript, vom crea instanțe ale imaginilor noastre.
var bgImage = imagine nouă (); var logoImage = imagine nouă (); var playImage = imagine nouă (); var instructImage = imagine nouă (); var settingsImage = imagine nouă (); var creditsImage = imagine nouă (); var shipImage = imagine nouă ();
Lipsesc o piesă crucială de cod pentru fiecare instanță - calea sursă! Am salvat toate imaginile din directorul "Imagini" din același director ca fișierul HTML, astfel:
shipImage.src = "Imagini / navă.png"; bgImage.src = "Imagini / Fundal.png"; logoImage.src = "Imagini / logo.png"; playImage.src = "Imagini / play.png"; instructImage.src = "Imagini / instrucțiuni.png"; settingsImage.src = "Imagini / setări.png"; creditsImage.src = "Imagini / credite.png";
Înainte de a desena imaginile pe panza, creați patru tablouri pentru a ține pozițiile și dimensiunile butoanelor (playImage
, instructImage
, settingsImage
, creditsImage
). Aceste tablouri vor fi utilizate mai târziu pentru a crea o funcție de mouse peste.
butonul varX = [192,110,149,160]; butonul varYY = [100,140,180,220]; var buttonWidth = [96,260,182,160]; var buttonHeight = [40,40,40,40];
Acum putem desena imagini pe pânză; acest lucru se poate face într-un onload
pentru fiecare imagine, dar nu trebuie să fie inclusă o funcție de încărcare - putem folosi pur și simplu drawImage ()
.
bgImage.onload = funcție () context.drawImage (bgImage, 0, 0); ; logoImage.onload = funcție () context.drawImage (logoImage, 50, -10); playImage.onload = funcția () context.drawImage (playImage, butonulX [0], butonulY [0]); instructImage.onload = funcția () context.drawImage (instructImage, butonulX [1], butonulY [1]); setăriImage.onload = funcție () context.drawImage (setăriImage, butonX [2], butonY [2]); creditsImage.onload = funcția () context.drawImage (crediteImage, butonulX [3], butonulY [3]);
Dacă încercați acum, ar trebui să vedeți o imagine statică a unui meniu pe care în curând îl vom respira. Nava nu a fost însoțită de restul imaginilor, deoarece vom trage mai târziu într-un eveniment de șoarece. Apropo, dacă nu ați făcut acest lucru până acum, păstrați variabilele grupate împreună în partea de sus și faceți același lucru cu funcțiile.
JavaScript nu are un onEnterFrame ()
echivalent, dar putem crea cu ușurință propriile noastre prin utilizarea unui interval (temporizator).
cadrele var = 30; var timerId = 0; timerId = setInterval (actualizare, 1000 / cadre);
S-ar putea să fii confuză cu privire la modul în care funcționează intervalul, așa că voi explica pe scurt. Intervalul numește funcția Actualizați()
fiecare (1000 /rame
) de milisecunde pentru a crea o rată de reîmprospătare netedă. Valoarea a rame
controlează fps-urile; dacă rame
este de 25, atunci browserul va încerca să sune Actualizați()
fiecare (1000/25 =) 40 de milisecunde.
Următorul nostru pas evident este de a crea funcția Actualizați()
funcția de actualizare () clar (); mișcare(); a desena();
Au mai fost numite alte trei funcții. clar()
este folosit pentru a șterge pânza deoarece, spre deosebire de blițul, pânza funcționează ca și cum ați pune autocolante pe o placă; imaginile nu pot fi mutate după ce au fost plasate. Următoarea funcție, mișcare()
, este utilizat pentru modificarea valorilor variabilelor care sunt utilizate cu imaginile. In cele din urma a desena()
este chemat să pună acele "autocolante".
funcion clear () context.clearRect (0, 0, lățime, înălțime);
Puneți simplu, acest cod șterge totul în interiorul dreptunghiului care este dimensiunea pânzei și este extras din (0,0), colțul din stânga sus. Asta înseamnă că curăță întreaga pânză vizibilă.
Înainte de a trece la următoarea funcție, trebuie introduse două variabile. backgroundY
va fi variabila pentru poziția y a imaginii de fundal și viteză
va fi folosit pentru a scăpa de la backgroundY
fiecare ciclu de actualizare.
var backgroundY = 0; viteza var = 1;
Efectul pe care îl vom produce este un fundal în continuă evoluție. Imaginea este alcătuită din două imagini identice, unul peste celălalt, într-o imagine mai mare (imaginea fiind de două ori înălțimea pânzei). Vom muta lent imaginea până când a doua jumătate este complet vizibilă și apoi vom reseta poziția imaginii înapoi la prima jumătate.
mutarea funcției () backgroundY - = speed; dacă (backgroundY == -1 * înălțime) backgroundY = 0;
În cele din urmă avem a desena()
funcţie. Toate imaginile vor fi redesenate, însă o singură modificare va fi aceea că bgImage
valoarea lui y a fost înlocuită cu variabila backgroundY
.
context.drawImage (bgImage, 0, backgroundY); context.drawImage (logoImage, 50, -10); context.drawImage (playImage, butonulX [0], butonulY [0]); context.drawImage (instructImage, butonulX [1], butonulY [1]); context.drawImage (setăriImage, butonX [2], butonY [2]); context.drawImage (crediteImage, butonulX [3], butonulY [3]);
Testați acum și admirați fundalul de derulare netedă.
Un lucru HTML5
var mouseX; var mouseY; canvas.addEventListener ("mousemove", checkPos);
Cele două variabile introduse vor fi folosite pentru a obține poziția curentă a mouse-ului. Am adăugat un ascultător de evenimente, ca în ActionScript, care apelează funcția checkPos ()
de fiecare dată când se mișcă mouse-ul.
funcția checkPos (mouseEvent) mouseX = mouseEvent.pageX - this.offsetLeft; mouseY = mouseEvent.pageY - this.offsetTop;
Dacă ați alertat valorile mouseX
și mousey
de fiecare dată când mișcați mouse-ul, veți obține poziția corectă. Dar există o problemă: nu toate browserele de desktop moderne acceptă această metodă. Pentru a depăși această problemă, putem folosi în schimb:
dacă (mouseEvent.pageX || mouseEvent.pageY == 0) mouseX = mouseEvent.pageX - this.offsetLeft; mouseY = mouseEvent.pageY - this.offsetTop; altceva dacă (mouseEvent.offsetX || mouseEvent.offsetY == 0) mouseX = mouseEvent.offsetX; mouseY = mouseEvent.offsetY;
Acest lucru verifică dacă browserul utilizează proprietăți "pagină" sau "offset" pentru a readuce poziția mouse-ului și ajustează valorile (dacă este necesar) pentru a obține poziția mouse-ului față de pânză.
Acum, amintiți-vă că nava am instanced, dar nu a atras? Vom lua acea imagine statică, o vom roti și vom face să apară ori de câte ori știm mouse-ul peste butoane!
vapor varX = [0,0]; var naY = [0,0]; var shipWidth = 35; var shipHeight = 40; var shipVisible = false; var shipSize = Lățimea navei; var shipRotate = 0;
Primele patru variabile sunt aceleași ca înainte (avem două poziții deoarece vor exista două nave). shipVisible
variabila va fi setată atunci când mouse-ul este peste un buton. În ceea ce privește shipSize
și shipRotate
, ele vor fi utilizate pentru a scala vertical nava și pentru ao repoziționa pentru a da iluzia că se rotește. Rețineți că imaginile sunt scalate de la dreapta la stânga.
pentru (i = 0; i < buttonX.length; i++) if(mouseX > butonulX [i] && mouseX < buttonX[i] + buttonWidth[i]) if(mouseY > butonulY [i] && mouseY < buttonY[i] + buttonHeight[i]) else
Adăugați codul în checkPos ()
funcţie. Mai intai trecem prin butoanele de acolo (mi-am dat seama ca folosesc valoarea buttonX.length
). Apoi comparăm mouseX
pentru a vedea dacă este mai mare decât butonul curent buttonX
și mai puțin decât a lui butonul ButonX + Lățime
- adică în limitele orizontale ale butonului. Apoi repetăm procesul în altă instrucțiune if pentru valorile Y. Dacă acest lucru este adevărat, atunci mouse-ul trebuie să fie peste un buton, setat astfel shipVisible
la Adevărat
:
shipVisible = true;
Și în gol altfel
declarația a pus-o la fals
; acesta va fi numit ori de câte ori vă scoateți dintr-un buton:
shipVisible = false;
Sub shipVisible = adevărat
vom seta valorile inițiale pentru shipX
și Shipy
, și efectuați toate scalarea în cadrul funcțiilor de deplasare și de desen.
shipX [0] = butonulX [i] - (ShipWidth / 2) - 2; nava [0] = butonul [i] + 2; shipX [1] = butonulX [i] + butonul Width [i] + (ShipWidth / 2); naYY [1] = butonulY [i] + 2;
Pentru primul shipX
, pe care o dorim doar la stânga butonului, am setat valoarea la (butonul curent al lui X - jumătate din lățimea navei) și l-am mutat peste 2 pixeli la stânga pentru a face să arate mai bine. Un proces similar este repetat pentru primul Shipy
. Pentru al doilea shipX
poziționăm la butonul curent (X + cu lățimea butonului + jumătate din lățimea navei) și apoi am setat modelul Y ca înainte.
Partea dificilă vine acum. Trebuie să scarăm nava și să o mutăm pentru a compensa scalarea. În cadrul mișcare()
funcția scrie acest lucru dacă
afirmație.
dacă (shipSize == ShipWidth) shipRotate = -1; dacă (shipSize == 0) shipRotate = 1; shipSize + = shipRotate;
Codul începe să scadă valoarea lui shipSize
, care vor fi utilizate pentru a scala imaginea atunci când o tragem; odată ce atinge zero, procesul se inversează până când este din nou scalarea completă.
Acum ne putem muta în a desena()
funcţie. Sub celelalte metode de tragere adăugați următoarea declarație if.
dacă (shipVisible == true) context.drawImage (ShipImage, shipX [0] - (ShipSize / 2), shipY [0], ShipSize, shipHeight); context.drawImage (ShipImage, shipX [1] - (navăSize / 2), navă [1], navăSize, navă);
Navele sunt trase în mod normal, cu excepția pozițiilor X compensate prin scăderea jumătății scării actuale.
Adăugați un alt ascultător de evenimente pentru mouseup și creați o nouă variabilă pentru un al doilea interval pe care îl vom crea.
var fadeId = 0; canvas.addEventListener ("mouseup", checkClick);
Creați funcția checkClick ().
funcția checkClick (mouseEvent) pentru (i = 0; i < buttonX.length; i++) if(mouseX > butonulX [i] && mouseX < buttonX[i] + buttonWidth[i]) if(mouseY > butonulY [i] && mouseY < buttonY[i] + buttonHeight[i])
Ca și înainte, verificăm dacă poziția mouse-ului este corectă. Acum trebuie să creăm noul interval și să oprim celelalte intervale și ascultători de evenimente.
fadeId = setInterval ("fadeOut ()", 1000 / cadre); clearInterval (timerId); canvas.removeEventListener ("mousemove", checkPos); canvas.removeEventListener ("mouseup", checkClick);
Nimic nou aici, cu excepția faptului că trebuie să creăm o funcție numită fadeOut ()
. De asemenea, trebuie să creați o altă variabilă numită timp
.
var timp = 0,0;
funcția fadeOut () context.fillStyle = "rgba (0,0,0, 0,2)"; context.fillRect (0, 0, lățime, înălțime); timp + = 0,1; dacă (timp> = 2) clearInterval (fadeId); timpul = 0; timerId = setInterval ("actualizare ()", 1000 / cadre); canvas.addEventListener ("mousemove", checkPos); canvas.addEventListener ("mouseup", checkClick);
Ea are câteva metode noi, dar este destul de simplă. Deoarece am oprit toți ascultătorii evenimentului iar celălalt intervalul este complet static. Așadar, redăm în mod repetat un dreptunghi transparent negru pe partea de sus a meniului - fără să îl ștergem - pentru a da iluzia de estompare.
Variabila timp
este mărită de fiecare dată când este apelată funcția și odată ce atinge o anumită valoare (odată ce au trecut 20 de cadre), ștergem intervalul curent. Aici am reinițializat meniul, dar aici este locul unde ați desena o nouă secțiune a meniului.
Un ultim lucru de observat este că atunci când desenați forme pe panza stil de completare
este setată cu o valoare rgb (roșu, verde, albastru). Când doriți să desenați forme transparente, utilizați rgba (roșu, verde, albastru, alfa).
Sper că este demistificat un pic de proces de învățare pentru trecerea de la programarea AS3 simplă la programarea simplu în panza. Postați un comentariu dacă aveți întrebări!