Android. Juego del ahorcado (VII). Escogiendo una palabra.

android gingerbreadEn este post, vamos a elegir una palabra a partir de una lista fija de palabras. La idea es practicar cómo se crea y se lee un array de Strings en una aplicación Android.

Veamos los pasos que he efectuado:

Crear un fichero de valores xml para almacenar el array de palabras.

  • En Eclipse, desplegamos el árbol del proyecto para llegar a la carpeta Proyecto Ahorcado -> res -> values. Si expandimos dicha carpeta, veremos que está el fichero Strings.xml, utilizado para las etiquetas que aparecen en el programa. La idea es crear otro fichero, de nombre palabras.xml, dentro de esta misma carpeta, para almacenar en él las palabras que serán parte del juego.

Esta es la opción elegida, aunque al lector seguramente le parecerá mejor otra. Si es así, no dude en compartirlo con esta pequeña comunidad. Como se verá más adelante en este mismo post, se ha intentado que el diseño del código de esta decisión sea flexible de cara a posibles cambios futuros sobre la manera de conseguir la palabra en juego.

  • Hacemos click con el botón derecho del ratón encima de esa carpeta. En el menú contextual nos vamos a “New -> Android XML File”. Nos aparece el diálogo siguiente:

crear xml android eclipse

En el que ponemos el nombre palabras.xml (sin olvidar la extensión xml) y seleccionamos el tipo “values” en el grupo de radiobuttons. Es interesante también verificar que en la opción “Folder” aparece la carpeta “res/values”. Pulsamos el botón Finish.

  • Una vez creado el fichero, hacemos doble click sobre él para abrirlo en el editor y verificamos que, de las dos pestañas que aparecen justo en la parte inferior del editor

pestañas edicion fichero xml android eclipse

tenemos seleccionada aquella que pone “palabras.xml”. En este fichero definiremos un array de Strings, en el que cada String será una de las palabras que formarán parte del juego. En este momento, he dejado el fichero así:

<?xml version=”1.0″ encoding=”utf-8″?>
<resources>
<string-array name=”palabras”>
<item>1234</item>
<item>12345</item>
<item>123456</item>
<item>1234567</item>
<item>12345678</item>
<item>123456789</item>
<item>1234567890</item>
</string-array>
</resources>

Lo que se ha añadido es la definición del array palabras…

<string-array name=”palabras”>…</string-array>

y cada una de las palabras dentro de las entradas <item>…</item>.

Como se ve, he puesto números en vez de palabras. Lo he hecho para probar cómo aparecen los diferentes tamaños en pantalla y saber cuál es el tamaño máximo permitido. En posteriores posts, modificaremos este fichero cuando desarrollemos la lógica del juego.

Creación de la clase palabra.java.

Esta clase tendrá las responsabilidades relacionadas con la palabra en juego. En el árbol de proyectos de Eclipse, hacemos click con el botón derecho sobre el paquete

Proyecto Ahorcado->src->misejemplos.ahorcado

y, en el menú contextual, seleccionamos “New->Class”. La llamaremos palabra (en singular). Os pongo el código de la versión actual de esta clase:

package misejemplos.ahorcado;

import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;

public class palabra {

private String[] palabras;
private Canvas lienzo;
private Monigote munyeco;
private String palabra_en_curso;

private int posicion_inicio;
private int espacio_abajo = 35;
private int espacio_entre = 7;
private int tamanyo_linea = 20;

private Paint pincel_linea;

palabra(Resources res, Canvas lienzo, Monigote munyeco)
{
palabras = res.getStringArray(R.array.palabras);
this.lienzo = lienzo;
this.munyeco = munyeco;
inicializa_pincel_linea();
}

private void inicializa_pincel_linea()
{
pincel_linea = new Paint();
pincel_linea.setColor(Color.WHITE);
}

private void getPalabra()
{
palabra_en_curso = palabras[palabra_aleatoria()];
}

private int palabra_aleatoria()
{
return (int) Math.ceil(Math.random()*palabras.length);
}

private int tamanyo_palabra_en_curso()
{
return palabra_en_curso.length();
}

public void pinta_palabra()
{
getPalabra();

int i = 1;

posicion_inicio =  munyeco.getdatosmonigote().getPdinfder();

for(i=1;i<=tamanyo_palabra_en_curso();i++)
{

lienzo.drawLine(posicion_inicio,
munyeco.getdatosmonigote().getPdinf() + espacio_abajo,
posicion_inicio + tamanyo_linea,
munyeco.getdatosmonigote().getPdinf() + espacio_abajo,
pincel_linea);

posicion_inicio = posicion_inicio + tamanyo_linea + espacio_entre;
}
}

}

Cosas interesantes respecto a esta clase:

  • El método constructor tiene definidos tres parámetros:

palabra(Resources res, Canvas lienzo, Monigote munyeco) {…}

Que son necesarios para, respectivamente, poder acceder al fichero xml, pintar y saber datos de posición del monigote para pintar las líneas horizontales en base a dicha posición.

  • Además de otros atributos, se define uno que es un array de Strings

private String[] palabras;

en el que “volcaremos” la información del fichero palabras.xml.

  • La idea consiste en
    • volcar el contenido del array del fichero xml en el array definido en esta clase como atributo,
    • Elegir una palabra al azar del array con palabra_aleatoria().
    • Saber de cuántas letras es con tamanyo_palabra_en_curso().
    • Presentar por pantalla una línea horizontal por cada letra que tiene la palabra seleccionada.
  • Todo ello se puede seguir a partir del método pinta_palabra(). Si sigues su código, comprobarás las llamadas a otros métodos que, de forma conjunta, realizan este trabajo.

Modificar la clase monigote.

Debido a que el atributo

private datosmonigote datos;

Es privado, crearemos un método público para poder consultarlo. ¿Por qué es necesario consultarlo?: para poder acceder a los datos de posición del monigote, y así saber en dónde empiezo a “pintar” las líneas horizontales de la palabra oculta. el método quedará de esta forma:

public datosmonigote getdatosmonigote()
{
return datos;
}

No es necesario hacer ningún otro cambio en esta clase.

Cambios en la clase Escenario.java.

El nuevo aspecto es el siguiente:

package misejemplos.ahorcado;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.view.View;

public class Escenario extends View {

private final Juego juego;
private Resources res;

public Escenario(Context context, Resources res) {
super(context);
this.res = res;
this.juego = (Juego) context;
setFocusable(true);

// TODO Auto-generated constructor stub
}

@Override
protected void onDraw(Canvas canvas)
{

Monigote monigote = new Monigote(canvas);
palabra palabra_juego = new palabra(res, canvas, monigote);
palabra_juego.pinta_palabra();

}
}

  • Ha sido necesario añadir un nuevo parámetro en el constructor. Resulta que el objeto que crearemos de la clase palabra, necesita saber el objeto de la clase Resources que le permitirá acceder al fichero palabras.xml. El objeto de la clase Escenario.java no tiene dicha referencia, por lo que se la pasaremos en el momento de su creación desde Juego.java, explicado más adelante.

Cambios en la clase Juego.java.

El nuevo aspecto de esta clase es el siguiente:

package misejemplos.ahorcado;

import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.os.Bundle;
import android.view.inputmethod.InputMethodManager;

public class Juego extends Activity{

private Escenario escenario;
private Resources res;

protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
res = getResources();
this.escenario = new Escenario(this, res);

setContentView(this.escenario);

// visualizar teclado soft siempre
InputMethodManager imm =
(InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED,
InputMethodManager.HIDE_IMPLICIT_ONLY);

}
}

Además del import de Resources, he destacado las dos líneas de código más interesantes. La primera accede a los recursos (y uno de ellos es nuestro nuevo fichero xml) de esta aplicación. La segunda crea un objeto de la clase Escenario. Esta última línea ya se ejecutaba en las versiones anteriores, aunque ha sido necesario modificarla para tener en cuenta el nuevo parámetro del constructor de la clase Escenario.

Viendo el resultado.

Si ejecutamos haciendo click con el botón derecho al proyecto y seleccionando “Run As-> Android Application”, el resultado, después de pulsar Nuevo juego es el siguiente:

desarrollo juego Android eclipse

Si vamos hacia atrás utilizando el botón boton atras emulador android eclipse en el emulador y vamos pulsando nuevo juego, podremos ver que la palabra que se utiliza va cambiando. Compruébalo viendo cuántas letras tiene.

Podéis utilizar el siguiente vínculo si queréis descargar el paquete entero de este desarrollo en el avance actual a este post.

Juego del Ahorcado hasta palabra oculta

¡Un saludo y hasta el próximo post!

Acerca de Isildur Fuentes

Apasionado de las buenas historias y aikidoka de la tierra.

Publicado el abril 2, 2011 en Android, Divulgación, EDIB, Programación y etiquetado en , , , , , , . Guarda el enlace permanente. 3 comentarios.

  1. Buenas Isidro,

    Me he encontrado con un problema a la hora de ejecutar la aplicacion en este paso y es que algunas veces al generar la palabra, me da un ArrayOutOfBoundsException.

    ¿Puede ser porque intente buscar el valor maximo (el tamaño del array es 7) dentro de los valores del array (0 a 6) y al buscar el 7 casque la excepcion?
    ¿Que opinas? ¿A ti no te ha pasado esto?

    Un saludo

  2. Buenas otra vez,

    parece que con un (palabras.length)-1 no salta la excepcion.

    Un slaudo.

    • Hola Miguel.
      Estaba a punto de contestar tu comentario anterior cuando he visto éste. Me alegra que hayas dado con la solución. Como bien dices, el error ArrayOutOfBoundsException se refiere al intento de acceder a una posición del array fuera de sus límites, cosa que arreglas.

      Gracias por compartir tus experiencias en este blog.

A %d blogueros les gusta esto: