Créer un puzzle HTML5 pour permutation de mosaïque

Dans ce didacticiel, nous allons utiliser le canevas HTML5 et le langage Javascript pour créer un jeu dynamique de permutation de pavés. Le résultat sera un casse-tête qui fonctionne avec n’importe quelle image, avec des niveaux de difficulté flexibles et faciles à régler.


Le puzzle complet sur toile HTML5

Voici un aperçu du puzzle que nous allons construire:


Cliquez pour jouer

Quelques notes:

  • Compatibilité multi-navigateurs: Ce puzzle a été testé et fonctionne dans toutes les versions de Safari, Firefox et Chrome qui prennent en charge la Toile élément.
  • Mobile: Le code fourni ici fonctionne dans le navigateur de bureau susmentionné et n'est pas optimisé pour les mobiles. Le puzzle se chargera et rendra très bien, mais en raison des comportements de toucher et de glisser dans les navigateurs mobiles, une optimisation est nécessaire pour qu'il fonctionne correctement. L’optimisation de ce puzzle pour mobile sera traitée dans un prochain tutoriel.
  • Niveau de difficulté ajustable: Le code contient une constante, PUZZLE_DIFFICULTY, qui détermine le nombre de pièces. Dans la démo ci-dessus, ceci est réglé sur 4, donnant un puzzle 4x4. Nous pouvons facilement changer cela - par exemple, cette version a une PUZZLE_DIFFICULTY de dix.

Commencer

Pour commencer, créez un répertoire pour le projet. Placez une image dans le répertoire que vous souhaitez utiliser comme puzzle. N'importe quelle image adaptée au Web fera l'affaire, et elle peut avoir la taille souhaitée par votre cœur - assurez-vous qu'elle s'adapte parfaitement au pli de la fenêtre de votre navigateur.


Étape 1: Création du modèle HTML

Ouvrez un nouveau fichier en utilisant votre éditeur de texte favori et enregistrez-le dans le répertoire de votre projet, à côté de votre image. Ensuite, remplissez cette base HTML modèle.

    Puzzle HTML5      

Tout ce que nous devons faire ici est de créer un standard HTML5 modèle contenant un Toile tag avec le identifiant de "toile". Nous écrirons un en charge auditeur dans le corps tag qui appellera notre init () fonctionner lors de la mise à feu.

Maintenant, commencez par placer votre curseur dans le scénario étiquette. A partir de là c'est tout javascript. À l'exception des variables initiales, je vais organiser les sections par fonction. Tout d'abord vous montrer le code et ensuite expliquer la logique.

Prêt? Allons droit au but!


Étape 2: Configuration de nos variables

Mettons en place nos variables et examinons chacune d'elles.

 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;

Nous avons d’abord deux constantes: PUZZLE_DIFFICULTY et PUZZLE_HOVER_TINT. le PUZZLE_DIFFICULTY Constante détient le nombre de pièces dans notre puzzle. Dans cette application, les lignes et les colonnes correspondent toujours, donc en définissant PUZZLE_DIFFICULTY à 4, nous avons 16 pièces de puzzle au total. Augmenter cela augmente la difficulté du puzzle.

Suivant est une série de variables:

  • _Toile et _étape tiendra une référence à la toile et à son contexte de dessin, respectivement. Nous faisons cela pour ne pas avoir à écrire toute la requête à chaque fois que nous les utilisons. Et nous les utiliserons beaucoup!
  • _img sera une référence à l'image chargée, que nous allons copier des pixels tout au long de l'application.
  • _puzzleWidth, _puzzleHeight, _pieceWidth, et _pieceHeight sera utilisé pour stocker les dimensions du puzzle entier et de chaque pièce du puzzle. Nous les configurons une fois pour éviter de les calculer encore et encore chaque fois que nous en avons besoin.
  • _currentPiece contient une référence à la pièce en train d'être traînée.
  • _currentDropPiece contient une référence à la pièce actuellement en position à déposer. (Dans la démo, cette pièce est surlignée en vert.)
  • _Souris est une référence qui tiendra le courant de la souris X et y position. Ceci est mis à jour lorsque le puzzle est cliqué pour déterminer quelle pièce est touchée, et quand une pièce est traînée pour déterminer quelle pièce est survolée.

Passons maintenant à nos fonctions.


Étape 3: le init () Une fonction

 fonction init () _img = new Image (); _img.addEventListener ('load', onImage, false); _img.src = "mke.jpg"; 

La première chose que nous souhaitons faire dans notre application est de charger l'image du puzzle. L’objet image est d’abord instancié et mis à notre _img variable. Ensuite, nous écoutons pour le charge événement qui va alors tirer notre onImage () fonctionne lorsque le chargement de l'image est terminé. Enfin, nous définissons la source de l'image, ce qui déclenche le chargement.


Étape 4: le onImage () Une fonction

 fonction 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 (); 

Maintenant que l'image est chargée avec succès, nous pouvons définir la majorité des variables déclarées précédemment. Nous faisons cela ici parce que nous avons maintenant des informations sur l'image et pouvons définir nos valeurs de manière appropriée..

La première chose à faire est de calculer la taille de chaque pièce du puzzle. Nous faisons cela en divisant le PUZZLE_DIFFICULTY valeur par la largeur et la hauteur de l'image chargée. Nous éliminons également le gras des bords pour nous donner quelques chiffres pairs et travailler avec nous et nous assurons que chaque pièce peut échanger les "slots" de manière appropriée avec d'autres.

Nous utilisons ensuite nos nouvelles valeurs de pièce de puzzle pour déterminer la taille totale du puzzle et définir ces valeurs sur _puzzleWidth et _puzzleHeight.

Enfin, nous appelons quelques fonctions - setCanvas () et initPuzzle ().


Étape 5: le setCanvas () Une fonction

 fonction setCanvas () _canvas = document.getElementById ('canvas'); _stage = _canvas.getContext ('2d'); _canvas.width = _puzzleWidth; _canvas.height = _puzzleHeight; _canvas.style.border = "1px noir uni"; 

Maintenant que nos valeurs de casse-tête sont complètes, nous voulons configurer notre Toile élément. D'abord nous définissons notre _Toile variable pour référencer notre Toile élément, et _étape référencer son le contexte.

Maintenant nous mettons le largeur et la taille de nôtre Toile pour correspondre à la taille de notre image recadrée, suivie de l'application de styles simples pour créer une bordure noire autour de notre Toile pour afficher les limites de notre puzzle.


Étape 6: le initPuzzle () Une fonction

 fonction initPuzzle () _pieces = []; _mouse = x: 0, y: 0; _currentPiece = null; _currentDropPiece = null; _stage.drawImage (_img, 0, 0, _puzzleWidth, _puzzleHeight, 0, 0, _puzzleWidth, _puzzleHeight); createTitle ("Cliquez pour démarrer le puzzle"); buildPieces (); 

Ici nous initialisons le puzzle. Nous avons configuré cette fonction de manière à pouvoir la rappeler ultérieurement lorsque nous voulons rejouer le puzzle. Tout ce qui devait être réglé avant de jouer ne l’aura pas à nouveau..

D'abord nous avons mis _pièces comme vide tableau et créer le _Souris objet, qui tiendra notre position de la souris tout au long de l'application. Ensuite, nous définissons le _currentPiece et _currentPieceDrop à nul. (Lors de la première lecture, ces valeurs seraient déjà nul, mais nous voulons nous assurer qu’ils sont réinitialisés lors de la relecture du puzzle.)

Enfin, il est temps de dessiner! Nous dessinons d’abord l’ensemble de l’image pour montrer au joueur ce qu’il va créer. Après cela, nous créons des instructions simples en appelant notre createTitle () une fonction.


Étape 7: le createTitle () Une fonction

 function 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); 

Ici, nous créons un message assez simple qui demande à l'utilisateur de cliquer sur le puzzle pour commencer.
Notre message sera un rectangle semi-transparent qui servira d'arrière-plan à notre texte. Cela permet à l'utilisateur de voir l'image derrière l'image et assure également que notre texte en blanc sera lisible sur n'importe quelle image.

Nous avons simplement mis fillStyle au noir et globalAlpha à .4, avant de remplir un court rectangle noir au bas de l'image.

Puisque globalAlpha affecte la toile entière, nous devons le remettre à 1 (opaque) avant de dessiner le texte. Pour définir notre titre, nous avons défini le textAlign pour «centrer» et le textBaseline à 'milieu'. Nous pouvons également appliquer certains Police de caractère Propriétés.

Pour dessiner le texte, nous utilisons le fillText () méthode. Nous passons dans le msg variable et placez-le au centre horizontal de la Toile, et le centre vertical du rectangle.


Étape 8: le buildPieces () Une fonction

 fonction buildPieces () var i; var pièce; var xPos = 0; var yPos = 0; pour (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; 

Enfin, il est temps de construire le puzzle!

Nous faisons cela en construisant un objet pour chaque pièce. Ces objets ne seront pas tenus de restituer sur la toile, mais simplement de contenir des références sur ce qu’il faut dessiner et où. Cela étant dit, allons-y.

Tout d'abord, déclarons quelques variables que nous allons réutiliser dans la boucle. Nous voulons mettre en place la boucle pour parcourir le nombre de pièces du puzzle dont nous avons besoin. On obtient cette valeur en multipliant PUZZLE_DIFFICULTY par lui-même - alors dans ce cas, nous obtenons 16.

Dans la boucle:

 pour (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; 

Commencez par créer un vide pièce objet. Ajouter ensuite le sx et sy propriétés à l'objet. Dans la première itération, ces valeurs sont 0 et représente le point de notre image d'où nous allons commencer à tirer. Maintenant, poussez-le vers le _pièces[] tableau. Cet objet contiendra également les propriétés xPos et yPos, qui nous dira la position actuelle dans le puzzle où la pièce doit être dessinée. Nous allons mélanger les objets avant qu'il ne soit jouable afin que ces valeurs n'aient pas encore besoin d'être définies.

La dernière chose que nous faisons dans chaque boucle est d'augmenter la variable locale xPos par _pieceWidth. Avant de continuer la boucle, nous déterminons s’il faut passer à la rangée suivante en vérifiant si xPos est au-delà de la largeur du puzzle. Si oui, nous réinitialisons xPos retour à 0 et augmenter yPos par _pieceHeight.

Maintenant, nous avons tous nos pièces de puzzle bien rangées dans notre _pièces tableau. À ce stade, le code cesse finalement de s'exécuter et attend que l'utilisateur interagisse. Nous plaçons un écouteur de clic sur le document tirer le shufflePuzzle () fonction une fois déclenchée, qui commencera le jeu.


Étape 9: le shufflePuzzle () Une fonction

 function shufflePuzzle () _pieces = shuffleArray (_pieces); _stage.clearRect (0,0, _puzzleWidth, _puzzleHeight); var i; var pièce; var xPos = 0; var yPos = 0; pour (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) pour (var j, x, i = longueur.i; j = parseInt (Math.random () * i), x = o [- i], o [i] = o [ j], o [j] = x); renvoyer o; 

Tout d’abord: mélangez les _pièces[] tableau. J'utilise une fonction utilitaire intéressante qui va mélanger les index du tableau qui y est passé. L'explication de cette fonction est au-delà du sujet de ce tutoriel, nous allons donc avancer, sachant que nous avons réussi à brouiller nos morceaux. (Pour une introduction de base à la lecture aléatoire, jetez un coup d'œil à ce tutoriel.)

Commençons par effacer tous les graphiques dessinés à la Toile faire place à dessiner nos pièces. Ensuite, configurez le tableau de la même manière que lors de la création de nos objets pièce..

Dans la boucle:

 pour (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; 

Tout d’abord, utilisez le je variable pour définir notre référence à l'objet pièce actuel dans la boucle. Maintenant, nous peuplons le xPos et yPos propriétés que j'ai mentionnées plus tôt, qui seront 0 dans notre première itération.

Nous dessinons enfin nos pièces.

Le premier paramètre de drawImage () assigne la source de l'image à partir de laquelle nous voulons tirer. Ensuite, utilisez les objets de la pièce sx et sy propriétés, avec _pieceWidth et _pieceHeight, peupler les paramètres qui déclarent la zone de l'image dans laquelle dessiner. Les quatre derniers paramètres définissent la zone de Toile où nous voulons dessiner. Nous utilisons le xPos et yPos valeurs que nous construisons à la fois dans la boucle et que nous assignons à l'objet.

Immédiatement après cela, nous dessinons un trait rapide autour de la pièce pour lui donner une bordure, ce qui la séparera joliment des autres pièces..

Nous attendons maintenant que l’utilisateur saisisse un morceau en définissant un autre Cliquez sur auditeur. Cette fois, il va tirer un onPuzzleClick () une fonction.


Étape 10: le onPuzzleClick () Une fonction

 fonction 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 = 0,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; 

Nous savons que le puzzle a été cliqué; Maintenant, nous devons déterminer quelle pièce a été cliquée. Cette conditionnelle simple nous permettra d’obtenir notre position de souris sur tous les navigateurs de bureau modernes qui prennent en charge Toile, en utilisant soit e.layerX et e.layerY ou e.offsetX et e.offsetY. Utilisez ces valeurs pour mettre à jour notre _Souris objet en lui assignant un X et un y propriété pour maintenir la position actuelle de la souris - dans ce cas, la position où elle a été cliquée.

A la ligne 112, nous définissons immédiatement _currentPiece à la valeur renvoyée de notre checkPieceClicked () une fonction. Nous séparons ce code car nous souhaitons l’utiliser plus tard en faisant glisser la pièce du puzzle. Je vais expliquer cette fonction dans la prochaine étape.

Si la valeur renvoyée était nul, nous ne faisons simplement rien, car cela implique que l'utilisateur n'a pas réellement cliqué sur une pièce du puzzle. Toutefois, si nous récupérons une pièce de puzzle, nous souhaitons la fixer à la souris et la disparaître un peu pour révéler les pièces situées en dessous. Alors, comment faisons-nous cela?

D'abord nous effacer le Toile zone où la pièce s'est assise avant que nous avons cliqué dessus. Nous utilisons clearRect () encore une fois, mais dans ce cas, nous passons dans la zone obtenue à partir du _currentPiece objet. Avant de le redessiner, nous voulons enregistrer() le contexte de la toile avant de continuer. Cela garantira que tout ce que nous tirons après avoir économisé ne se contentera pas de dessiner sur quoi que ce soit de sa manière. Nous faisons cela parce que nous allons légèrement effacer le morceau traîné et vouloir voir les morceaux en dessous. Si on n'a pas appelé enregistrer(), nous venons de dessiner sur des graphiques de la manière - fanée ou non.

Nous dessinons maintenant l'image de sorte que son centre soit positionné au pointeur de la souris. Les 5 premiers paramètres de drawImage sera toujours le même tout au long de l'application. En cliquant, les deux paramètres suivants seront mis à jour pour se centrer sur le pointeur de la souris. Les deux derniers paramètres, le largeur et la taille dessiner, ne changera jamais.

Enfin nous appelons le restaurer() méthode. Cela signifie essentiellement que nous en avons terminé avec la nouvelle valeur alpha et que nous souhaitons restaurer toutes les propriétés où elles étaient. Pour conclure cette fonction, nous ajoutons deux auditeurs supplémentaires. Un pour quand on déplace la souris (en faisant glisser la pièce du puzzle), et un pour quand on lâche (déposer la pièce du puzzle).


Étape 11: le checkPieceClicked () Une fonction

 fonction checkPieceClicked () var i; var pièce; pour (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;  return null; 

Nous devons maintenant revenir un peu en arrière. Nous avons pu déterminer quelle pièce était cliquée, mais comment l'avons-nous fait? C'est assez simple en fait. Ce que nous devons faire, c'est parcourir toutes les pièces du puzzle et déterminer si le clic est dans les limites de l'un de nos objets. Si nous en trouvons un, nous retournons l'objet correspondant et mettons fin à la fonction. Si nous ne trouvons rien, nous revenons nul.


Étape 12: le updatePuzzle () Une fonction

 function 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; var pièce; pour (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); 

Revenons maintenant à la traînée. Nous appelons cette fonction lorsque l'utilisateur déplace la souris. C’est la fonction la plus importante de l’application car elle fait plusieurs choses. Commençons. Je vais décomposer comme nous allons.

 _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; 

Commencez par mettre _currentDropPiece à nul. Nous devons réinitialiser ceci à nul mise à jour en raison de la chance que notre pièce a été traînée à sa maison. Nous ne voulons pas le précédent _currentDropPiece valeur traîner. Ensuite, nous définissons le _Souris objecter de la même manière que nous avons fait sur clic.

 _stage.clearRect (0,0, _puzzleWidth, _puzzleHeight);

Ici, nous devons effacer tous les graphiques sur la toile. Nous avons essentiellement besoin de redessiner les pièces du puzzle car l’objet glissé dessus affectera leur apparence. Si nous ne le faisions pas, nous constaterions des résultats très étranges sur le tracé de notre pièce de puzzle traînée..

 var i; var pièce; pour (i = 0; i < _pieces.length;i++)

Commencez par configurer notre boucle de pièces habituelle.

Dans la boucle:

 morceau = _pieces [i]; if (morceau == _currentPiece) continue; 

Créer notre pièce référence comme d'habitude. Vérifiez ensuite si la pièce à laquelle vous faites référence est identique à celle que nous faisons glisser. Si oui, continuez la boucle. Cela gardera l'emplacement d'origine de la pièce glissée vide.

 _stage.drawImage (_img, piece.sx, piece.sy, _pieceWidth, _pieceHeight, piece.xPos, piece.yPos, _pieceWidth, _pieceHeight); _stage.strokeRect (piece.xPos, piece.yPos, _pieceWidth, _pieceHeight);

Pour continuer, redessine le puzzle en utilisant ses propriétés exactement de la même manière que lorsque nous les avions dessinées pour la première fois. Vous aurez besoin de dessiner la frontière aussi.

 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 (); 

Comme nous avons une référence à chaque objet de la boucle, nous pouvons également utiliser cette opportunité pour vérifier si la pièce glissée est dessus. Nous faisons cela parce que nous souhaitons donner à l’utilisateur un retour d’information sur la pièce sur laquelle il peut être déposé. Fouillons dans ce code maintenant.

Premièrement, nous voulons voir si cette boucle a déjà produit une cible de dépôt. Si tel est le cas, nous n’avons pas besoin de nous embêter, puisqu’une seule cible de largage est possible et que la souris se déplace. Si non, _currentDropPiece sera nul et nous pouvons procéder dans la logique. Puisque notre souris est au milieu de la pièce glissée, tout ce que nous avons à faire est de déterminer de quelle autre pièce notre souris se trouve.

Ensuite, utilisez notre pratique checkPieceClicked () fonction pour déterminer si la souris survole l’objet pièce actuel dans la boucle. Si oui, nous définissons la _currentDropPiece variable et dessinez une boîte teintée sur la pièce du puzzle, indiquant que c'est maintenant la cible de chute.

Se souvenir de enregistrer() et restaurer(). Sinon, vous obtiendrez la boîte teintée et non l'image en dessous.

Hors de la boucle:

 _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);

Enfin et surtout, nous devons redessiner la pièce glissée. Le code est le même que lorsque nous avons cliqué pour la première fois, mais la souris a bougé et sa position sera mise à jour..


Étape 13: le pieceDropped () Une fonction

 fonction 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, le pire est derrière nous. Nous réussissons maintenant à faire glisser un morceau de puzzle et même à obtenir un retour visuel sur l'endroit où il sera déposé. Maintenant, il ne reste plus qu'à laisser tomber la pièce. Commençons par retirer immédiatement les auditeurs car rien n'est traîné.

Ensuite, vérifiez que _currentDropPiece n'est pas nul. Si c'est le cas, cela signifie que nous l'avons redirigé vers la zone d'origine de la pièce et non vers un autre emplacement. Si ce n'est pas nul, on continue avec la fonction.

Ce que nous faisons maintenant, c’est simplement échanger la xPos et yPos de chaque pièce. Nous créons un objet temp rapide sous forme de tampon pour contenir l'une des valeurs de l'objet dans le processus de permutation. À ce stade, les deux pièces ont toutes deux une nouvelle xPos et yPos valeurs, et vont se glisser dans leurs nouvelles maisons sur le prochain tirage au sort. C'est ce que nous allons faire maintenant, en vérifiant simultanément si le jeu a été gagné..


Étape 14: le resetPuzzleAndCheckWin () Une fonction

 fonction resetPuzzleAndCheckWin () _stage.clearRect (0,0, _puzzleWidth, _puzzleHeight); var gameWin = true; var i; var pièce; pour (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);  

Encore une fois, effacez la Toile et mettre en place un gameWin variable, le mettre à vrai par défaut. Continuez maintenant avec notre boucle de pièces trop familière.

Le code ici devrait avoir l'air familier pour que nous ne l'examinions pas. Il ramène simplement les pièces dans leurs fentes originales ou nouvelles. Dans cette boucle, nous voulons voir si chaque pièce est dessinée dans sa position gagnante. C’est simple: nous vérifions si notre sx et sy propriétés correspondent avec xPos et yPos. Sinon, nous savons que nous ne pourrions peut-être pas gagner le puzzle et régler gameWin à faux. Si nous avons réussi à traverser la boucle avec tout le monde dans leurs places gagnantes, nous avons mis en place une rapide temps libre appeler notre jeu terminé() méthode. (Nous avons défini un délai d'attente afin que l'écran ne change pas de façon aussi radicale lorsque vous déposez la pièce du puzzle.)


Étape 15: le jeu terminé() Une fonction

 fonction gameOver () document.onmousedown = null; document.onmousemove = null; document.onmouseup = null; initPuzzle (); 

Ceci est notre dernière fonction! Ici, nous supprimons tous les écouteurs et appelons initPuzzle (), qui réinitialise toutes les valeurs nécessaires et attend que l'utilisateur rejoue.


Conclusion

Cliquez ici pour voir le résultat final.

Comme vous pouvez le constater, vous pouvez créer de nombreuses créations en HTML5 à l'aide de zones bitmap sélectionnées d'images et de dessins chargés. Vous pouvez facilement étendre cette application en ajoutant un score et peut-être même une minuterie pour lui donner plus de gameplay. Une autre idée serait d’augmenter la difficulté et de sélectionner une image différente dans jeu terminé() fonction, donnant les niveaux de jeu.