In questo tutorial lavoreremo con la tela HTML5 e Javascript per creare un gioco dinamico di scambio di tessere. Il risultato sarà un puzzle che funziona con qualsiasi immagine, e ha livelli di difficoltà flessibili facilmente regolabili.
Ecco una rapida carrellata del puzzle che costruiremo:
Un paio di note:
tela
elemento.PUZZLE_DIFFICULTY
, che determina il numero di pezzi. Nella demo sopra, questo è impostato su 4
, dando un puzzle 4x4. Possiamo facilmente cambiare questo - per esempio, questa versione ha un PUZZLE_DIFFICULTY
di 10
. Per iniziare, crea una directory per il progetto. Inserisci un'immagine nella directory che vuoi utilizzare come puzzle. Qualsiasi immagine web friendly andrà bene e può essere di qualsiasi dimensione il tuo cuore desidera - basta assicurarsi che si adatti alla piega della finestra del browser.
Apri un nuovo file usando il tuo editor di testo preferito e salvalo nella directory del tuo progetto, accanto alla tua immagine. Quindi, completa questa base HTML
modello.
HTML5 Puzzle
Tutto ciò che dobbiamo fare qui è creare uno standard HTML5
modello contenente uno tela
tag con il id
di "tela". Scriveremo un onload
ascoltatore nel corpo
tag che chiamerà il nostro dentro()
funzione quando sparato.
Ora inizia posizionando il cursore all'interno del copione
etichetta. Da qui in avanti è tutto javascript. Ad eccezione delle variabili iniziali, organizzerò le sezioni per funzione. Per prima cosa ti mostri il codice e poi spieghi la logica.
Pronto? Andiamo subito ad esso!
Impostiamo le nostre variabili e diamo un'occhiata a ciascuna di esse.
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;
Innanzitutto abbiamo un paio di costanti: PUZZLE_DIFFICULTY
e PUZZLE_HOVER_TINT
. Il PUZZLE_DIFFICULTY
costante tiene il numero di pezzi nel nostro puzzle. In questa applicazione, le righe e le colonne corrispondono sempre, quindi impostando PUZZLE_DIFFICULTY
a 4
, otteniamo 16 puzzle in totale. Aumentando questo aumenta la difficoltà del puzzle.
La prossima è una serie di variabili:
_tela
e _palcoscenico
manterrà un riferimento alla tela e al suo contesto di disegno, rispettivamente. Lo facciamo in modo da non dover scrivere l'intera query ogni volta che li usiamo. E li useremo molto!_img
sarà un riferimento all'immagine caricata, che copieremo pixel da tutta l'applicazione._puzzleWidth
, _puzzleHeight
, _pieceWidth
, e _pieceHeight
sarà usato per memorizzare le dimensioni sia dell'intero puzzle sia di ogni singolo pezzo del puzzle. Le impostiamo una volta per impedire di calcolarle più e più volte ogni volta che ne abbiamo bisogno._currentPiece
contiene un riferimento al pezzo attualmente trascinato._currentDropPiece
contiene un riferimento al pezzo attualmente in posizione da lasciare cadere. (Nella demo, questo pezzo è evidenziato in verde.)_topo
è un riferimento che manterrà la corrente del mouse X
e y
posizione. Questo viene aggiornato quando viene cliccato il puzzle per determinare quale pezzo viene toccato e quando un pezzo viene trascinato per determinare quale pezzo è sospeso sopra.Ora, alle nostre funzioni.
dentro()
Funzionefunction init () _img = new Image (); _img.addEventListener ( 'carico', onImage, false); _img.src = "mke.jpg";
La prima cosa che vogliamo fare nella nostra applicazione è caricare l'immagine per il puzzle. L'oggetto immagine viene prima istanziato e impostato sul nostro _img
variabile. Successivamente, ascoltiamo il caricare
evento che poi licenzierà onImage ()
funzione al termine del caricamento dell'immagine. Infine impostiamo la fonte dell'immagine, che attiva il carico.
onImage ()
Funzionefunction onImage (e) _pieceWidth = Math.floor (_img.width / PUZZLE_DIFFICULTY) _pieceHeight = Math.floor (_img.height / PUZZLE_DIFFICULTY) _puzzleWidth = _pieceWidth * PUZZLE_DIFFICULTY; _puzzleHeight = _pieceHeight * PUZZLE_DIFFICULTY; setCanvas (); initPuzzle ();
Ora che l'immagine è stata caricata correttamente, possiamo impostare la maggior parte delle variabili dichiarate in precedenza. Lo facciamo qui perché ora abbiamo informazioni sull'immagine e possiamo impostare i nostri valori in modo appropriato.
La prima cosa che facciamo è calcolare la dimensione di ogni pezzo del puzzle. Lo facciamo dividendo il PUZZLE_DIFFICULTY
valore per larghezza e altezza dell'immagine caricata. Abbiamo anche tagliato il grasso dai bordi per darci dei bei numeri pari con cui lavorare e assicurarci che ogni pezzo possa scambiare opportunamente le "fessure" con gli altri.
Successivamente utilizziamo i nostri nuovi valori dei pezzi del puzzle per determinare la dimensione totale del puzzle e impostare questi valori su _puzzleWidth
e _puzzleHeight
.
Infine, richiamiamo alcune funzioni - setCanvas ()
e initPuzzle ()
.
setCanvas ()
Funzionefunction setCanvas () _canvas = document.getElementById ('canvas'); _stage = _canvas.getContext ('2d'); _canvas.width = _puzzleWidth; _canvas.height = _puzzleHeight; _canvas.style.border = "1px solido nero";
Ora che i nostri valori del puzzle sono completi, vogliamo impostare il nostro tela
elemento. Per prima cosa impostiamo il nostro _tela
variabile per fare riferimento al nostro tela
elemento, e _palcoscenico
per riferirsi al suo contesto
.
Ora impostiamo il larghezza
e altezza
della nostra tela
per abbinare la dimensione della nostra immagine ritagliata, seguita dall'applicazione di alcuni stili semplici per creare un bordo nero intorno al nostro tela
per mostrare i limiti del nostro puzzle.
initPuzzle ()
Funzionefunction initPuzzle () _pieces = []; _mouse = x: 0, y: 0; _currentPiece = null; _currentDropPiece = null; _stage.drawImage (_img, 0, 0, _puzzleWidth, _puzzleHeight, 0, 0, _puzzleWidth, _puzzleHeight); createTitle ("Clicca per iniziare il puzzle"); buildPieces ();
Qui inizializziamo il puzzle. Impostiamo questa funzione in modo tale da poterla richiamare più tardi quando vogliamo riprodurre il puzzle. Tutto il resto che doveva essere impostato prima di giocare non ha bisogno di essere reimpostato.
Per prima cosa abbiamo impostato _pieces
come vuoto schieramento
e creare il _topo
oggetto, che manterrà la nostra posizione del mouse per tutta l'applicazione. Quindi impostiamo il _currentPiece
e _currentPieceDrop
a nullo
. (Al primo gioco questi valori sarebbero già stati nullo
, ma vogliamo assicurarci che vengano ripristinati durante la riproduzione del puzzle.)
Finalmente, è tempo di disegnare! Per prima cosa disegniamo l'intera immagine per mostrare al giocatore ciò che creeranno. Dopodiché creiamo alcune semplici istruzioni chiamando il nostro createTitle ()
funzione.
createTitle ()
Funzionefunction createTitle (msg) _stage.fillStyle = "# 000000"; _stage.globalAlpha = .4; _stage.fillRect (100, _puzzleHeight - 40, _puzzleWidth - 200,40); _stage.fillStyle = "#FFFFFF"; _stage.globalAlpha = 1; _stage.textAlign = "center"; _stage.textBaseline = "middle"; _stage.font = "20px Arial"; _stage.fillText (msg, _puzzleWidth / 2, _puzzleHeight - 20);
Qui creiamo un messaggio abbastanza semplice che indica all'utente di fare clic sul puzzle per iniziare.
Il nostro messaggio sarà un rettangolo semitrasparente che servirà da sfondo del nostro testo. Ciò consente all'utente di vedere l'immagine dietro di esso e assicura anche che il nostro testo bianco sarà leggibile su qualsiasi immagine
Abbiamo semplicemente impostato fillStyle
al nero e globalAlpha
a .4
, prima di riempire un breve rettangolo nero nella parte inferiore dell'immagine.
Da globalAlpha
interessa l'intero canvas, dobbiamo impostarlo su 1
(opaco) prima di disegnare il testo. Per impostare il nostro titolo, abbiamo impostato il textAlign
a 'centro' e il TextBaseline
a 'Middle'
. Possiamo anche applicarne alcuni font
proprietà.
Per disegnare il testo, usiamo il fillText ()
metodo. Passiamo nel msg
variabile e posizionarlo al centro orizzontale del tela
, e il centro verticale del rettangolo.
buildPieces ()
Funzionefunction buildPieces () var i; pezzo var; var xPos = 0; var yPos = 0; per (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;
Finalmente è il momento di costruire il puzzle!
Lo facciamo costruendo un oggetto
per ogni pezzo. Questi oggetti non saranno responsabili del rendering sulla tela, ma piuttosto semplicemente dei riferimenti su cosa disegnare e dove. Detto questo, arriviamo ad esso.
Innanzitutto, dichiariamo alcune variabili che riutilizzeremo nel ciclo. Vogliamo impostare il ciclo per iterare attraverso il numero di pezzi del puzzle di cui abbiamo bisogno. Otteniamo questo valore moltiplicando PUZZLE_DIFFICULTY
da solo - quindi in questo caso otteniamo 16.
per (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;
Inizia creando un vuoto pezzo
oggetto. Quindi aggiungere il sx
e sy
proprietà all'oggetto. Nella prima iterazione, questi valori sono 0
e rappresenta il punto nella nostra immagine da cui inizieremo a disegnare. Ora spingilo al _pieces []
array. Questo oggetto conterrà anche le proprietà xPos
e yPos
, che ci dirà la posizione corrente nel puzzle in cui il pezzo dovrebbe essere disegnato. Mischeremo gli oggetti prima che siano giocabili, quindi non è necessario impostare ancora questi valori.
L'ultima cosa che facciamo in ogni ciclo è aumentare la variabile locale xPos
di _pieceWidth
. Prima di continuare con il ciclo, determiniamo se è necessario passare alla fila successiva di pezzi controllando se xPos
è oltre la larghezza del puzzle. Se è così, resettiamo xPos
torna a 0 e aumenta yPos
di _pieceHeight
.
Ora abbiamo i nostri pezzi del puzzle tutti ben conservati nel nostro _pieces
array. A questo punto, il codice smette di essere in esecuzione e attende che l'utente interagisca. Impostiamo un ascoltatore di clic su documento
licenziare il shufflePuzzle ()
funzione quando attivata, che inizierà il gioco.
shufflePuzzle ()
Funzionefunction shufflePuzzle () _pieces = shuffleArray (_pieces); _stage.clearRect (0,0, _puzzleWidth, _puzzleHeight); var i; pezzo var; var xPos = 0; var yPos = 0; per (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;
function shuffleArray (o) for (var j, x, i = o.length; i; j = parseInt (Math.random () * i), x = o [- i], o [i] = o [ j], o [j] = x); return o;
Per prima cosa: mischia il _pieces []
array. Sto usando qui una bella funzione di utilità che mescolerà gli indici dell'array passato. La spiegazione di questa funzione va oltre l'argomento di questo tutorial, quindi andremo avanti, sapendo di aver mescolato con successo i nostri pezzi. (Per un'introduzione di base allo shuffling, dai un'occhiata a questo tutorial).
Deselezioniamo innanzitutto tutti i grafici disegnati su tela
per far posto a disegnare i nostri pezzi. Quindi, imposta l'array in modo simile a come facevamo quando creavamo i nostri oggetti pezzo.
per (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;
Prima di tutto, usa il io
variabile per impostare il nostro riferimento all'oggetto pezzo corrente nel ciclo. Ora popoliamo il xPos
e yPos
proprietà che ho menzionato prima, che sarà 0
nella nostra prima iterazione.
Ora, finalmente, disegniamo i nostri pezzi.
Il primo parametro di drawImage ()
assegna la fonte dell'immagine da cui attingere. Quindi usa gli oggetti pezzo sx
e sy
proprietà, insieme a _pieceWidth
e _pieceHeight
, per popolare i parametri che dichiarano l'area dell'immagine in cui attingere. Gli ultimi quattro parametri impostano l'area del tela
dove vogliamo disegnare. Noi usiamo il xPos
e yPos
valori che stiamo entrambi costruendo nel loop e assegnandoci all'oggetto.
Subito dopo, disegniamo un tratto veloce attorno al pezzo per dargli un bordo, che lo separerà bene dagli altri pezzi.
Ora aspettiamo che l'utente prenda un pezzo impostandone un altro clic
ascoltatore. Questa volta sparerà un onPuzzleClick ()
funzione.
onPuzzleClick ()
Funzionefunction onPuzzleClick (e) if (e.layerX || e.layerX == 0) _mouse.x = e.layerX - _canvas.offsetLeft; _mouse.y = e.layerY - _canvas.offsetTop; else if (e.offsetX || e.offsetX == 0) _mouse.x = e.offsetX - _canvas.offsetLeft; _mouse.y = e.offsetY - _canvas.offsetTop; _currentPiece = checkPieceClicked (); if (_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 = pieceDropped;
Sappiamo che il puzzle è stato cliccato; ora dobbiamo determinare su quale pezzo è stato fatto clic. Questo semplice condizionale ci porterà la posizione del mouse su tutti i browser desktop moderni che supportano tela
, usando entrambi e.layerX
e e.layerY
o e.offsetX
e e.offsetY
. Utilizza questi valori per aggiornare il nostro _topo
oggetto assegnandolo a X
e a y
proprietà per mantenere la posizione corrente del mouse - in questo caso, la posizione in cui è stato fatto clic.
Nella riga 112, quindi, impostiamo immediatamente _currentPiece
al valore restituito dal nostro checkPieceClicked ()
funzione. Separiamo questo codice perché vogliamo usarlo in seguito quando trascini il pezzo del puzzle. Spiegherò questa funzione nel prossimo passaggio.
Se il valore restituito era nullo
, semplicemente non facciamo nulla, poiché ciò implica che l'utente non ha effettivamente fatto clic su un pezzo del puzzle. Tuttavia, se recuperiamo un pezzo del puzzle, vogliamo collegarlo al mouse e sbiadirlo un po 'per rivelare i pezzi sottostanti. Quindi, come lo facciamo??
Per prima cosa cancelliamo il tela
area in cui il pezzo si è seduto prima che l'avessimo fatto clic. Noi usiamo clearRect ()
ancora una volta, ma in questo caso passiamo solo nell'area ottenuta dal _currentPiece
oggetto. Prima di ridisegnarlo, lo vogliamo salvare()
il contesto della tela prima di procedere. Ciò assicurerà che tutto ciò che disegniamo dopo il salvataggio non si limiterà a disegnare qualsiasi cosa a suo modo. Lo facciamo perché dovremmo sbiadire leggermente il pezzo trascinato e vogliamo vedere i pezzi sotto di esso. Se non abbiamo chiamato salvare()
, disegneremmo su qualsiasi grafica in questo modo - sbiadita o meno.
Ora disegniamo l'immagine in modo che il suo centro sia posizionato sul puntatore del mouse. I primi 5 parametri di drawImage
sarà sempre lo stesso per tutta l'applicazione. Facendo clic, i prossimi due parametri verranno aggiornati per centrarsi sul puntatore del mouse. Gli ultimi due parametri, il larghezza
e altezza
disegnare, non cambierà mai.
Infine chiamiamo il ristabilire()
metodo. Questo significa essenzialmente che stiamo usando il nuovo valore alfa e vogliamo ripristinare tutte le proprietà nel punto in cui si trovavano. Per concludere questa funzione aggiungiamo altri due listener. Uno per quando spostiamo il mouse (trascinando il pezzo del puzzle), e uno per quando lasciamo andare (rilascia il pezzo del puzzle).
checkPieceClicked ()
Funzionefunction checkPieceClicked () var i; pezzo var; per (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 else return piece; restituisce null;
Ora abbiamo bisogno di tornare indietro un po '. Siamo stati in grado di determinare quale pezzo è stato cliccato, ma come lo abbiamo fatto? In realtà è piuttosto semplice. Quello che dobbiamo fare è passare in rassegna tutti i pezzi del puzzle e determinare se il clic fosse all'interno dei limiti di uno qualsiasi dei nostri oggetti. Se ne troviamo uno, restituiamo l'oggetto abbinato e terminiamo la funzione. Se non troviamo nulla, torniamo nullo
.
updatePuzzle ()
Funzionefunction updatePuzzle (e) _currentDropPiece = null; if (e.layerX || e.layerX == 0) _mouse.x = e.layerX - _canvas.offsetLeft; _mouse.y = e.layerY - _canvas.offsetTop; else if (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; pezzo var; per (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 > (piece.yPos + _pieceHeight)) // NOT OVER else _currentDropPiece = piece; _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);
Ora torniamo al trascinamento. Chiamiamo questa funzione quando l'utente muove il mouse. Questa è la più grande funzione dell'applicazione poiché fa diverse cose. Cominciamo. Lo romperò mentre andiamo.
_currentDropPiece = null; if (e.layerX || e.layerX == 0) _mouse.x = e.layerX - _canvas.offsetLeft; _mouse.y = e.layerY - _canvas.offsetTop; else if (e.offsetX || e.offsetX == 0) _mouse.x = e.offsetX - _canvas.offsetLeft; _mouse.y = e.offsetY - _canvas.offsetTop;
Inizia impostando _currentDropPiece
a nullo
. Dobbiamo resettarlo a nullo
in aggiornamento a causa della possibilità che il nostro pezzo sia stato trascinato a casa sua. Non vogliamo il precedente _currentDropPiece
valore in giro. Quindi impostiamo il _topo
oggetto allo stesso modo in cui lo abbiamo fatto al clic.
_stage.clearRect (0,0, _puzzleWidth, _puzzleHeight);
Qui abbiamo bisogno di cancellare tutti i grafici sulla tela. In sostanza, abbiamo bisogno di ridisegnare i pezzi del puzzle perché l'oggetto che viene trascinato sopra avrà effetto sul loro aspetto. Se non lo facessimo, vedremmo dei risultati molto strani seguendo il percorso del nostro pezzo di puzzle trascinato.
var i; pezzo var; per (i = 0; i < _pieces.length;i++)
Inizia impostando il nostro solito ciclo di pezzi.
pezzo = _pieces [i]; if (piece == _currentPiece) continua;
Crea il nostro pezzo
riferimento come al solito. Quindi verifica se il pezzo a cui stiamo facendo riferimento è lo stesso del pezzo che stiamo trascinando. Se è così, continua il ciclo. Ciò manterrà lo spazio di casa del pezzo trascinato vuoto.
_stage.drawImage (_img, piece.sx, piece.sy, _pieceWidth, _pieceHeight, piece.xPos, piece.yPos, _pieceWidth, _pieceHeight); _stage.strokeRect (piece.xPos, piece.yPos, _pieceWidth, _pieceHeight);
Andando avanti, ridisegna il pezzo del puzzle usando le sue proprietà esattamente nello stesso modo in cui lo abbiamo fatto quando le abbiamo disegnate per la prima volta. Dovrai disegnare anche il bordo.
if (_currentDropPiece == null) if (_mouse.x < piece.xPos || _mouse.x > (piece.xPos + _pieceWidth) || _mouse.y < piece.yPos || _mouse.y > (piece.yPos + _pieceHeight)) // NOT OVER else _currentDropPiece = piece; _stage.save (); _stage.globalAlpha = .4; _stage.fillStyle = PUZZLE_HOVER_TINT; _stage.fillRect (_currentDropPiece.xPos, _currentDropPiece.yPos, _pieceWidth, _pieceHeight); _stage.restore ();
Dato che abbiamo un riferimento a ciascun oggetto nel ciclo, possiamo anche usare questa opportunità per verificare se il pezzo trascinato è sopra di esso. Lo facciamo perché vogliamo dare all'utente il feedback su quale pezzo può essere lasciato cadere. Analizziamo ora il codice.
Per prima cosa vogliamo vedere se questo ciclo ha già prodotto un obiettivo di rilascio. Se è così, non dobbiamo preoccuparci poiché solo un obiettivo di rilascio può essere possibile e qualsiasi movimento del mouse specificato. Altrimenti, _currentDropPiece
sarà nullo
e possiamo procedere nella logica. Dato che il nostro mouse si trova nel mezzo del pezzo trascinato, tutto ciò che dobbiamo davvero fare è determinare quale altro pezzo il nostro mouse è finito.
Successivamente, usa il nostro pratico checkPieceClicked ()
funzione per determinare se il mouse passa con il mouse sopra l'oggetto pezzo corrente nel loop. Se è così, impostiamo il _currentDropPiece
variabile e disegna una scatola colorata sopra il pezzo del puzzle, indicando che ora è il bersaglio di caduta.
Ricordati di salvare()
e ristabilire()
. Altrimenti otterresti la scatola colorata e non l'immagine sottostante.
_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);
Ultimo ma non meno importante, dobbiamo ridisegnare il pezzo trascinato. Il codice è lo stesso di quando l'abbiamo fatto clic per primo, ma il mouse si è spostato, quindi la sua posizione verrà aggiornata.
pieceDropped ()
Funzionefunction pieceDropped (e) document.onmousemove = null; document.onmouseup = null; if (_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, il peggio è dietro di noi. Ora stiamo trascinando con successo un pezzo del puzzle e ottenendo anche un riscontro visivo su dove verrà rilasciato. Ora non resta che lasciare il pezzo. Prima rimuoviamo gli ascoltatori poiché nulla viene trascinato.
Quindi, controlla quello _currentDropPiece
non è nullo
. Se lo è, significa che l'abbiamo trascinato nell'area del pezzo e non su un altro slot. Se non lo è nullo
, continuiamo con la funzione.
Quello che facciamo ora è semplicemente scambiare il xPos
e yPos
di ogni pezzo. Facciamo un oggetto temporaneo veloce come un buffer per contenere uno dei valori dell'oggetto nel processo di swapping. A questo punto, i due pezzi sono entrambi nuovi xPos
e yPos
valori, e si inseriranno nelle loro nuove case al sorteggio successivo. Questo è quello che faremo ora, controllando contemporaneamente se il gioco è stato vinto.
resetPuzzleAndCheckWin ()
Funzionefunction resetPuzzleAndCheckWin () _stage.clearRect (0,0, _puzzleWidth, _puzzleHeight); var gameWin = true; var i; pezzo var; per (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);
Ancora una volta, cancella il tela
e impostare a gameWin
variabile, impostandolo su vero
per impostazione predefinita. Ora procedi con il nostro loop di pezzi fin troppo familiari.
Il codice qui dovrebbe sembrare familiare, quindi non lo esamineremo. Rimuove semplicemente i pezzi nelle loro slot originali o nuove. All'interno di questo ciclo, vogliamo vedere se ogni pezzo viene disegnato nella sua posizione vincente. Questo è semplice: controlliamo se il nostro sx
e sy
proprietà corrispondono xPos
e yPos
. Se no, sappiamo che non potremmo vincere il puzzle e il set gameWin
a falso
. Se avessimo fatto il giro con tutti i giocatori nei loro luoghi vincenti, avremmo fatto un rapido tempo scaduto
chiamare il nostro gioco finito()
metodo. (Impostiamo un timeout in modo che lo schermo non cambi in modo così drastico una volta eliminato il pezzo del puzzle.)
gioco finito()
Funzionefunction gameOver () document.onmousedown = null; document.onmousemove = null; document.onmouseup = null; initPuzzle ();
Questa è la nostra ultima funzione! Qui rimuoviamo tutti gli ascoltatori e chiamiamo initPuzzle ()
, che ripristina tutti i valori necessari e attende che l'utente ricominci.
Clicca qui per vedere il risultato finale.
Come puoi vedere, puoi fare molte nuove cose creative in HTML5 usando aree bitmap selezionate di immagini e disegni caricati. Puoi facilmente estendere questa applicazione aggiungendo punteggio e forse anche un timer per dargli più gameplay. Un'altra idea sarebbe quella di aumentare la difficoltà e selezionare un'immagine diversa in gioco finito()
funzione, dando i livelli di gioco.