Juglar

Motor de juegos narrativos y educativos
para aprender programación web

Formar imágenes

Otro tipo de puzle sencillo puede ser el formar una imagen a partir de varias piezas. En este caso simplemente tenemos que girar las piezas para formar la imagen correcta:

En el html tenemos 9 piezas, todas dentro de un mismo elemento:


<puzle-giratorio>
	<button data-escena="menú-juego">Volver</button>
	
	<piezas-puzle>
		<pieza-puzle></pieza-puzle>
		<pieza-puzle></pieza-puzle>
		<pieza-puzle></pieza-puzle>
		
		<pieza-puzle></pieza-puzle>
		<pieza-puzle></pieza-puzle>
		<pieza-puzle></pieza-puzle>
		
		<pieza-puzle></pieza-puzle>
		<pieza-puzle></pieza-puzle>
		<pieza-puzle></pieza-puzle>
	</piezas-puzle>
	
	<link rel="stylesheet" href="puzle_giratorio.css">
	<script src="puzle_giratorio.js"></script>
</puzle-giratorio>

En css, para colocarlas en filas y columnas usaremos una rejilla (grid), e indicamos las filas (grid-template-rows) y columnas (grid-template-columns) con el valor auto tres veces, para indicar que tendremos tres filas y tres columnas:

piezas-puzle{
	display: grid;
	grid-template-columns:auto auto auto;
	grid-template-rows:auto auto auto;
	margin: auto;
	width:90%;
	aspect-ratio: 1/1;
}

Para las fichas usaremos la misma imagen, solo que cada una solo mostrará una parte. Con background-size la hacemos tres veces más grande, y luego con background-position elegimos que parte de la imagen muestra:


pieza-puzle{
	background-image:url("img/triceratops.jpg");
	background-size:calc(300%) calc(300%);
	
	background-position-x:0%;
	background-position-y:0%;
	cursor:pointer;
	
	transition:rotate 0.5s;
	
	&:nth-child(3n - 1){
		background-position-x:50%;
	}
	
	&:nth-child(3n){
		background-position-x:100%;
	}
	
	&:nth-child(n+4){
		background-position-y:50%;
	}
	
	&:nth-child(n+7){
		background-position-y:100%;
	}
}

Usamos nth-child para escoger filas y columnas, y en base a estos decidir que parte de la imagen mostramos.

En javascript lo primero que haremos es girar al azar las piezas del puzzle:

const puzle_giratorio = selecciona("puzle-giratorio")
const piezas = puzle_giratorio.selecciona("pieza-puzle")

gira_al_azar_las_piezas_del_puzle()

function gira_al_azar_las_piezas_del_puzle(){
	piezas.para_cada(pieza => {
		const rotación = Math.floor(al_azar_entre(0, 3)) * 90
		pieza.estilo.rotate = rotación + "deg"
	})
}

Luego solo tenemos que girar cada pieza al pulsar en ella, añadiendo 90 grados a la rotación, para terminar comprobando si todas las piezas están bien colocadas:

piezas.al_pulsar(pieza =>{
	let  rotación = parseInt(pieza.estilo.rotate)
	
	if(!rotación) rotación = 0
	rotación += 90
	
	pieza.estilo.rotate = rotación + "deg"
	comprueba_puzle()
})

Este tipo de puzle serviría para completar un texto o un mapa roto en varias partes, por ejemplo. Aunque la misma idea se puede usar con cables o tuberías que hay que girar para arreglar algún aparato.