Juego en Ionic 2 – Creación del fantástico ahorcado – Parte 2

Adivina la palabra secreta – vamos a continuar con la creación del divertido juego en Ionic 2 que desarrollamos en nuestra entrada anterior.

¿Qué veremos  esta entrada?

Vamos a mejorar el código fuente de nuestra aplicación Juego en Ionic 2Ahorcado para que quede como se muestra en la siguiente imagen. Añadiremos un contador de vidas que estará basado en un sistema de fallos y aciertos, además completaremos el juego con un sistema de puntuación y también se crearán las celdas para saber de cuantas letras se compone la palabra secreta.

Añadimos para el juego en Ionic 2  las celdas que nos indican cuantas letras tiene la palabra

Ahora lo que vamos a hacer es un contador del número de letras del cual dispone la palabra secreta y convertiremos cada letra en un hueco o barra baja, de este modo al iniciar la aplicación y cuando el sistema haya definido la nueva palabra, aparecerá un hueco por cada una de las letras y conoceremos su longitud. Se podrá intuir que _ _ _ _ puede corresponder a la palabra MOTO, BICI o similar.

Volvemos a ir al controlador home.ts y creamos un nuevo método justo debajo del método compruebaLetra(), aquí muestro como ha de quedar y seguidamente explicaré que es lo que estamos haciendo.

public muestraHuecosPalabra() {
    let totalHuecos = this.nombreSecreto.length;

    // Declaramos la variable huecos como nuevo array.		
    let huecos = new Array;
    for (let i = 0; i < totalHuecos; i++) {
	//Asignamos tantos huecos como letras tenga la palabra.
	huecos.push('_');
    }

    // Para empezar formamos la variable palabra tan solo con los huecos, ya que en este momento aún no se ha seleccionado ninguna letra.	
    this.palabra = huecos;
    return this.palabra;
}

Detalle del método muestraHuecosPalabra()

En la primera línea, contamos el número de letras que tiene la palabra que generó el sistema ejecutando el método palabraAleatoria(primer, ultimo) ya que this.nombreSecreto es el resultado de este.

Declaramos un nuevo array let huecos y le asignamos un valor _ por cada vuelta que da el bucle, si la palabra secreta fuera MOTO, el bucle se ejecutaría 4 veces y el valor de huecos sería [_,_,_,_].

Por último, le asignamos el valor del array a la variable palabra, esta variable será tratada posteriormente, pero para que esta funcione correctamente antes deberemos declararla justo debajo de letra, nombres y nombreSecreto.

Añadiendo los huecos de la palabra secreta a la vista home.html

Abrimos de nuevo nuestra vista y añadimos una lista de Ionic donde vamos a mostrar los huecos que hemos definido en el controlador, justo debajo de la etiqueta <ion-content padding> y encima de la etiqueta <ion-list> correspondiente al selector, insertaremos lo siguiente.

<ion-list >
    <ion-grid>
	<ion-row>
            <ion-col col-2 *ngFor="let item of palabra">
		<ion-input type="text" value="{{item}}">{{item}}</ion-input>
	    </ion-col>
	</ion-row>
    </ion-grid>
</ion-list>

Lo que hemos hecho en la vista sabemos que es añadir una nueva lista al igual que hicimos con el selector, pero tiene la novedad de llevar incluido un grid dentro, los grids estan formados en su interior por filas <ion-row></ion-row> y por columnas <ion-col></ion-col>, pero lo que realmente cabe destacar aquí es la etiqueta *ngFor de Angular. Con la etiqueta *ngFor lo que conseguimos es crear un bucle en la vista y le asignamos a item el valor de cada uno de los elementos del array palabra que en este caso inicial serán tantas _ (barra baja) como letras tenga la propia palabra.

Si alguien quiere obtener información adicional sobre los grids de Ionic, puede visitar: https://ionicframework.com/docs/components/#grid

Vemos que si guardamos en este momento, y vamos al navegador no apreciamos cambio alguno, esto tiene una fácil explicación y es debido a qué no hemos lanzado el método muestraHuecosPalabra() en la carga inicial de la aplicación, para ello, vamos a volver al controlador e insertamos justo debajo de la declaración de la variable palabra la siguiente línea.

muestraHuecos: any = this.muestraHuecosPalabra();

En este momento, tras haber guardado ya podemos ver en nuestro navegador que el resultado es el esperado, ya disponemos de los huecos correspondientes de las letras de la palabra secreta.

Insertando las letras acertadas en los huecos de la palabra

Volvemos al controlador home.ts, vamos a ampliar notablemente el contenido del método compruebaLetra() quedando de la siguiente manera.

// Método que valida la letra seleccionada.	
public compruebaLetra() {
    // Formateamos a mayúsculas para mejorar la legibilidad.
    let letraMayusculas = this.letra.toUpperCase();
    
    // Si se ha seleccionado una letra...		
    if (letraMayusculas) {

        if (this.nombreSecreto.indexOf(letraMayusculas) != -1) {

            let nombreSecretoModificado = this.nombreSecreto;
	    let posicion = new Array;
	    let posicionTotal = 0;

	    let contador = 1;
	    while (nombreSecretoModificado.indexOf(letraMayusculas) != -1) {
					
		posicion[contador] = nombreSecretoModificado.indexOf(letraMayusculas);
	        nombreSecretoModificado = nombreSecretoModificado.substring(nombreSecretoModificado.indexOf(letraMayusculas) + letraMayusculas.length, nombreSecretoModificado.length);

		// Calculamos la posición total.
		if (contador > 1) {
		    posicionTotal = posicionTotal + posicion[contador] + 1;
	        }
		else { 
		    posicionTotal = posicionTotal + posicion[contador];
		}

		this.palabra[posicionTotal] = letraMayusculas;

                alert('GENIAL!!! La letra ' + letraMayusculas + ' se encuentra en la palabra secreta.');

                contador++;
            }
        }
        else {
            alert('FALLO!!! La letra ' + letraMayusculas + ' no se encuentra en la palabra secreta.');
        }
    }
    else {
        alert('Seleccione una letra del listado.');
    }
}

Detalle del método compruebaLetra()

Definimos la variable nombreSecretoModificado que nos permitirá trocear la cadena o palabra sin llegar a perder la palabra original, también definimos posicion como nuevo array que guardará por cada elemento el valor o posición en el cual se encuentra, por ejemplo en la palabra MOTO si seleccionamos la letra O esta se encuentra 2 veces por lo tanto el valor de posicion será [‘1′,’3’] ya que la letra O se encuentra en las posiciones 1 y 3 del string MOTO. La variable posicionTotal será utilizada para realizar la suma de la posición de cada una de las letras.

Creamos un bucle while para que de tantas vueltas como veces sea detectada la letra seleccionada en la palabra. En su interior se realizan las tareas de asignación de valores a posicion como os acabo de comentar. Reasignamos valor a la variable nombreSecretoModificado, en este caso será un texto troceado, me explico volviendo a poner como ejemplo la palabra MOTO… en la primera vuelta del bucle, la variabe nombreSecretoModificado vale MOTO, pero en la segunda vuelta quitamos lo que ya no necesitamos que es MO y el nuevo valor de la variable sería TO.

Continuamos calculando la posición total y cambiamos la _ (barra baja) por la letra seleccionada con la línea this.palabra[posicionTotal] = letraMayusculas; y por último sumamos 1 al contador.

Cambiando los alerts por mensajes en la aplicación

Ha llegado el momento de cambiar las ventanas modales por mensajes en formato de texto en la propia aplicación, para ello empezaremos definiendo una nueva variable justo a continuación de muestraHuecos: any = this.muestraHuecosPalabra(); y será la siguiente: mensaje: string = ‘Selecciona una letra del listado.’;

Hagamos recuento de cómo tenemos la declaración de variables.

// Definimos las variables
letra: string = '';
nombres: any = ['COCHE', 'MOTO', 'CARTEL', 'COCHECITO', 'RAQUETA'];
nombreSecreto: any = this.palabraAleatoria(0, (this.nombres.length - 1));
palabra: any = '';
muestraHuecos: any = this.muestraHuecosPalabra();
mensaje: string = 'Selecciona una letra del listado.';

Ahora vamos a cambiar la línea:

alert('GENIAL!!! La letra ' + letraMayusculas + ' se encuentra en la palabra secreta.');

Por la línea:

this.mensaje = 'Genial, la letra ' + letraMayusculas + ' está en la palabra secreta.';

También cambiamos la línea:

alert('FALLO!!! La letra ' + letraMayusculas + ' no se encuentra en la palabra secreta.');

Por la línea:

this.mensaje = 'Fallo, la letra ' + letraMayusculas + ' no está en la palabra secreta.';

Y por último cambiamos la línea:

alert('Seleccione una letra del listado.');

Por:

this.mensaje = 'Seleccione una letra del listado.';

Volvemos de nuevo a nuestra vista home.html e insertamos una nueva lista de ionic justo entre la lista donde pintamos los huecos y la lista del selector de letras.

<ion-list>
    <ion-grid>
	<ion-row>
	    <ion-col col-12>{{mensaje}}</ion-col>
	</ion-row>
    </ion-grid>
</ion-list>

Desde este momento y tras haber guardado los cambios, nuestra aplicación tendrá el siguiente aspecto.

Añadiendo sistema de puntuación y vidas a la aplicación Juego de Ionic – Ahorcado

Estamos acercándonos al final del desarrollo de la aplicación y vamos a continuar creando un contador de vidas del cual iremos restando por cada fallo que tengamos. También vamos a incorporar un sistema de puntos que hará el juego más atractivo, para ello volvemos a la vista e insertamos la siguiente lista entre las listas donde pintamos los huecos y los mensajes. Aquí disponemos de dos nuevas variables vidas y puntos a las cuales les vamos a asignar valor en el controlador.

<ion-list>
    <ion-grid>
	<ion-row>
	    <ion-col col-6 ><ion-icon name="body" color="secondary"></ion-icon> Vidas: {{vidas}}</ion-col>
	    <ion-col col-6>Puntos: {{puntos}}</ion-col>
	</ion-row>
    </ion-grid>
</ion-list>

Volvamos entonces al controlador y añadamos 3 nuevas variables y el array controlLetras (que explicaremos más tarde) justo a continuación de mensaje: string = ‘Selecciona una letra del listado.’;

Como veis cada vez detallo menos puesto que son cosas que ya hemos visto cómo hacer anteriormente pero no os preocupéis, al final del post dejaré el enlace a la descarga de los scripts completos por si os habéis perdido durante la explicación.

vidas: number = 5;
puntos: number = 0;
ganador: number = 0;

// Creamos un array para guardar las letras que se van seleccionando.
controlLetras = new Array;

Más cosas, justo a continuación de la línea this.mensaje = ‘Genial, la letra ‘ + letraMayusculas + ‘ está en la palabra secreta.’; y antes de contador++; vamos a insertar el siguiente trozo de código.

// Sumamos puntos
if (this.controlLetras.indexOf(letraMayusculas) == -1) {
    this.puntos = this.puntos + 10;
}
else { 
    this.mensaje = 'La letra ' + letraMayusculas + ' fue seleccionada anteriormente.';
}

Aquí lo que hacemos es comprobar que la letra que hemos elegido no haya sido seleccionada anteriormente, si no ha sido seleccionada ya que estamos dentro de lo que es el acierto asignamos 10 puntos. En caso de haber sido seleccionada pues mostramos un nuevo mensaje en la aplicación.

¿Y ahora qué?, ¿por dónde continuamos?

Vamos a localizar este trozo de código.

else {
    this.mensaje = 'Fallo, la letra ' + letraMayusculas + ' no está en la palabra secreta.';
}

Aquí lo que tenemos que hacer ahora son varias cosas: restar vidas, restar puntos siempre y cuando nuestros puntos no sean 0 o menos y en caso de tener 0 vidas dar el juego por finalizado. Sustituyamos el código comentado por el siguiente, y sí, aquí tenemos nuevas funciones que aún no hemos creado, lo haremos a continuación.

else {
    // Restamos una vida.
    this.nuevoFallo();

    // Comprobamos si nos queda alguna vida.
    if (this.vidas > 0) {

        // Restamos puntos siempre y cuando no sean 0.
	if (this.puntos > 0) { 
	    if (this.controlLetras.indexOf(letraMayusculas) == -1) {
		this.puntos = this.puntos - 5;
	    }
	}

	// Mostramos un mensaje indicando el fallo.					
	this.mensaje = 'Fallo, la letra ' + letraMayusculas + ' no está en la palabra secreta, recuerda que te quedan ' + this.vidas + ' vidas.';
    }
    else { 
	// Damos el juego por finalizado, el jugador pierde.
	this.finDelJuego('pierde')
    }
}

// Aquí colocaremos el control de suma de puntos.

Vemos como novedad los métodos nuevoFallo(); y finDelJuego(‘pierde’), vamos entonces a crear nuevoFallo() justo debajo del método muestraHuecosPalabra(), así es como debe quedar y poco hay que comentar, lo único que hace es restar una vida al número de vidas actual.

public nuevoFallo() {
    this.vidas = this.vidas - 1;
    return this.vidas;
}

Y ahora creamos otro método llamado finDelJuego(valor), a este lo podemos llamar con 2 valores (gana o pierde), dependiendo de su parámetro mostrará un mensaje u otro. En el caso de ‘gana’ también damos valor = 1 a la variable ganador, luego explicaremos el uso de esta.

public finDelJuego(valor) { 
    // Perdedor
    if (valor == 'pierde') { 
	// Mostramos el mensaje como que el juego ha terminado
	this.mensaje = 'Perdiste!, Inténtalo de nuevo. Has conseguido un total de ' + this.puntos + ' puntos. La palabra secreta es ' + this.nombreSecreto;
    }

    // Ganador
    if (valor == 'gana') { 
	this.mensaje = 'Enhorabuena!, Has acertado la palabra secreta. Has conseguido un total de ' + this.puntos + ' puntos.';
	this.ganador = 1;
    }		
}

Añadiendo a la vista home.html vidas y puntos

En la vista vamos a crear una nueva lista de Ionic justo encima de la lista donde mostramos el mensaje, paso a continuación las líneas que vamos a añadir para dar formato a la sección de vidas y puntos.

<ion-list>
    <ion-grid>
	<ion-row>
	    <ion-col col-6 ><ion-icon name="body" color="secondary"></ion-icon> Vidas: {{vidas}}</ion-col>
	    <ion-col col-6>Puntos: {{puntos}}</ion-col>
	</ion-row>
    </ion-grid>
</ion-list>

Llegados a este punto, podemos guardar y probar nuestra aplicación y la verdad es que todo parece estar funcionando correctamente, pero no, tenemos un problema con el trampeo de puntos y es que si escogemos una letra y esta existe en la palabra secreta y volvemos a pulsar el botón sin cambiar la letra, por cada vez que pulsamos el botón se nos suman 10 puntos… aiiiiiis tramposines… debemos evitar esto, ¿cómo?, vamos a ello.

En el controlador buscamos la línea donde dice // Aquí colocaremos el control de suma de puntos. y la reemplazamos por el trozo de código que muestro a continuación. Se acabaron las trampas.

// Añadimos al array de letras la nueva letra seleccionada.
this.controlLetras.push(letraMayusculas);

Creando un botón u otro dependiendo del estado del juego

Volvemos a la vista y ahora reemplazamos esto.

<!-- Mostramos el botón para seleccionar letra  -->
<button ion-button block color="secondary" (click)="compruebaLetra()">Seleccionar</button>

Por esto otro.

<!-- Si continuamos teniendo vidas, mostramos el botón para seleccionar letra  -->
<button *ngIf="vidas!=0 && ganador!=1" ion-button block color="secondary" (click)="compruebaLetra()">Seleccionar</button>

<!-- En caso de no tener vidas, mostramos un botón para reiniciar el juego -->
<button *ngIf="vidas==0 || ganador==1" ion-button block (click)="reiniciaJuego()">Jugar de nuevo</button>

Estamos haciendo uso de los condicionales de Angular JS *ngIf en este caso estamos comprobando el valor de las variables asignadas en el controlador y dependiendo de este, mostramos un botón u otro.

Últimos pasos del post

Para finalizar, vamos a crear en el controlador el método que nos permita reiniciar todos los valores una vez se dé por finalizado el juego, este lo podemos insertar justo después de finDelJuego(valor)

public reiniciaJuego() { 
    this.letra = '';
    this.palabra = '';
    this.vidas = 5;
    this.mensaje = '';
    this.ganador = 0;
    this.puntos = 0;
    this.nombreSecreto = this.palabraAleatoria(0, (this.nombres.length-1));
    this.muestraHuecos = this.muestraHuecosPalabra();
}

Y a su vez vamos a crear un premio extra de 50 puntos para todo aquel que sea capaz de acertar la palabra secreta, este trozo de código lo colocaremos justo después de contador++;  } del método

compruebaLetra()
// Si ya no quedan huecos, mustramos el mensaje para el ganador.
if (this.palabra.indexOf('_') == -1) { 

    // Sumamos puntos
    if (this.controlLetras.indexOf(letraMayusculas) == -1) {
	this.puntos = this.puntos + 50;
    }

    // Damos el juego por finalizado, el jugador gana.
    this.finDelJuego('gana')					
}

Guardamos y a disfrutar del juego. Hasta aquí llega nuestra entrada de hoy, en futuras entradas disfrutaremos de posibles mejoras sobre este fantástico juego de ahorcado creado con el framework de desarrollo Ionic 2.

Descargas

home.html: https://drive.google.com/open?id=0B_sqK8lXq9J9Nkt6ckctRER0MGs
home.ts: https://drive.google.com/open?id=0B_sqK8lXq9J9Z3piQ3FNMUhlUGM

Y recuerda, si quieres estar al día acerca de la creación de nuevas entradas, no te olvides de suscribirte al blog.

Versiones utilizadas, tiempo y dificultad de desarrollo:

Dificultad del ejercicio: Iniciación-intermedio.
Tiempo de realización: 45 minutos.
Ionic versión: 2.2.1
Node versión: 7.5.0
NPM versión: 4.3.0
Cordova versión: 6.5.0
Sistema operativo: Windows

Publicaciones relacionadas

Dejar un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Responsable de los datos: Luis María Jordán Muñoz | Finalidad: Responder a la solicitud que me envíes y ofrecerte información | Legitimación: Tu consentimiento de forma expresa | Destinatario: Webempresa mi proveedor de hosting | Derechos: Tienes derecho al acceso, rectificación, supresión, limitación, portabilidad y olvido, para más información, te dejo enlace a mi política de privacidad ... enlace