En este tutorial, trabajaremos con el lienzo HTML5 y Javascript para crear un juego dinámico de intercambio de fichas. El resultado será un rompecabezas que funciona con cualquier imagen dada y tiene niveles de dificultad flexibles que se ajustan fácilmente.
Aquí está un tiro rápido del rompecabezas que estaremos construyendo:
Un par de notas:
lona
elemento.PUZZLE_DIFICULTAD
, Eso determina el número de piezas. En la demostración anterior, esto se establece en 4
, Dando un puzzle 4x4. Podemos cambiar esto fácilmente, por ejemplo, esta versión tiene una PUZZLE_DIFICULTAD
de 10
. Para empezar, crea un directorio para el proyecto. Coloque una imagen en el directorio que desea utilizar como su rompecabezas. Cualquier imagen compatible con la web servirá, y puede ser de cualquier tamaño que su corazón desee, solo asegúrese de que se ajuste al pliegue de la ventana de su navegador..
Abra un nuevo archivo con su editor de texto favorito y guárdelo en el directorio de su proyecto, al lado de su imagen. A continuación, rellene este básico HTML
modelo.
Puzzle HTML5
Todo lo que necesitamos hacer aquí es crear un estándar. HTML5
plantilla que contiene uno lona
etiqueta con el carné de identidad
de “lienzo”. Escribiremos un onload
oyente en el cuerpo
etiqueta que llamará nuestra en eso()
funciona cuando se dispara.
Ahora comienza colocando el cursor dentro de la guión
etiqueta. De aquí en adelante es todo javascript. Con la excepción de las variables iniciales, organizaré las secciones por función. Primero mostrándote el código y luego explicando la lógica.
Listo? Vamos a hacerlo bien!
Configuremos nuestras variables y echemos un vistazo a cada una..
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;
Primero tenemos un par de constantes: PUZZLE_DIFICULTAD
y PUZZLE_HOVER_TINT
. los PUZZLE_DIFICULTAD
constante mantiene el número de piezas en nuestro rompecabezas. En esta aplicación, las filas y columnas siempre coinciden, por lo que al configurar PUZZLE_DIFICULTAD
a 4
, Conseguimos 16 piezas de rompecabezas en total. Aumentar esto aumenta la dificultad del rompecabezas..
A continuación hay una serie de variables:
_lona
y _escenario
mantendrá una referencia al lienzo y a su contexto de dibujo, respectivamente. Hacemos esto para no tener que escribir la consulta completa cada vez que los usamos. Y los estaremos usando mucho.!_img
será una referencia a la imagen cargada, de la que copiaremos píxeles en toda la aplicación._puzzleWidth
, _puzzleHeight
, _pieceWidth
, y _pieceHeight
se utilizará para almacenar las dimensiones de todo el rompecabezas y cada pieza individual del rompecabezas. Los configuramos una vez para evitar que se calculen una y otra vez cada vez que los necesitemos.._currentPiece
Mantiene una referencia a la pieza que actualmente está siendo arrastrada.._currentDropPiece
contiene una referencia a la pieza actualmente en posición para ser colocada. (En la demo, esta pieza está resaltada en verde)._ratón
Es una referencia que mantendrá la corriente del ratón. X
y y
posición. Esto se actualiza cuando se hace clic en el rompecabezas para determinar qué pieza se toca, y cuando se arrastra una pieza para determinar en qué pieza se está moviendo..Ahora, a nuestras funciones..
en eso()
Funciónfunction init () _img = new Image (); _img.addEventListener ('load', onImage, false); _img.src = "mke.jpg";
Lo primero que queremos hacer en nuestra aplicación es cargar la imagen para el rompecabezas. El objeto de imagen se crea una primera instancia y se establece en nuestro _img
variable. A continuación, escuchamos la carga
evento que luego disparará nuestra onImage ()
Funciona cuando la imagen ha terminado de cargarse. Por último, establecemos la fuente de la imagen, que activa la carga..
onImage ()
Funciónfunction 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 ();
Ahora que la imagen se ha cargado correctamente, podemos establecer la mayoría de las variables declaradas anteriormente. Hacemos esto aquí porque ahora tenemos información sobre la imagen y podemos establecer nuestros valores de manera apropiada.
Lo primero que hacemos es calcular el tamaño de cada pieza del rompecabezas. Hacemos esto dividiendo el PUZZLE_DIFICULTAD
Valor por el ancho y alto de la imagen cargada. También recortamos la grasa de los bordes para darnos algunos números pares para trabajar y asegurarnos de que cada pieza pueda intercambiar apropiadamente las "ranuras" con otras.
A continuación, utilizamos nuestros nuevos valores de piezas de rompecabezas para determinar el tamaño total del rompecabezas y establecer estos valores en _puzzleWidth
y _puzzleHeight
.
Por último, cancelamos algunas funciones. - setCanvas ()
y initPuzzle ()
.
setCanvas ()
Funciónfunción setCanvas () _canvas = document.getElementById ('lienzo'); _stage = _canvas.getContext ('2d'); _canvas.width = _puzzleWidth; _canvas.height = _puzzleHeight; _canvas.style.border = "1px negro sólido";
Ahora que nuestros valores de rompecabezas están completos, queremos configurar nuestro lona
elemento. Primero ponemos nuestro _lona
variable para hacer referencia a nuestra lona
elemento, y _escenario
para hacer referencia a su contexto
.
Ahora configuramos el anchura
y altura
de nuestro lona
para coincidir con el tamaño de nuestra imagen recortada, seguido de la aplicación de algunos estilos simples para crear un borde negro alrededor de nuestra lona
para mostrar los límites de nuestro rompecabezas.
initPuzzle ()
Funciónfunction initPuzzle () _pieces = []; _mouse = x: 0, y: 0; _currentPiece = null; _currentDropPiece = null; _stage.drawImage (_img, 0, 0, _puzzleWidth, _puzzleHeight, 0, 0, _puzzleWidth, _puzzleHeight); createTitle ("Click to Start Puzzle"); buildPieces ();
Aquí inicializamos el puzzle. Configuramos esta función de tal manera que podamos volver a llamarla más tarde cuando deseamos volver a jugar el rompecabezas. Cualquier otra cosa que haya que configurar antes de jugar no tendrá que volver a configurarse.
Primero nos ponemos _piezas
como un vacío formación
y crea el _ratón
Objeto, que mantendrá la posición de nuestro ratón en toda la aplicación. A continuación ponemos la _currentPiece
y _currentPieceDrop
a nulo
. (En la primera jugada estos valores ya estarían nulo
, pero queremos asegurarnos de que se reinicien al volver a jugar el rompecabezas.)
Finalmente, es hora de dibujar! Primero dibujamos la imagen completa para mostrar al jugador lo que van a crear. Después de eso creamos algunas instrucciones simples llamando a nuestro createTitle ()
función.
createTitle ()
Funciónfunction 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);
Aquí creamos un mensaje bastante simple que indica al usuario que haga clic en el rompecabezas para comenzar.
Nuestro mensaje será un rectángulo semitransparente que servirá como fondo de nuestro texto. Esto permite al usuario ver la imagen detrás de ella y también asegura que nuestro texto en blanco será legible en cualquier imagen
Simplemente establecemos estilo de relleno
a negro y globalAlpha
a .4
, antes de rellenar un rectángulo negro corto en la parte inferior de la imagen.
Ya que globalAlpha
afecta a todo el lienzo, tenemos que volver a ponerlo en 1
(opaco) antes de dibujar el texto. Para configurar nuestro título, configuramos el texto alineado
al 'centro' y al textBaseline
a 'medio'
. También podemos aplicar algunos fuente
propiedades.
Para dibujar el texto, usamos el fillText ()
método. Pasamos en el msg
variable y colóquelo en el centro horizontal de la lona
, y el centro vertical del rectángulo.
buildPieces ()
Funciónfunction buildPieces () var i; pieza de var var xPos = 0; var yPos = 0; para (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 es hora de construir el puzzle.!
Hacemos esto construyendo un objeto
para cada pieza. Estos objetos no serán responsables de la representación en el lienzo, sino de mantener referencias sobre qué dibujar y dónde. Dicho esto, vamos a ello.
En primer lugar, declaremos algunas variables que reutilizaremos a través del bucle. Queremos configurar el bucle para recorrer el número de piezas de rompecabezas que necesitamos. Obtenemos este valor multiplicando PUZZLE_DIFICULTAD
por sí mismo - por lo que en este caso obtenemos 16.
para (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;
Comience creando un vacío trozo
objeto. A continuación agregue el sx
y sy
Propiedades al objeto. En la primera iteración, estos valores son 0
y representar el punto en nuestra imagen de donde comenzaremos a dibujar. Ahora empújalo a la _piezas[]
formación. Este objeto también contendrá las propiedades. xPos
y yPos
, lo que nos dirá la posición actual en el rompecabezas donde se debe dibujar la pieza. Vamos a barajar los objetos antes de poder reproducirlos, por lo que no es necesario configurar estos valores todavía..
Lo último que hacemos en cada bucle es aumentar la variable local. xPos
por _pieceWidth
. Antes de continuar con el ciclo, determinamos si necesitamos pasar a la siguiente fila de piezas al verificar si xPos
está más allá del ancho del rompecabezas. Si es así, restablecemos xPos
volver a 0 y aumentar yPos
por _pieceHeight
.
Ahora tenemos nuestras piezas de rompecabezas almacenadas muy bien en nuestro _piezas
formación. En este punto, el código finalmente deja de ejecutarse y espera a que el usuario interactúe. Configuramos un oyente de clic en el documento
para disparar el shufflePuzzle ()
Funciona cuando se activa, lo que comenzará el juego..
shufflePuzzle ()
Funciónfunction shufflePuzzle () _pieces = shuffleArray (_pieces); _stage.clearRect (0,0, _puzzleWidth, _puzzleHeight); var i; pieza de var var xPos = 0; var yPos = 0; para (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); retorno o;
Lo primero es lo primero: baraja la _piezas[]
formación. Estoy usando una buena función de utilidad aquí que mezclará los índices de la matriz que se le pasa. La explicación de esta función está más allá del tema de este tutorial, así que seguiremos adelante, sabiendo que hemos barajado con éxito nuestras piezas. (Para obtener una introducción básica a la reproducción aleatoria, eche un vistazo a este tutorial).
Primero aclaremos todos los gráficos dibujados a la lona
Para dar paso al dibujo de nuestras piezas. A continuación, configure la matriz de manera similar a como lo hicimos al crear nuestros objetos de pieza por primera vez.
para (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;
En primer lugar, use el yo
Variable para configurar nuestra referencia al objeto pieza actual en el bucle. Ahora poblamos el xPos
y yPos
propiedades que mencioné anteriormente, que serán 0
en nuestra primera iteración.
Ahora, por fin, dibujamos nuestras piezas..
El primer parámetro de drawImage ()
Asigna la fuente de la imagen de la que queremos dibujar. Luego usa los objetos de la pieza. sx
y sy
propiedades, junto con _pieceWidth
y _pieceHeight
, para rellenar los parámetros que declaran el área de la imagen en la que se dibuja. Los últimos cuatro parámetros establecen el área del lona
donde queremos dibujar. Usamos el xPos
y yPos
Valores que ambos estamos construyendo en el bucle y asignando al objeto..
Inmediatamente después de esto, hacemos un trazo rápido alrededor de la pieza para darle un borde, que la separará muy bien de las otras piezas..
Ahora esperamos que el usuario agarre una pieza configurando otra hacer clic
oyente. Esta vez disparará un onPuzzleClick ()
función.
onPuzzleClick ()
Funciónfuncion 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;
Sabemos que se hizo clic en el rompecabezas; Ahora necesitamos determinar en qué pieza se hizo clic. Este condicional simple nos dará la posición de nuestro mouse en todos los navegadores de escritorio modernos que admiten lona
, usando cualquiera e.layerX
y e.layerY
o e.offsetX
y e.offsetY
. Utilice estos valores para actualizar nuestros _ratón
objeto asignándole una X
y un y
propiedad para mantener la posición actual del mouse - en este caso, la posición donde se hizo clic.
En la línea 112 nos ponemos inmediatamente _currentPiece
al valor devuelto de nuestro checkPieceClicked ()
función. Separamos este código porque queremos usarlo más adelante al arrastrar la pieza del rompecabezas. Explicaré esta función en el siguiente paso..
Si el valor devuelto era nulo
, simplemente no hacemos nada, ya que esto implica que el usuario no hizo clic en una pieza del rompecabezas. Sin embargo, si recuperamos una pieza del rompecabezas, queremos unirla al mouse y desvanecerla un poco para revelar las piezas que se encuentran debajo. Entonces como hacemos esto?
Primero limpiamos el lona
Área donde se sentó la pieza antes de hacer clic. Usamos clearRect ()
Una vez más, pero en este caso pasamos solo en el área obtenida de la _currentPiece
objeto. Antes de redibujarlo, queremos salvar()
El contexto del lienzo antes de proceder. Esto asegurará que cualquier cosa que dibujemos después de guardar no se limitará a dibujar nada en su camino. Hacemos esto porque estaremos desvaneciendo un poco la pieza arrastrada y queremos ver las piezas debajo de ella. Si no llamáramos salvar()
, Acabábamos de dibujar sobre cualquier gráfico en el camino, descolorido o no.
Ahora dibujamos la imagen para que su centro quede posicionado en el puntero del mouse. Los primeros 5 parámetros de dibujar imagen
Siempre será el mismo en toda la aplicación. Al hacer clic, los dos parámetros siguientes se actualizarán para centrarse en el puntero del mouse. Los dos últimos parámetros, el anchura
y altura
dibujar, tampoco cambiará nunca..
Por último llamamos al restaurar()
método. Básicamente, esto significa que hemos terminado de usar el nuevo valor alfa y queremos restaurar todas las propiedades a donde estaban. Para concluir esta función añadimos dos oyentes más. Una para cuando movemos el mouse (arrastrando la pieza del rompecabezas) y otra para cuando soltamos (soltamos la pieza del rompecabezas).
checkPieceClicked ()
Funciónfunción checkPieceClicked () var i; pieza de var para (i = 0; i < _pieces.length;i++) piece = _pieces[i]; if(_mouse.x < piece.xPos || _mouse.x > (piece.xPos + _pieceWidth) || _pardusco < piece.yPos || _mouse.y > (piece.yPos + _pieceHeight)) // PIECE NOT HIT else return piece; devolver nulo;
Ahora tenemos que retroceder un poco. Pudimos determinar en qué pieza se hizo clic, pero ¿cómo lo hicimos? Es bastante simple en realidad. Lo que debemos hacer es recorrer todas las piezas del rompecabezas y determinar si el clic estuvo dentro de los límites de cualquiera de nuestros objetos. Si encontramos uno, devolvemos el objeto coincidente y finalizamos la función. Si no encontramos nada, volvemos. nulo
.
updatePuzzle ()
Funciónfunction 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; pieza de var para (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) || _pardusco < 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);
Ahora volvemos al arrastre. Llamamos a esta función cuando el usuario mueve el mouse. Esta es la función más importante de la aplicación, ya que está haciendo varias cosas. Vamos a empezar. Lo desglosaré a medida que avanzamos.
_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;
Empezar por la configuración _currentDropPiece
a nulo
. Necesitamos restablecer esto de nuevo a nulo
en la actualización debido a la posibilidad de que nuestra pieza haya sido arrastrada a su hogar. No queremos lo anterior. _currentDropPiece
valor que cuelga alrededor. A continuación ponemos la _ratón
objeto de la misma manera que hicimos en clic.
_stage.clearRect (0,0, _puzzleWidth, _puzzleHeight);
Aquí tenemos que hacer claros todos los gráficos en el lienzo. Básicamente necesitamos volver a dibujar las piezas del rompecabezas porque el objeto que se arrastra hacia arriba afectará su apariencia. Si no hiciéramos esto, veríamos algunos resultados muy extraños siguiendo el camino de nuestra pieza de rompecabezas arrastrada.
var i; pieza de var para (i = 0; i < _pieces.length;i++)
Empieza configurando nuestro habitual bucle de piezas..
pieza = _pieces [i]; if (pieza == _currentPiece) continuar;
Crear nuestro trozo
referencia como de costumbre. A continuación, compruebe si la pieza a la que estamos haciendo referencia actualmente es la misma que estamos arrastrando. Si es así, continúa el bucle. Esto mantendrá la ranura de inicio de la pieza arrastrada vacía..
_stage.drawImage (_img, piece.sx, piece.sy, _pieceWidth, _pieceHeight, piece.xPos, piece.yPos, _pieceWidth, _pieceHeight); _stage.strokeRect (piece.xPos, piece.yPos, _pieceWidth, _pieceHeight);
Continuando, vuelva a dibujar la pieza del rompecabezas usando sus propiedades exactamente de la misma manera que lo hicimos cuando las dibujamos por primera vez. Tendrás que dibujar el borde también.
if (_currentDropPiece == null) if (_mouse.x < piece.xPos || _mouse.x > (piece.xPos + _pieceWidth) || _pardusco < 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 ();
Ya que tenemos una referencia a cada objeto en el bucle, también podemos usar esta oportunidad para verificar si la pieza arrastrada está encima de él. Hacemos esto porque queremos dar retroalimentación al usuario sobre qué pieza se puede colocar. Vamos a profundizar en ese código ahora.
Primero queremos ver si este bucle ya ha producido un objetivo de caída. Si es así, no debemos molestarnos, ya que solo es posible un objetivo de lanzamiento y cualquier movimiento del mouse. Si no, _currentDropPiece
estarán nulo
y podemos proceder a la lógica. Ya que nuestro mouse está en el medio de la pieza arrastrada, todo lo que necesitamos hacer es determinar en qué otra pieza está nuestro mouse..
A continuación, utilice nuestro práctico checkPieceClicked ()
función para determinar si el mouse se desplaza sobre el objeto de pieza actual en el bucle. Si es así, establecemos la _currentDropPiece
variable y dibuja un cuadro teñido sobre la pieza del rompecabezas, lo que indica que ahora es el objetivo de caída.
Recuerda salvar()
y restaurar()
. De lo contrario, obtendrías la caja teñida y no la imagen debajo..
_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);
Por último, pero no menos importante, tenemos que volver a dibujar la pieza arrastrada. El código es el mismo que cuando hicimos clic en él por primera vez, pero el mouse se movió para que su posición se actualice.
pieceDropped ()
Funciónfunction 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, lo peor está detrás de nosotros. Ahora estamos arrastrando con éxito una pieza del rompecabezas e incluso obteniendo retroalimentación visual sobre dónde se dejará caer. Ahora todo lo que queda es dejar caer la pieza. Primero eliminemos a los oyentes de inmediato, ya que no se está arrastrando nada..
A continuación, compruebe que _currentDropPiece
no es nulo
. Si es así, esto significa que lo arrastramos de nuevo a la zona de inicio de la pieza y no a otra ranura. Si no es nulo
, continuamos con la función.
Lo que hacemos ahora es simplemente cambiar la xPos
y yPos
de cada pieza. Hacemos un objeto temporal rápido como un búfer para mantener uno de los valores del objeto en el proceso de intercambio. En este punto, las dos piezas tienen nuevas xPos
y yPos
valores, y se ajustarán a sus nuevos hogares en el próximo sorteo. Eso es lo que haremos ahora, verificando simultáneamente si el juego ha sido ganado..
resetPuzzleAndCheckWin ()
Funciónfunction resetPuzzleAndCheckWin () _stage.clearRect (0,0, _puzzleWidth, _puzzleHeight); var gameWin = true; var i; pieza de var para (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);
Una vez más, borra el lona
y configurar un juegoWin
variable, configurándolo para cierto
por defecto. Ahora proceda con nuestro bucle de piezas muy familiar.
El código aquí debería ser familiar para que no lo revisemos. Simplemente dibuja las piezas de nuevo en sus ranuras originales o nuevas. Dentro de este bucle, queremos ver si cada pieza se está dibujando en su posición ganadora. Esto es simple: verificamos si nuestro sx
y sy
propiedades coinciden con xPos
y yPos
. Si no, sabemos que posiblemente no podríamos ganar el rompecabezas y poner juegoWin
a falso
. Si superamos el ciclo con todos en sus lugares ganadores, configuramos un rápido se acabó el tiempo
para llamar a nuestro juego terminado()
método. (Establecemos un tiempo de espera para que la pantalla no cambie tan drásticamente al soltar la pieza del rompecabezas).
juego terminado()
Funciónfunction gameOver () document.onmousedown = null; document.onmousemove = null; document.onmouseup = null; initPuzzle ();
¡Esta es nuestra última función! Aquí solo eliminamos a todos los oyentes y llamamos. initPuzzle ()
, que restablece todos los valores necesarios y espera a que el usuario vuelva a jugar.
Haga clic aquí para ver el resultado final..
Como puede ver, puede hacer muchas cosas creativas nuevas en HTML5 utilizando áreas de mapa de bits seleccionadas de imágenes cargadas y dibujos. Puede extender esta aplicación fácilmente agregando puntuación y quizás incluso un temporizador para darle más juego. Otra idea sería aumentar la dificultad y seleccionar una imagen diferente en el juego terminado()
Función, dando los niveles de juego..