În acest tutorial vom lucra cu panza HTML5 și Javascript pentru a crea un joc dinamic de schimbare a țiglelor. Rezultatul va fi un puzzle care funcționează cu orice imagine dată și are nivele flexibile de dificultate care sunt ușor de ajustat.
Iată o fotografie scurtă a puzzle-ului pe care îl vom construi:
Câteva note:
pânză
element.PUZZLE_DIFFICULTY
, care determină numărul de bucăți. În demo-ul de mai sus, acesta este setat la 4
, oferind un puzzle 4x4. Putem schimba cu ușurință acest lucru - de exemplu, această versiune are o PUZZLE_DIFFICULTY
de 10
. Pentru a începe, creați un director pentru proiect. Plasați o imagine în directorul pe care doriți să-l utilizați ca puzzle. Orice imagine prietenoasă pe web va face, și poate fi orice dimensiune dorința inimii dvs. - asigurați-vă că se potrivește în interiorul ferestrei browserului dvs..
Deschideți un fișier nou utilizând editorul de text preferat și salvați-l în directorul de proiect, lângă imaginea dvs. Apoi, completați această bază HTML
șablon.
HTML5 Puzzle
Tot ce trebuie să facem aici este să creeze un standard HTML5
șablon care conține unul pânză
eticheta cu id
de "pânză". Vom scrie un onload
ascultător în corp
eticheta care ne va suna init ()
când este declanșat.
Acum începeți prin plasarea cursorului în interiorul scenariu
etichetă. De aici și aici toate javascript. Cu excepția variabilelor inițiale, voi organiza secțiunile după funcție. În primul rând vă arată codul și apoi explicați logica.
Gata? Să mergem direct la asta!
Să ne stabilim variabilele și să aruncăm o privire la fiecare.
const PUZZLE_DIFFICULTY = 4; const PUZZLE_HOVER_TINT = '# 009900'; var _canvas; var _stage; var _img; var _pieces; var _puzzleWidth; var _puzzleHeight; var _pieceWidth; var _pieceHeight; var _currentPiece; var _currentDropPiece; var _mouse;
Mai întâi avem câteva constante: PUZZLE_DIFFICULTY
și PUZZLE_HOVER_TINT
. PUZZLE_DIFFICULTY
constantă ține numărul de piese în puzzle-ul nostru. În această aplicație, rândurile și coloanele se potrivesc întotdeauna, prin setare PUZZLE_DIFFICULTY
la 4
, vom obține 16 piese de puzzle în total. Creșterea acestui fapt crește dificultatea puzzle-ului.
Următoarea este o serie de variabile:
_canvas
și _etapă
va avea o referință la panza și respectiv la contextul de desenare. Facem acest lucru, astfel încât nu trebuie să scriem întreaga interogare de fiecare dată când le folosim. Și le vom folosi foarte mult!_img
va fi o referință la imaginea încărcată, pe care o vom copia pixeli din toată aplicația._puzzleWidth
, _puzzleHeight
, _pieceWidth
, și _pieceHeight
va fi folosit pentru a stoca dimensiunile atât a puzzle-ului întreg cât și a fiecărei piese de puzzle individuale. Am stabilit aceste o dată pentru a preveni calcularea lor de peste si peste de fiecare dată când avem nevoie de ele._currentPiece
conține o referință la piesa care este în prezent trasă._currentDropPiece
are o referință la piesa aflată în prezent în poziția de a fi abandonată. (În demo, această piesă este evidențiată în verde.)_șoarece
este o referință care va menține curentul mouse-ului X
și y
poziţie. Aceasta se actualizează atunci când puzzle-ul este apăsat pentru a determina ce piesă este atinsă și când o piesă este târâtă pentru a determina ce piesă se mișcă peste.Acum, la funcțiile noastre.
init ()
Funcţiefuncția init () _img = imagine nouă (); _img.addEventListener ( 'încărcare', onImage, fals); _img.src = "mke.jpg";
Primul lucru pe care dorim să-l facem în aplicația noastră este să încărcăm imaginea pentru puzzle. Obiectul imaginii este inițial instanțiat și setat pentru a noastră _img
variabil. Apoi, ascultăm pentru sarcină
eveniment care ne va da foc onImage ()
atunci când imaginea sa terminat de încărcat. În cele din urmă, setăm sursa imaginii, care declanșează sarcina.
onImage ()
Funcţiefuncția onImage (e) _pieceWidth = Math.floor (_img.width / PUZZLE_DIFFICULTY) _pieceHeight = Matematică (_img.height / PUZZLE_DIFFICULTY) _puzzleWidth = _pieceWidth * PUZZLE_DIFFICULTY; _puzzleHeight = _pieceHeight * PUZZLE_DIFFICULTY; setCanvas (); initPuzzle ();
Acum că imaginea este încărcată cu succes, putem seta majoritatea variabilelor declarate anterior. Facem asta aici pentru că acum avem informații despre imagine și putem să ne stabilim valorile în mod corespunzător.
Primul lucru pe care îl facem este să calculam mărimea fiecărei bucăți de puzzle. Noi facem acest lucru împărțind PUZZLE_DIFFICULTY
valoare după lățimea și înălțimea imaginii încărcate. De asemenea, eliminăm grăsimea de pe margini pentru a ne oferi niște numere frumoase pentru a lucra și pentru a ne asigura că fiecare piesă poate schimba în mod adecvat "sloturile" cu ceilalți.
Apoi vom folosi noile valori ale puzzle-ului pentru a determina dimensiunea totală a puzzle-ului și a le seta _puzzleWidth
și _puzzleHeight
.
În cele din urmă, am anula câteva funcții - setCanvas ()
și initPuzzle ()
.
setCanvas ()
Funcţiefuncția setCanvas () _canvas = document.getElementById ('canvas'); _stage = _canvas.getContext ("2d"); _canvas.width = _puzzleWidth; _canvas.height = _puzzleHeight; _canvas.style.border = "1px solid negru";
Acum că valorile puzzle-ului sunt complete, vrem să ne înființăm pânză
element. Mai întâi ne-am stabilit _canvas
variabilă pentru a ne referi pânză
element, și _etapă
pentru a-i face referire context
.
Acum am setat lăţime
și înălţime
a noastră pânză
pentru a se potrivi dimensiunile imaginii tăiate, urmată de aplicarea unor stiluri simple pentru a crea o graniță neagră în jurul nostru pânză
pentru a afișa limitele puzzle-ului nostru.
initPuzzle ()
Funcţiefuncția initPuzzle () _pieces = []; _mouse = x: 0, y: 0; _currentPiece = null; _currentDropPiece = null; _stage.drawImage (_img, 0, 0, _puzzleWidth, _puzzleHeight, 0, 0, _puzzleWidth, _puzzleHeight); createTitle ("Faceți clic pentru a începe Puzzle"); buildPieces ();
Aici inițializăm puzzle-ul. Am setat această funcție în așa fel încât să o putem numi din nou mai târziu când vrem să reluăm puzzle-ul. Orice altceva care trebuia să fie setat înainte de a juca nu va mai trebui să fie setat din nou.
Mai întâi am stabilit _pieces
ca un gol mulțime
și creați _șoarece
obiect, care va menține poziția mouse-ului pe tot parcursul aplicației. Apoi setăm _currentPiece
și _currentPieceDrop
la nul
. (La prima piesă, aceste valori ar fi deja nul
, dar vrem să ne asigurăm că se resetează atunci când redau puzzle-ul.)
În cele din urmă, este timpul să atragem! Mai întâi tragem întreaga imagine pentru a afișa jucătorului ceea ce vor crea. După aceea, vom crea niște instrucțiuni simple sunând la noi createTitle ()
funcţie.
createTitle ()
Funcţiefuncția createTitle (msg) _stage.fillStyle = "# 000000"; _stage.globalAlpha = .4; _stage.fillRect (100, _puzzleHeight - 40, _puzzleWidth - 200,40); _stage.fillStyle = "#FFFFFF"; _stage.globalAlpha = 1; _stage.textAlign = "centru"; _stage.textBaseline = "mijloc"; _stage.font = "20px Arial"; _stage.fillText (msg, _puzzleWidth / 2, _puzzleHeight - 20);
Aici vom crea un mesaj destul de simplu care instruiește utilizatorul să facă clic pe puzzle pentru a începe.
Mesajul nostru va fi un dreptunghi semi-transparent care va servi ca fundal al textului nostru. Acest lucru permite utilizatorului să vadă imaginea din spatele acestuia și asigură, de asemenea, că textul alb va fi lizibil pe orice imagine
Am stabilit pur și simplu stil de completare
la negru și globalAlpha
la .4
, înainte de a completa un dreptunghi negru scurt în partea de jos a imaginii.
De cand globalAlpha
afectează întreaga pânză, trebuie să o readucăm înapoi 1
(opac) înainte de a desena textul. Pentru a configura titlul, setăm aliniere text
pentru a "centra" și pentru a textBaseline
la 'mijloc'
. Putem aplica și altele font
proprietăţi.
Pentru a desena textul, folosim fillText ()
metodă. Trecem în msg
variabilă și se plasează la centrul orizontal al pânză
, și centrul vertical al dreptunghiului.
buildPieces ()
Funcţiefuncția buildPieces () var i; var bucată; var xPos = 0; var yPos = 0; pentru (i = 0; i < PUZZLE_DIFFICULTY * PUZZLE_DIFFICULTY;i++) piece = ; piece.sx = xPos; piece.sy = yPos; _pieces.push(piece); xPos += _pieceWidth; if(xPos >= _puzzleWidth) xPos = 0; yPos + = _pieceHeight; document.onmousedown = shufflePuzzle;
În cele din urmă, este timpul să construim puzzle-ul!
Noi facem asta prin construirea unui obiect
pentru fiecare piesă. Aceste obiecte nu vor fi responsabile pentru redarea pe pânză, ci mai degrabă să țină doar referințe la ceea ce să atragă și unde. Acestea fiind spuse, să ajungem la ele.
În primul rând, să declarăm câteva variabile pe care le vom reutiliza prin buclă. Vrem să setăm bucla pentru a repeta numărul de piese de puzzle de care avem nevoie. Obținem această valoare prin înmulțire PUZZLE_DIFFICULTY
de la sine - așa că în acest caz primim 16.
pentru (i = 0; i < PUZZLE_DIFFICULTY * PUZZLE_DIFFICULTY;i++) piece = ; piece.sx = xPos; piece.sy = yPos; _pieces.push(piece); xPos += _pieceWidth; if(xPos >= _puzzleWidth) xPos = 0; yPos + = _pieceHeight;
Începeți prin a crea un spațiu gol bucată
obiect. Apoi adăugați s x
și sy
proprietățile obiectului. În prima iterație, aceste valori sunt 0
și reprezintă punctul din imaginea noastră de unde vom începe să tragem. Acum, împingeți-l la _pieces []
matrice. Acest obiect va conține, de asemenea, proprietățile xPos
și yPos
, care ne va spune poziția actuală în puzzle unde ar trebui să fie desenată piesa. Vom amesteca obiectele înainte de a fi redate, astfel încât aceste valori nu trebuie să fie setate încă.
Ultimul lucru pe care îl facem în fiecare buclă este creșterea variabilei locale xPos
de _pieceWidth
. Înainte de a continua cu bucla, vom determina dacă trebuie să mergem la următorul rând de bucăți verificând dacă xPos
este dincolo de lățimea puzzle-ului. Dacă da, ne reinițializăm xPos
înapoi la 0 și măriți yPos
de _pieceHeight
.
Acum avem piesele noastre de puzzle toate stocate departe frumos în nostru _pieces
matrice. În acest moment, codul încetează în cele din urmă să execute și așteaptă ca utilizatorul să interacționeze. Am setat un ascultător de clic pe document
pentru a trage shufflePuzzle ()
atunci când se declanșează, care va începe jocul.
shufflePuzzle ()
Funcţiefuncția shufflePuzzle () _pieces = shuffleArray (_pieces); _stage.clearRect (0,0, _puzzleWidth, _puzzleHeight); var i; var bucată; var xPos = 0; var yPos = 0; pentru (i = 0; i < _pieces.length;i++) piece = _pieces[i]; piece.xPos = xPos; piece.yPos = yPos; _stage.drawImage(_img, piece.sx, piece.sy, _pieceWidth, _pieceHeight, xPos, yPos, _pieceWidth, _pieceHeight); _stage.strokeRect(xPos, yPos, _pieceWidth,_pieceHeight); xPos += _pieceWidth; if(xPos >= _puzzleWidth) xPos = 0; yPos + = _pieceHeight; document.onmousedown = onPuzzleClick;
(i), o [i], o [i] = o [i] = o [ j], o [j] = x); retur o;
Mai intai lucrurile: shuffle _pieces []
matrice. Folosesc aici o funcție utilă de utilitate, care va amesteca indicii matricei introduse în ea. Explicația acestei funcții este dincolo de subiectul acestui tutorial, așa că vom merge mai departe, știind că am reușit să ne amestecăm piesele. (Pentru o introducere de bază a amestecării, aruncați o privire la acest tutorial.)
Să clarificăm mai întâi toate graficele atrase de pânză
pentru a face loc pentru desenarea pieselor noastre. Apoi, configurați matricea asemănătoare cu cea pe care am făcut-o când creați mai întâi piesele noastre.
pentru (i = 0; i < _pieces.length;i++) piece = _pieces[i]; piece.xPos = xPos; piece.yPos = yPos; _stage.drawImage(_img, piece.sx, piece.sy, _pieceWidth, _pieceHeight, xPos, yPos, _pieceWidth, _pieceHeight); _stage.strokeRect(xPos, yPos, _pieceWidth,_pieceHeight); xPos += _pieceWidth; if(xPos >= _puzzleWidth) xPos = 0; yPos + = _pieceHeight;
Mai întâi de toate, utilizați eu
variabilă pentru a configura referința noastră la piesa curentă a bucății din bucla. Acum vom popula xPos
și yPos
proprietățile pe care le-am menționat mai devreme, care vor fi 0
în prima noastră iterație.
Acum, în sfârșit, ne desenați piesele.
Primul parametru al lui drawImage ()
atribuie sursa imaginii de la care vrem să trasăm. Apoi folosiți obiectele piesei s x
și sy
proprietăți, împreună cu _pieceWidth
și _pieceHeight
, pentru a popula parametrii care declară aria imaginii în care să se deseneze. Ultimii patru parametri stabilesc aria zonei pânză
unde vrem să desenezi. Noi folosim xPos
și yPos
valori pe care amândoi le construim în bucle și atribuind obiectului.
Imediat după aceasta, tragem o lovitură rapidă în jurul piesei pentru a da o margine, care o va deosebi frumos de celelalte piese.
Acum așteptăm ca utilizatorul să apuce o piesă, stabilind altul clic
ascultător. De data asta o să tragă un onPuzzleClick ()
funcţie.
onPuzzleClick ()
Funcţiefuncția onPuzzleClick (e) if (e.layerX || e.layerX == 0) _mouse.x = e.layerX - _canvas.offsetLeft; _mouse.y = e.layerY - _canvas.offsetTop; altfel dacă (e.offsetX || e.offsetX == 0) _mouse.x = e.offsetX - _canvas.offsetLeft; _mouse.y = e.offsetY - _canvas.offsetTop; _currentPiece = checkPieceClicked (); dacă (_currentPiece! = null) _stage.clearRect (_currentPiece.xPos, _currentPiece.yPos, _pieceWidth, _pieceHeight); _stage.save (); _stage.globalAlpha = .9; _stage.drawImage (_img, _currentPiece.sx, _currentPiece.sy, _pieceWidth, _pieceHeight, _mouse.x - (_pieceWidth / 2), _mouse.y - (_pieceHeight / 2), _pieceWidth, _pieceHeight); _stage.restore (); document.onmousemove = updatePuzzle; document.onmouseup = bucatăDropată;
Știm că a fost făcut clic pe puzzle; acum trebuie să determinăm ce piesă a fost făcută. Această condiție simplă ne va aduce poziția mouse-ului pe toate browserele de desktop moderne care acceptă pânză
, folosind fie e.layerX
și e.layerY
sau e.offsetX
și e.offsetY
. Utilizați aceste valori pentru a ne actualiza _șoarece
obiect prin atribuirea acestuia X
și a y
proprietatea de a menține poziția actuală a mouse-ului - în acest caz, poziția în care a fost făcut clic.
În linia 112 am stabilit imediat _currentPiece
la valoarea returnată din partea noastră checkPieceClicked ()
funcţie. Separăm acest cod deoarece dorim să îl folosim mai târziu când tragem piesa de puzzle. Voi explica această funcție în pasul următor.
Dacă valoarea returnată a fost nul
, pur și simplu nu facem nimic, deoarece acest lucru implică faptul că utilizatorul nu a făcut clic pe o piesă de puzzle. Cu toate acestea, dacă facem să preluăm o piesă de puzzle, vrem să o atașăm la mouse și să o decolăm puțin pentru a dezvălui piesele dedesubt. Deci, cum facem asta??
În primul rând, noi clarificăm pânză
zona în care piesa stătea înainte să dăm clic pe ea. Folosim clearRect ()
încă o dată, dar în acest caz trecem numai în zona obținută de la _currentPiece
obiect. Înainte de a ne redresa, vrem să Salvați()
contextul panzei înainte de a continua. Acest lucru va asigura că tot ce facem după salvare nu va atrage pur și simplu nimic în calea lui. Facem acest lucru pentru că vom scădea ușor piesa târâtă și vrem să vedem piesele sub ea. Dacă nu am sunat Salvați()
, tocmai am tras peste orice grafică în felul ăsta - estompată sau nu.
Acum desenați imaginea astfel încât centrul acesteia să fie poziționat deasupra indicatorului mouse-ului. Primii 5 parametri ai drawImage
va fi întotdeauna aceeași în întreaga aplicație. Când faceți clic, următorii doi parametri vor fi actualizați pentru a se centura pe pointerul mouse-ului. Ultimii doi parametri, lăţime
și înălţime
pentru a desena, nu se va schimba niciodată.
În cele din urmă numim restabili()
metodă. Acest lucru înseamnă, în esență, că am terminat folosind noua valoare alfa și doriți să restaurați toate proprietățile înapoi în locul în care se aflau. Pentru a încheia această funcție adăugăm încă doi ascultători. Unul pentru atunci când mutăm mouse-ul (tragerea piesei puzzle-ului), și unul pentru când vom lăsa să plecăm (picătură piesa de puzzle).
checkPieceClicked ()
Funcţiefuncția checkPieceClicked () var i; var bucată; pentru (i = 0; i < _pieces.length;i++) piece = _pieces[i]; if(_mouse.x < piece.xPos || _mouse.x > (piece.xPos + _pieceWidth) || _mouse.y < piece.yPos || _mouse.y > (piece.yPos + _pieceHeight)) // PIECE NOT HIT altceva return piece; întoarce null;
Acum trebuie să renunțem puțin. Am reușit să determinăm ce piesă a fost făcută, dar cum am făcut-o? E destul de simplu de fapt. Ceea ce trebuie să facem este să țâșniți prin toate piesele de puzzle și să determinați dacă clicul a fost în limitele oricărui obiect al nostru. Dacă găsim una, vom întoarce obiectul corespunzător și vom termina funcția. Dacă nu găsim nimic, ne întoarcem nul
.
updatePuzzle ()
Funcţieactualizare functiePuzzle (e) _currentDropPiece = null; dacă (e.layerX || e.layerX == 0) _mouse.x = e.layerX - _canvas.offsetLeft; _mouse.y = e.layerY - _canvas.offsetTop; altfel dacă (e.offsetX || e.offsetX == 0) _mouse.x = e.offsetX - _canvas.offsetLeft; _mouse.y = e.offsetY - _canvas.offsetTop; _stage.clearRect (0,0, _puzzleWidth, _puzzleHeight); var i; var bucată; pentru (i = 0; i < _pieces.length;i++) piece = _pieces[i]; if(piece == _currentPiece) continue; _stage.drawImage(_img, piece.sx, piece.sy, _pieceWidth, _pieceHeight, piece.xPos, piece.yPos, _pieceWidth, _pieceHeight); _stage.strokeRect(piece.xPos, piece.yPos, _pieceWidth,_pieceHeight); if(_currentDropPiece == null) if(_mouse.x < piece.xPos || _mouse.x > (piece.xPos + _pieceWidth) || _mouse.y < piece.yPos || _mouse.y > (buc.yPos + _pieceHeight)) // NU EXTERN altceva _currentDropPiece = bucată; _stage.save (); _stage.globalAlpha = .4; _stage.fillStyle = PUZZLE_HOVER_TINT; _stage.fillRect (_currentDropPiece.xPos, _currentDropPiece.yPos, _pieceWidth, _pieceHeight); _stage.restore (); _stage.save (); _stage.globalAlpha = .6; _stage.drawImage (_img, _currentPiece.sx, _currentPiece.sy, _pieceWidth, _pieceHeight, _mouse.x - (_pieceWidth / 2), _mouse.y - (_pieceHeight / 2), _pieceWidth, _pieceHeight); _stage.restore (); _stage.strokeRect (_mouse.x - (_pieceWidth / 2), _mouse.y - (_pieceHeight / 2), _pieceWidth, _pieceHeight);
Acum, înapoi la tragere. Apelam această funcție când utilizatorul mișcă mouse-ul. Aceasta este cea mai mare funcție a aplicației, deoarece face mai multe lucruri. Sa incepem. O să-l rup în timp ce mergem.
_currentDropPiece = null; dacă (e.layerX || e.layerX == 0) _mouse.x = e.layerX - _canvas.offsetLeft; _mouse.y = e.layerY - _canvas.offsetTop; altfel dacă (e.offsetX || e.offsetX == 0) _mouse.x = e.offsetX - _canvas.offsetLeft; _mouse.y = e.offsetY - _canvas.offsetTop;
Începeți prin setare _currentDropPiece
la nul
. Trebuie să reinițializăm acest lucru nul
pe actualizare, din cauza șanselor ca piesa noastră să fie târâtă înapoi la casă. Nu vrem pe cei anteriori _currentDropPiece
valoare în jurul valorii de agățat. Apoi setăm _șoarece
obiect în același mod în care am făcut clic.
_stage.clearRect (0,0, _puzzleWidth, _puzzleHeight);
Aici trebuie să clarificăm toate imaginile de pe panza. Trebuie, în esență, să redesemnăm piesele de puzzle, deoarece obiectul care este tras în sus va avea efectul apariției lor. Dacă nu am face acest lucru, am fi văzut niște rezultate foarte ciudate urmând calea piesei noastre de puzzle trase.
var i; var bucată; pentru (i = 0; i < _pieces.length;i++)
Începeți prin a configura bucla obișnuită.
bucata = piesele [i]; dacă (piece == _currentPiece) continue;
Creați-ne bucată
referință ca de obicei. Apoi, verificați dacă piesa pe care o prezentăm în prezent este aceeași cu piesa pe care o trasăm. Dacă da, continuați buclele. Aceasta va menține spațiul liber al casei trase.
_stage.drawImage (_img, piece.sx, piece.sy, _pieceWidth, _pieceHeight, piece.xPos, piece.yPos, _pieceWidth, _pieceHeight); _stage.strokeRect (bucată.xPos, bucată.Plasă, piesă lățime, piesă de înălțime);
Deplasând-o, retușați piesa de puzzle utilizând proprietățile ei exact așa cum am făcut-o atunci când le-am desenat mai întâi. Va trebui să tragi și frontiera.
dacă (_currentDropPiece == null) if (_mouse.x < piece.xPos || _mouse.x > (piece.xPos + _pieceWidth) || _mouse.y < piece.yPos || _mouse.y > (buc.yPos + _pieceHeight)) // NU EXTERN altceva _currentDropPiece = bucată; _stage.save (); _stage.globalAlpha = .4; _stage.fillStyle = PUZZLE_HOVER_TINT; _stage.fillRect (_currentDropPiece.xPos, _currentDropPiece.yPos, _pieceWidth, _pieceHeight); _stage.restore ();
Deoarece avem o referință la fiecare obiect din buclă, putem folosi și această ocazie pentru a verifica dacă piesa trasă este pe partea de sus a acesteia. Facem acest lucru pentru că vrem să oferim utilizatorilor feedback cu privire la ce piesă poate fi abandonată. Hai să intrăm în codul ăsta acum.
Mai întâi vrem să vedem dacă această buclă a produs deja o țintă de scădere. Dacă este așa, nu trebuie să ne deranjăm, deoarece este posibilă o singură atingere și orice mișcare a mouse-ului dat. Dacă nu, _currentDropPiece
va fi nul
și putem trece în logică. Deoarece mouse-ul nostru se află în mijlocul piesei trase, tot ce trebuie să facem este să determinăm ce altă piesă sa terminat.
Apoi, folosiți-ne la îndemână checkPieceClicked ()
pentru a determina dacă mouse-ul se află pe obiectul curent în bucla. Dacă da, am setat _currentDropPiece
variați și desenați o cutie colorată deasupra piesei puzzle-ului, indicând faptul că aceasta este acum țintă.
A își aminti să Salvați()
și restabili()
. În caz contrar, veți obține caseta colorată și nu imaginea dedesubt.
_stage.save (); _stage.globalAlpha = .6; _stage.drawImage (_img, _currentPiece.sx, _currentPiece.sy, _pieceWidth, _pieceHeight, _mouse.x - (_pieceWidth / 2), _mouse.y - (_pieceHeight / 2), _pieceWidth, _pieceHeight); _stage.restore (); _stage.strokeRect (_mouse.x - (_pieceWidth / 2), _mouse.y - (_pieceHeight / 2), _pieceWidth, _pieceHeight);
Nu în ultimul rând, trebuie să redesemnăm piesa trasă. Codul este același ca atunci când am făcut clic pentru prima dată, dar mouse-ul sa mutat, astfel încât poziția sa să fie actualizată.
pieceDropped ()
Funcţiefuncția bucatăDropată (e) document.onmousemove = null; document.onmouseup = null; dacă (_currentDropPiece! = null) var tmp = xPos: _currentPiece.xPos, yPos: _currentPiece.yPos; _currentPiece.xPos = _currentDropPiece.xPos; _currentPiece.yPos = _currentDropPiece.yPos; _currentDropPiece.xPos = tmp.xPos; _currentDropPiece.yPos = tmp.yPos; resetPuzzleAndCheckWin ();
OK, cel mai rău este în spatele nostru. Acum reușim să tragem cu succes o piesă de puzzle și chiar să obținem un feedback vizual despre locul în care va fi abandonat. Acum tot ce a mai rămas este să renunți la piesă. Să eliminăm imediat ascultătorii de îndată ce nu se trage nimic.
Apoi, verificați asta _currentDropPiece
nu este nul
. Dacă este, înseamnă că l-am târât înapoi în zona de acasă a piesei și nu pe alt slot. Dacă nu este nul
, vom continua cu funcția.
Ceea ce facem acum este pur și simplu să schimbați xPos
și yPos
din fiecare bucată. Facem un obiect temp rapid ca tampon pentru a ține una dintre valorile obiectului în procesul de schimbare. În acest moment, cele două piese au și noi xPos
și yPos
valori, și va intra în noile lor case pe următoarea remiză. Asta vom face acum, verificând simultan dacă jocul a fost câștigat.
resetPuzzleAndCheckWin ()
Funcţieresetarea funcțieiPuzzleAndCheckWin () _stage.clearRect (0,0, _puzzleWidth, _puzzleHeight); var gameWin = adevărat; var i; var bucată; pentru (i = 0; i < _pieces.length;i++) piece = _pieces[i]; _stage.drawImage(_img, piece.sx, piece.sy, _pieceWidth, _pieceHeight, piece.xPos, piece.yPos, _pieceWidth, _pieceHeight); _stage.strokeRect(piece.xPos, piece.yPos, _pieceWidth,_pieceHeight); if(piece.xPos != piece.sx || piece.yPos != piece.sy) gameWin = false; if(gameWin) setTimeout(gameOver,500);
Încă o dată, eliminați pânză
și să înființeze o gameWin
variabilă, setându-l la Adevărat
în mod implicit. Acum continuați cu bucla noastră de bucăți foarte cunoscute.
Codul aici ar trebui să pară familiar, așa că nu vom trece peste el. Pur și simplu trage piesele înapoi în sloturile originale sau noi. În cadrul acestei bucle, dorim să vedem dacă fiecare piesă este trasă în poziția câștigătoare. Acest lucru este simplu: verificăm dacă ne vom vedea s x
și sy
proprietățile se potrivesc cu xPos
și yPos
. Dacă nu, știm că nu am reușit să câștigăm puzzle-ul și să ne fixăm gameWin
la fals
. Dacă am făcut-o prin buclă cu toată lumea în locurile lor câștigătoare, am stabilit un rapid pauză
să ne sunăm joc încheiat()
metodă. (Am setat un timeout astfel încât ecranul să nu se schimbe atât de drastic la căderea piesei de puzzle.)
joc încheiat()
Funcţiefuncția gameOver () document.onmousedown = null; document.onmousemove = null; document.onmouseup = null; initPuzzle ();
Aceasta este ultima noastră funcție! Aici eliminăm toți ascultătorii și sunăm initPuzzle ()
, care resetează toate valorile necesare și așteaptă ca utilizatorul să redea.
Faceți clic aici pentru a vedea rezultatul final.
După cum puteți vedea, puteți realiza o mulțime de lucruri creative noi în HTML5 utilizând zone bitmap selectate de imagini încărcate și desen. Puteți extinde cu ușurință această aplicație prin adăugarea de scoruri și poate chiar de un cronometru pentru a da mai mult gameplay. O altă idee ar fi să sporiți dificultatea și să selectați o altă imagine în joc încheiat()
funcție, oferind nivelurile de joc.