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.
Voici un aperçu du puzzle que nous allons construire:
Quelques notes:
Toile
élément.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
. 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.
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!
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.
init ()
Une fonctionfonction 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.
onImage ()
Une fonctionfonction 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 ()
.
setCanvas ()
Une fonctionfonction 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.
initPuzzle ()
Une fonctionfonction 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.
createTitle ()
Une fonctionfunction 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.
buildPieces ()
Une fonctionfonction 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.
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.
shufflePuzzle ()
Une fonctionfunction 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..
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.
onPuzzleClick ()
Une fonctionfonction 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).
checkPieceClicked ()
Une fonctionfonction 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
.
updatePuzzle ()
Une fonctionfunction 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.
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.
_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..
pieceDropped ()
Une fonctionfonction 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é..
resetPuzzleAndCheckWin ()
Une fonctionfonction 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.)
jeu terminé()
Une fonctionfonction 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.
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.