Aplicación experimental del juego del ahorcado en Javascript, con jQuery y las librerías jQuery UI y uso del elemento Canvas del HTML 5.
En este artículo voy a presentar una aplicación experimental que he realizado, basada en el popular Juego del ahorcado. Hay personas que disfrutan montando maquetas de trenes, pero yo soy de los que se entretienen con la programación. Prueba de ello es el siguiente script, que realicé hace meses, únicamente con la intención de probar algunos de los más novedosos juguetitos para desarrolladores, como son jQuery UI o el elemento Canvas.
A pesar que no voy a explicar paso por paso cómo se construyó esta aplicación, me he decidido a escribir este artículo por si a alguien le interesa conocer una posible implementación del juego del Ahorcado en Javascript. Además, nos servirá de práctica para las personas que están aprendiendo jQuery o el dibujo con el elemento Canvas.
Para empezar, dejo un enlace a la página del juego en funcionamiento, para que los interesados puedan ver el resultado final de esta práctica.
Tecnologías usadas en la aplicación del ahorcado
En este juego del ahorcado hemos usado algunas de las tecnologías más modernas para el desarrollo de webs, las nombramos a continuación.
Framework Javascript jQuery:
Usamos jQuery para simplificar las cosas durante la programación en Javascript. Puedes aprender en el Manual de jQuery.
Librería jQuery UI:
Las librerías jQuery UI nos sirven para crear diversos componentes de interfaz de usuario avanzados, como botones o cajas de diálogo. Podría hacerse sin estas librerías, igual que también sin el propio jQuery, pero la verdad es que simplifican nuestra vida bastante y nos ayudan a realizar un juego más atractivo visualmente y facilitan una mejor experiencia de usuario. En DesarrolloWeb.com también puedes aprender jQuery UI.
Canvas del HTML 5:
Utilizamos el componente CANVAS para pintar cada una de las partes del cuerpo del ahorcado que se colocan según la persona que juega va cometiendo errores. La propia estructura de la ahorca también está pintada con el elemento Canvas del HTML 5. También podríamos hacer este juego sin utilizar el Canvas, colocando simples imágenes generadas con algún editor gráfico, pero justamente lo que deseamos es hacer una aplicación donde podamos practicar con el elemento Canvas. Puedes aprender sobre esto en el Manual de Canvas del HTML 5.
Aparte de todo esto, por supuesto, utilizamos el lenguaje Javascript, que se puede aprender en la sección Javascript a fondo.
Explicación básica del script
El primer pedazo de código que podemos revisar es donde se escoge una palabra. Esto se hace cuando la página carga. Ese pedazo de código está comentado con el texto "PALABRAS" a partir de la línea de código 37. Primero se define un array con todas las letras posibles y luego se crea una variable "palabraEscogida" con una de esas letras seleccionada aleatoriamente. Además, todo seguido, se define un array con los aciertos.
Una vez hemos reparado en el detalle de cómo se escoge la palabra inicialmente para el juego, podemos ver el resto del código. Para ver cómo hemos hecho este script para el juego del ahorcado recomiendo leer la parte en la que se inicia la aplicación y luego ir revisando cada una de las funciones a medida que se van invocando desde el inicio.
Como cualquier aplicación o script jQuery, el código que se ejecuta al principio está dentro método ready del objeto document.
$(document).ready(function(){
//código que inicia la aplicación
}
- Creamos un array con las letras del abecedario y luego un bucle para recorrerlas.
- Para cada letra, generamos un elemento SPAN que tiene el texto de dicha letra y convertimos ese SPAN en un componente botón de las librerías jquery UI. Además, en el elemento SPAN guardo un dato con el método data() para saber qué letra corresponde a ese elemento.
- También para cada una de las letras, se define un evento click con jQuery. El clic en usa de esas letras significa que el usuario la ha elegido para ver si estaba en la palabra que debía adivinar. A partir de los clics en esas letras se van ejecutando las acciones para mostrar esa letra, en caso que estuviera en la palabra, o colocar un pedazo más del ahorcado, en caso que fuera un error.
- Si la letra escogida estaba en la palabra, entonces la meto en el array de aciertos y la escribo en la página. Además, si estaban todas las palabras acertadas, muestro un mensaje en una caja de diálogo con el componente dialog de jQuery UI.
- En caso que la letra escogida no estuviese en la palabra, incremento una variable con el número de fallos y dibujo el ahorcado con los fallos actuales. Si se ha llegado al número de fallos máximo, se muestra un mensaje con otra caja de diálogo.
- Dentro del evento clic definido para toda letra que se haya pulsado, como última acción, se desactiva el botón y se elimina el evento clic, para que no se permita volver a pulsar sobre la misma letra.
- Ya fuera del código del evento, pero todavía dentro del bucle para recorrer todas las letras, se hace un append() para colocar ese botón en la página.
- Se dibuja el ahorcado con la función dibujaAhorcado(), enviando el número de fallos, que inicialmente es cero.
- Además, se escribe la palabra escogida, inicialmente ocultando todas las letras con guiones, pues inicialmente no hay ninguna letra en el array de aciertos.
Código completo del juego del ahorcado
En las líneas anteriores hemos visto un resumen de la funcionalidad principal del juego del ahorcado, pero claro que hay mucho más código para hacerlo funcionar. Además, que deberíamos haber hecho otras cosas como incluir los scripts jQuery y jQuery UI, así como la hoja de estilos.
Podemos ver a continuación las 300 líneas de código que hacen el juego completo.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Aplicaciçon de Ahorcado</title>
<link type="text/css" href="css/cupertino/jquery-ui-1.8.1.custom.css" rel="Stylesheet" />
<script type="text/javascript" src="js/jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="js/jquery-ui-1.8.1.custom.min.js"></script>
<script>
function aleatorio(inferior,superior){
numPosibilidades = superior - inferior + 1
aleat = Math.random() * numPosibilidades
aleat = Math.floor(aleat)
return parseInt(inferior) + aleat
}
function esta(caracter, miarray){
//console.log("buscando ", caracter, " en ", miarray)
for(var j=0;j<miarray.length;j++){
if (caracter==miarray[j]){
return true;
}else{
//console.log("el caracter ", caracter, " no es el valor del array ",miarray[j] )
}
}
return false;
}
function estanTodas(arrayAciertos, mipalabra){
for(var i=0; i<mipalabra.length; i++){
if(!esta(mipalabra.charAt(i),arrayAciertos))
return false;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
// PALABRAS
////////////////////////////////////////////////////////////////////////////////
var palabras = ['ahorcado', 'lavadora', 'invierno', 'plastico', 'ordenador', 'colador', 'guantera', 'alimentador', 'calculos'];
var palabraEscogida = palabras[aleatorio(0,palabras.length-1)]
var aciertos = [];
//console.log(palabraEscogida);
function escribePalabra(palabra, arrayAciertos){
//console.log("estoy en escribePalabra y arrat de aciertos es: " , arrayAciertos);
var texto = '';
for(var i=0; i<palabra.length; i++){
texto += "<span>";
var cActual = palabra.charAt(i);
if(esta(cActual,arrayAciertos)){
texto += cActual;
}else{
texto += '_';
}
texto += "</span>";
//console.log(cActual)
}
$("#letras").html(texto);
}
////////////////////////////////////////////////////////////////////////////////
//// inicio todo!!!
////////////////////////////////////////////////////////////////////////////////
$(document).ready(function(){
//creo los botones con las letras
var letras = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'Ñ', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'];
for(i=0; i<letras.length; i++){
//creo el span de la letra
letraActual = $('<span class="botonletra">' + letras[i] + '</span>');
letraActual.data("letra",letras[i]);
//lo convierto en un botón
letraActual.button();
letraActual.click(function(){
//traigo la letra pulsada
var miletra = $(this).data("letra").toLowerCase()
//miro si esa letra está en la palabra
if(palabraEscogida.indexOf(miletra)!=-1){
//si está, va para aciertos
aciertos.push(miletra);
escribePalabra(palabraEscogida, aciertos);
//miro si ha ganado
if(estanTodas(aciertos,palabraEscogida)){
var caja = $('<div class="dialogletra" title="Has Ganado!!">Felicidades! has adivinado la palabra!!</div>');
caja.dialog({
modal: true,
width: 600,
buttons: {
"Ok": function(){
$(this).dialog("close");
}
}
});
}
}else{
//no estaba
numFallos++;
dibujaAhorado(numFallos);
//miro si se ha perdido
if(numFallos==6){
var caja = $('<div class="dialogletra" title="Has Perdido!!">Lo lamento!! la palabra era: ' + palabraEscogida + '</div>');
caja.dialog({
modal: true,
width: 600,
buttons: {
"Ok": function(){
$(this).dialog("close");
}
}
});
}
}
//una vez pulsado el botón, lo desabilito y quito su evento click
$(this).button("disable");
$(this).unbind( "click" );
})
$("#botonesletras").append(letraActual);
}
//inicio el canvas
dibujaAhorado(numFallos);
//inicio las palabras
escribePalabra(palabraEscogida, aciertos);
});
/////////////////////////////////
//CANVAS
/////////////////////////////////
function cargaContextoCanvas(idCanvas){
var elemento = document.getElementById(idCanvas);
if(elemento && elemento.getContext){
var contexto = elemento.getContext('2d');
if(contexto){
return contexto;
}
}
return false;
}
function borrarCanvas(contexto, anchura, altura){
contexto.clearRect(0,0,anchura,anchura);
}
function dibujaHorca(ctx){
ctx.fillStyle = '#462501';
ctx.fillRect(64,9,26,237);
ctx.fillRect(175,193,26,53);
ctx.fillRect(64,193,136,15);
ctx.fillRect(64,9,115,11);
ctx.beginPath();
ctx.moveTo(64,65);
ctx.lineTo(64,80);
ctx.lineTo(133,11);
ctx.lineTo(118,11);
ctx.fill();
}
function dibujaCabeza(ctx){
var img = new Image();
img.onload = function(){
ctx.fillStyle = '#f2d666';
ctx.drawImage(img,150,38);
ctx.fillRect(172,12,4,28);
}
img.src = 'images/picture.jpg';
}
function dibujaCuerpo(ctx){
ctx.beginPath();
ctx.moveTo(171,82);
ctx.lineTo(168,119);
ctx.lineTo(162,147);
ctx.lineTo(189,149);
ctx.lineTo(185,111);
ctx.lineTo(183,83);
ctx.fill()
}
function dibujaBrazoIzq(ctx){
ctx.beginPath();
ctx.moveTo(173,102);
ctx.lineTo(140,128);
ctx.lineTo(155,133);
ctx.lineTo(178,114);
ctx.fill()
}
function dibujaBrazoDer(ctx){
ctx.beginPath();
ctx.moveTo(180,99);
ctx.lineTo(222,121);
ctx.lineTo(209,133);
ctx.lineTo(183,110);
ctx.fill()
}
function dibujaPiernaIzq(ctx){
ctx.beginPath();
ctx.moveTo(166,142);
ctx.lineTo(139,175);
ctx.lineTo(164,178);
ctx.lineTo(175,144);
ctx.fill()
}
function dibujaPiernaDer(ctx){
ctx.beginPath();
ctx.moveTo(178,145);
ctx.lineTo(193,178);
ctx.lineTo(212,170);
ctx.lineTo(188,142);
ctx.fill()
}
////////////////////////////////////////////////////////
// GESTION DE FALLOS
////////////////////////////////////////////////////////
var numFallos = 0;
function dibujaAhorado(numerrores){
var contexto = cargaContextoCanvas('canvasahorcado');
if(contexto){
dibujaHorca(contexto);
if(numFallos>0){
dibujaCabeza(contexto)
}
contexto.fillStyle = '#1f3e18';
if(numFallos>1){
dibujaCuerpo(contexto)
}
if(numFallos>2){
dibujaBrazoIzq(contexto)
}
if(numFallos>3){
dibujaBrazoDer(contexto)
}
if(numFallos>4){
dibujaPiernaIzq(contexto)
}
if(numFallos>5){
dibujaPiernaDer(contexto)
}
}
}
</script>
<style type="text/css">
body{
font-size: 0.7em;
font-family: Trebuchet MS, verdana, arial, sans-serif;
}
.botonletra{
font-size: 0.9em;
margin: 2px;
width: 30px;
text-align: center;
}
.dialogletra{
font-size: 3em;
text-align: center;
padding-top: 15px;
}
#botonesletras{
width: 330px;
clear: both;
}
#dibujoahorcado{
margin-bottom: 20px;
}
#letras{
font-size: 3em;
text-align:center;
width: 320px;
clear: both;
margin-bottom: 10px;
}
#letras span{
width: 30px;
text-align:center;
padding-left: 5px;
}
</style>
</head>
<body>
<div id="dibujoahorcado">
<canvas id="canvasahorcado" width="320" height="250">
El Ahorcado sólo funciona en navegadores que soporten Canvas. Actualízate a Firefox o Chrome, por poner dos posibilidades.
</canvas>
</div>
<div id="letras">
</div>
<div id="botonesletras"></div>
</body>
</html>
Eso es todo!! quedan bastantes cosas que explicar en el tintero, pero estoy seguro que se podrán entender siguiendo los comentarios del código y las referencias a manuales y artículos donde explicamos cosas como jQuery o el componente Canvas.
Para acabar, podemos ver el ejercicio en marcha en una página aparte.
Miguel Angel Alvarez
Fundador de DesarrolloWeb.com y la plataforma de formación online EscuelaIT. Com...