Genesis Vargas J

Como hacer el juego del ahorcado en Android Studio

Comparte:

Hola amigos, tenía bastante tiempo sin publicar en el blog pero esta vez traigo un aporte acerca de la programación móvil en android. Se trata de hacer nosotros mismos el famoso juego del ahorcado, muchos lo conocerán porque antes se jugaba en papel y con todo esto de la tecnología tambien lo podemos tener en nuestros celulares. Lo primero que hay que tener en cuenta es la lógica que tiene este juego: escoger una palabra (aleatoria) y "partirla" por cada letra para que el jugador adivine la letra que va en cada posición en ciertos intentos.

Bien, introduciendónos en nuestro proyecto de android studio debemos tener un archivo xml resource array donde escribiremos las palabras y en este caso agruparlas por categorías para que el jugador escoja una. También le añadiremos al juego una serie de niveles y guardaremos los puntajes y palabras del resource array en una base de datos Sqlite.

words.XML


<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="nivel">
        <item>FÁCIL</item>
        <item>DIFICIL</item>
    </string-array>
    <string-array name="descripcionnivel">
        <item>Tienes 6 intentos para acertar la palabra</item>
        <item>Tienes 4 intentos para acertar la palabra</item>
    </string-array>
    <string-array name="categoria">
        <item>NATURALEZA</item>
        <item>CIUDADES</item>
    </string-array>
    <string-array name="descripcioncategoria">
        <item>En esta categoria estan: animales, flores, frutas y plantas</item>
        <item>En esta categoria estan algunas de las ciudades de todo el mundo</item>
    </string-array>
    <string-array name="NATURALEZA">
        <item>PERRO</item>
        <item>GATO</item>
        <item>CABALLO</item>
        <item>...</item>
    </string-array>
    <string-array name="CIUDADES">
        <item>BOGOTA</item>
        <item>USHUAIA</item>
        <item>CALLAO</item>
        <item>...</item>
    </string-array>
</resources>

Nuestra base de datos tendrá dos tablas, la primera es la tabla Word que tendrá las columnas: Id (número entero), Name(palabra como tal), Category(nombre de la categoría) y la segunda es la tabla Score que tendrá las columnas: Points(los puntos por cada acierto), Category (la categoría en la que se esta jugando), Level(el nivel en el que se esta jugando).

AdminSQLiteOpenHelper.JAVA


import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class AdminSQLiteOpenHelper extends SQLiteOpenHelper{

    private static final int VERSION = 1;
    private static final String NAME = "ahorcado.db";
    private static final String TABLE = "CREATE TABLE IF NOT EXISTS Word(Id INT, Name TEXT, Category TEXT)";
    private static final String TABLE2 = "CREATE TABLE IF NOT EXISTS Score(Points TEXT, Level TEXT, Category TEXT)";

    public AdminSQLiteOpenHelper(Context context) {
        super(context, NAME, null, VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(TABLE);
        db.execSQL(TABLE2);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE Word");
        db.execSQL("DROP TABLE Score");
        onCreate(db);
    }
}

En esta clase estamos haciendo la configuracion de Sqlite: nombre, versión y por default le creamos las dos tablas mencionadas anteriormente.

Database.JAVA


import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

public class Database {

    AdminSQLiteOpenHelper admin;
    SQLiteDatabase db;

    public Database(Context context)
    {
        admin = new AdminSQLiteOpenHelper(context);
    }

    public void connectDb()
    {
        db = admin.getWritableDatabase();
    }

    public void disconnectDb()
    {
        db.close();
    }

    public Cursor getData(String sql)
    {
        Cursor rows = db.rawQuery(sql, null);
        return rows;
    }

    public Long insertData(String table, ContentValues value)
    {
        Long row = db.insert(table, null, value);
        return row;
    }

    public int updateData(String table, String where, ContentValues value)
    {
        int row = db.update(table, value, where, null);
        return row;
    }
}

En esta clase creamos las funciones para interactuar directamente con la clase helper de sqlite, en el constructor de ésta recibimos el Context y se lo pasamos al helper; estas serían las funciones básicas para un CRUD.

Game.JAVA


import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.widget.Toast;

import java.util.ArrayList;

public class Game {

    String[] categorys;
    String[] categorysData;
    String[] levels;
    Database db;
    Cursor cr;
    Context cntx;

    public Game(Context context)
    {
        cntx = context;
        db = new Database(cntx);
        if(firstTime())
        {
            insertInitialData();
        }
    }

    public void insertInitialData()
    {
        categorys = cntx.getResources().getStringArray(R.array.categoria);
        levels = cntx.getResources().getStringArray(R.array.nivel);
        db.connectDb();
        for (String category : categorys)
        {
            int catint = cntx.getResources().getIdentifier(category, "array", cntx.getPackageName());
            categorysData = cntx.getResources().getStringArray(catint);
            for (int j = 0; j < categorysData.length; j++)
            {
                ContentValues value = new ContentValues();
                value.put("Id", j);
                value.put("Name", categorysData[j]);
                value.put("Category", category);
                db.insertData("Word", value);
            }
        }
        for (String level : levels)
        {
            for (String category : categorys)
            {
                ContentValues value = new ContentValues();
                value.put("Points", "0");
                value.put("Level", level);
                value.put("Category", category);
                db.insertData("Score", value);
            }
        }
        db.disconnectDb();
    }

    Boolean firstTime()
    {
        Boolean set;
        db.connectDb();
        cr = db.getData("SELECT COUNT(*) FROM Word");
        if (cr.moveToFirst())
        {
            if(cr.getInt(0) > 0)
            {
                set = false;
            }
            else
            {
                set = true;
            }
        }
        else
        {
            set = true;
        }
        cr.close();
        db.disconnectDb();
        return set;
    }

    public String getWord(String num, String category)
    {
        String str = null;
        db.connectDb();
        cr = db.getData("SELECT Name FROM Word WHERE Id = " + num + " AND Category = '" + category + "'");
        if (cr.moveToFirst())
        {
            str = cr.getString(0);
        }
        else
        {
            str = null;
        }
        cr.close();
        db.disconnectDb();
        return str;
    }

    public ArrayList<String> getScore()
    {
        ArrayList<String> str = new ArrayList<String>();
        db.connectDb();
        cr = db.getData("SELECT * FROM Score GROUP BY Level, Category");
        if (cr.moveToFirst())
        {
            do
            {
                String cat = cr.getString(cr.getColumnIndex("Category"));
                String lev = cr.getString(cr.getColumnIndex("Level"));
                String pto = cr.getString(cr.getColumnIndex("Points"));
                str.add("Nivel: " + lev + "\nCategoría: " + cat + "\nPuntos: " + pto);
            }
            while (cr.moveToNext());
        }
        else
        {
            str = null;
        }
        cr.close();
        db.disconnectDb();
        return str;
    }

    public int updateScore(String val, String category, String level)
    {
        int row;
        db.connectDb();
        ContentValues value = new ContentValues();
        value.put("Points", val);
        row = db.updateData("Score", "Level='" + level + "' AND Category ='" + category + "'", value);
        db.disconnectDb();
        return row;
    }
}

Esta clase Game la creamos para tener los procedimientos necesarios para el juego, en ella creamos un objeto de la clase Database y tendremos 3 arrays: para los niveles, categorías y las palabras de cada categoría. En el metodo constructor recuperamos el Context que recibimos y se lo pasamos al objeto database y preguntamos si es verdadero la función firstTime que simplemente hace una consulta a la base de datos preguntando si hay filas (osea: datos) en la tabla Word, si es el caso llamamos al método insertInitialData el cual se encargará de asignar a los tres arrays el valor que tienen en nuestro resource array en el archivo words.xml, la idea en este método es insertar los datos iniciales en las dos tablas: para la tabla Word se hacen dos foreach (uno de categoria hasta las palabras de esa categoría) para introducir los valores correspondientes en un ContentValues y finalmente pasarlo a la función insertData de la clase database y lo mismo hacemos para la tabla de Score pera esta vez seran dos foreach de niveles a categorías. Si hay dos arrays de categorías en el archivo xml habran dos arrays con el mismo nombre que tendrán las palabras (por default pusé 80). Y por último las tres funciones principales: la que nos devuelve la palabra aleatoria del juego (una simple consulta a la tabla Word especificando un Id y una Category), el puntaje que devolvemos en un ArrayList y la función para actualizar el puntaje definiendo la categoría y el nivel.


Ahora nos vamos al MainActivity que nos crea por default android studio y aquí vamos a tener nuestra pantalla principal del juego donde tendremos dos spinner para escoger el nivel y la categoría (estos spinner los cargaremos con la data que tenga el archivo xml resource array). Nuestro activity xml sería así:

activity_main.XML


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="co.dstic.ahorcado.MainActivity">

    <LinearLayout
        android:padding="20dp"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/footer"
        android:orientation="vertical">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:text="Selecciona Nivel:"
            android:layout_marginBottom="5dp"/>

        <Spinner
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/nivel"
            android:layout_marginBottom="5dp" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:text="Selecciona Categoría:"
            android:layout_marginBottom="5dp"/>

        <Spinner
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/category"
            android:layout_marginBottom="5dp" />

        <ImageView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:contentDescription="fondo"
            android:scaleType="fitXY"
            android:src="@drawable/imagen" />
    </LinearLayout>

    <LinearLayout
        android:orientation="vertical"
        android:layout_centerInParent="true"
        android:id="@+id/footer"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true">

        <Button
            android:id="@+id/start"
            android:text="Iniciar Juego"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:onClick="Navegar"
            android:background="@drawable/boton"
            android:layout_marginBottom="5dp"
            android:textColor="#ffffff"
            android:textStyle="bold" />
        <Button
            android:id="@+id/score"
            android:text="Puntaje"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:onClick="Navegar"
            android:background="@drawable/boton"
            android:layout_marginBottom="5dp"
            android:textColor="#ffffff"
            android:textStyle="bold" />
    </LinearLayout>
</RelativeLayout>

MainActivity.JAVA


import android.content.Context;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.*;

public class MainActivity extends AppCompatActivity {

    String[] categorys;
    String[] descriptionCategorys;
    String[] levels;
    String[] descriptionLevels;
    Spinner categorySpinner, levelSpinner;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        categorys = this.getResources().getStringArray(R.array.categoria);
        descriptionCategorys = this.getResources().getStringArray(R.array.descripcioncategoria);
        levels = this.getResources().getStringArray(R.array.nivel);
        descriptionLevels = this.getResources().getStringArray(R.array.descripcionnivel);
        categorySpinner = (Spinner)findViewById(R.id.category);
        levelSpinner = (Spinner)findViewById(R.id.nivel);
        categorySpinner.setAdapter(new SpinnerAdapter(this, R.layout.custom_spinner, categorys));
        levelSpinner.setAdapter(new SpinnerAdapter2(this, R.layout.custom_spinner, levels));
    }

    public void Navegar(View v)
    {
        switch(v.getId()) {
            case R.id.start:
                Intent i = new Intent(MainActivity.this, GameActivity.class);
                i.putExtra("categoria", categorySpinner.getSelectedItem().toString());
                i.putExtra("nivel", levelSpinner.getSelectedItem().toString());
                startActivity(i);
                break;
            case R.id.score:
                Intent i2 = new Intent(MainActivity.this, ScoreActivity.class);
                startActivity(i2);
                break;
        }
    }

    public class SpinnerAdapter extends ArrayAdapter
    {

        public SpinnerAdapter(Context context, int textViewResourceId, String[] objects)
        {
            super(context, textViewResourceId, objects);
        }


        @Override
        public View getDropDownView(int position, View convertView,ViewGroup parent)
        {
            return getCustomView(position, convertView, parent);
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent)
        {
            return getCustomView(position, convertView, parent);
        }

        public View getCustomView(int position, View convertView, ViewGroup parent)
        {
            LayoutInflater inflater=getLayoutInflater();
            View row=inflater.inflate(R.layout.custom_spinner, parent, false);
            TextView label=(TextView)row.findViewById(R.id.txt1);
            label.setText(categorys[position]);
            TextView sub=(TextView)row.findViewById(R.id.txt2);
            sub.setText(descriptionCategorys[position]);
            return row;
        }
    }

    public class SpinnerAdapter2 extends ArrayAdapter
    {

        public SpinnerAdapter2(Context context, int textViewResourceId, String[] objects)
        {
            super(context, textViewResourceId, objects);
        }


        @Override
        public View getDropDownView(int position, View convertView,ViewGroup parent)
        {
            return getCustomView(position, convertView, parent);
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent)
        {
            return getCustomView(position, convertView, parent);
        }

        public View getCustomView(int position, View convertView, ViewGroup parent)
        {
            LayoutInflater inflater=getLayoutInflater();
            View row=inflater.inflate(R.layout.custom_spinner, parent, false);
            TextView label=(TextView)row.findViewById(R.id.txt1);
            label.setText(levels[position]);
            TextView sub=(TextView)row.findViewById(R.id.txt2);
            sub.setText(descriptionLevels[position]);
            return row;
        }
    }
}

Aquí declaramos arrays para las categorías, palabras, niveles, y las descripcion de niveles (todos estos están en el archivo xml array resource), en el método onCreate asignamos a cada array con su correspondiente valor del archivo xml y a los spinner los cargamos cada array(el de niveles y categorías) y como son personalizados le pasamos los parámetros de la clase ArrayAdapter personalizada y el layout xml personalizado: custom_spinner.xml para finalmente asignarle los valores desde el array hasta los TextView de dicho layout. También tenemos elñ método para abrir el activity del juego (le pasamos como parámetro la categoría y el nivel que este seleccionado de los spinner) y el de los puntos

Ahora creamos un nuevo activity donde se desarrollará el juego.

activity_game.xml


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="co.dstic.ahorcado.GameActivity"
    android:background="#ffffff">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/footer"
        android:orientation="vertical">

        <TableLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <TableRow
                android:layout_width="match_parent"
                android:layout_height="match_parent">

                <LinearLayout
                    android:orientation="vertical"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent">

                    <LinearLayout
                        android:orientation="horizontal"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginBottom="5dp">
                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:textAppearance="?android:attr/textAppearanceLarge"
                            android:text="Categoría"
                            android:textColor="#ef4444"
                            android:textStyle="bold"
                            android:layout_marginRight="10dp" />
                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:textAppearance="?android:attr/textAppearanceLarge"
                            android:text=""
                            android:id="@+id/txtCategoria" />
                    </LinearLayout>
                    <LinearLayout
                        android:orientation="horizontal"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginBottom="5dp">
                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:textAppearance="?android:attr/textAppearanceLarge"
                            android:text="Puntaje"
                            android:layout_gravity="right"
                            android:textStyle="bold"
                            android:textColor="#ef4444"
                            android:layout_marginRight="10dp" />
                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:textAppearance="?android:attr/textAppearanceLarge"
                            android:text="0"
                            android:id="@+id/txtPuntaje"
                            android:layout_gravity="right" />
                    </LinearLayout>
                    <LinearLayout
                        android:orientation="horizontal"
                        android:layout_width="match_parent"
                        android:layout_height="wrap_content"
                        android:layout_marginBottom="5dp">
                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:textAppearance="?android:attr/textAppearanceLarge"
                            android:text="Intentos"
                            android:layout_gravity="right"
                            android:textColor="#ef4444"
                            android:textStyle="bold"
                            android:layout_marginRight="10dp" />
                        <TextView
                            android:layout_width="wrap_content"
                            android:layout_height="wrap_content"
                            android:textAppearance="?android:attr/textAppearanceLarge"
                            android:text="4"
                            android:id="@+id/txtIntentos"
                            android:layout_gravity="right" />
                    </LinearLayout>
                </LinearLayout>
            </TableRow>

            <TableRow
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1">

                <ImageView
                        android:id="@+id/img"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:src="@drawable/ima1"
                    android:layout_marginBottom="5dp" />

            </TableRow>

            <TableRow
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:gravity="center">

                <LinearLayout
                    android:id="@+id/word"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:background="#FFFFFFFF"
                    android:orientation="horizontal"
                    android:padding="10dp"
                    android:gravity="center"
                    android:layout_gravity="center_horizontal" />
            </TableRow>
        </TableLayout>

    </LinearLayout>
    <LinearLayout
        android:id="@+id/footer"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:orientation="vertical">
        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:orientation="horizontal">
            <Button
                android:onClick="Verificar"
                android:layout_height="wrap_content"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:text="Q"
                android:background="@drawable/boton"
                android:textColor="#ffffff" />
            <Button
                android:onClick="Verificar"
                android:layout_height="wrap_content"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:text="W"
                android:background="@drawable/boton"
                android:textColor="#ffffff" />
            <Button
                android:onClick="Verificar"
                android:layout_height="wrap_content"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:text="E"
                android:background="@drawable/boton"
                android:textColor="#ffffff" />
            <Button
                android:onClick="Verificar"
                android:layout_height="wrap_content"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:text="R"
                android:background="@drawable/boton"
                android:textColor="#ffffff" />
            <Button
                android:onClick="Verificar"
                android:layout_height="wrap_content"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:text="T"
                android:background="@drawable/boton"
                android:textColor="#ffffff" />
            <Button
                android:onClick="Verificar"
                android:layout_height="wrap_content"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:text="Y"
                android:background="@drawable/boton"
                android:textColor="#ffffff" />
            <Button
                android:onClick="Verificar"
                android:layout_height="wrap_content"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:text="U"
                android:background="@drawable/boton"
                android:textColor="#ffffff" />
            <Button
                android:onClick="Verificar"
                android:layout_height="wrap_content"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:text="I"
                android:background="@drawable/boton"
                android:textColor="#ffffff" />
            <Button
                android:onClick="Verificar"
                android:layout_height="wrap_content"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:text="O"
                android:background="@drawable/boton"
                android:textColor="#ffffff" />
        </LinearLayout>
        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:orientation="horizontal">
            <Button
                android:onClick="Verificar"
                android:layout_height="wrap_content"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:text="A"
                android:background="@drawable/boton"
                android:textColor="#ffffff" />
            <Button
                android:onClick="Verificar"
                android:layout_height="wrap_content"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:text="S"
                android:background="@drawable/boton"
                android:textColor="#ffffff" />
            <Button
                android:onClick="Verificar"
                android:layout_height="wrap_content"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:text="D"
                android:background="@drawable/boton"
                android:textColor="#ffffff" />
            <Button
                android:onClick="Verificar"
                android:layout_height="wrap_content"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:text="F"
                android:background="@drawable/boton"
                android:textColor="#ffffff" />
            <Button
                android:onClick="Verificar"
                android:layout_height="wrap_content"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:text="G"
                android:background="@drawable/boton"
                android:textColor="#ffffff" />
            <Button
                android:onClick="Verificar"
                android:layout_height="wrap_content"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:text="H"
                android:background="@drawable/boton"
                android:textColor="#ffffff" />
            <Button
                android:onClick="Verificar"
                android:layout_height="wrap_content"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:text="J"
                android:background="@drawable/boton"
                android:textColor="#ffffff" />
            <Button
                android:onClick="Verificar"
                android:layout_height="wrap_content"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:text="K"
                android:background="@drawable/boton"
                android:textColor="#ffffff" />
            <Button
                android:onClick="Verificar"
                android:layout_height="wrap_content"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:text="L"
                android:background="@drawable/boton"
                android:textColor="#ffffff" />
        </LinearLayout>
        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:orientation="horizontal">
            <Button
                android:onClick="Verificar"
                android:layout_height="wrap_content"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:text="P"
                android:background="@drawable/boton"
                android:textColor="#ffffff" />
            <Button
                android:onClick="Verificar"
                android:layout_height="wrap_content"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:text="Ñ"
                android:background="@drawable/boton"
                android:textColor="#ffffff" />
            <Button
                android:onClick="Verificar"
                android:layout_height="wrap_content"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:text="Z"
                android:background="@drawable/boton"
                android:textColor="#ffffff" />
            <Button
                android:onClick="Verificar"
                android:layout_height="wrap_content"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:text="X"
                android:background="@drawable/boton"
                android:textColor="#ffffff" />
            <Button
                android:onClick="Verificar"
                android:layout_height="wrap_content"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:text="C"
                android:background="@drawable/boton"
                android:textColor="#ffffff" />
            <Button
                android:onClick="Verificar"
                android:layout_height="wrap_content"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:text="V"
                android:background="@drawable/boton"
                android:textColor="#ffffff" />
            <Button
                android:onClick="Verificar"
                android:layout_height="wrap_content"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:text="B"
                android:background="@drawable/boton"
                android:textColor="#ffffff" />
            <Button
                android:onClick="Verificar"
                android:layout_height="wrap_content"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:text="N"
                android:background="@drawable/boton"
                android:textColor="#ffffff" />
            <Button
                android:onClick="Verificar"
                android:layout_height="wrap_content"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:text="M"
                android:background="@drawable/boton"
                android:textColor="#ffffff" />
        </LinearLayout>
    </LinearLayout>
</RelativeLayout>

GameActivity.JAVA


import android.content.Context;
import android.media.MediaPlayer;
import android.os.Vibrator;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.TypedValue;
import android.view.View;
import android.widget.LinearLayout.LayoutParams;
import android.widget.*;
import java.util.ArrayList;
import java.util.Random;

public class GameActivity extends AppCompatActivity {

    MediaPlayer mp;
    int intentos = 4;
    int puntos = 0;
    int wordalength;
    String worda, CATEGORY, LEVEL;
    LinearLayout lyt, lytbtns;
    TextView txtPuntos, txtIntentos, txtCategoria;
    ImageView img;
    ArrayList<View> btns;
    Game gm;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_game);
        lyt = (LinearLayout)findViewById(R.id.word);
        lytbtns = (LinearLayout)findViewById(R.id.footer);
        txtPuntos = (TextView)findViewById(R.id.txtPuntaje);
        txtIntentos = (TextView)findViewById(R.id.txtIntentos);
        txtCategoria = (TextView)findViewById(R.id.txtCategoria);
        img = (ImageView)findViewById(R.id.img);
        btns = lytbtns.getTouchables();
        Bundle extras = getIntent().getExtras();
        CATEGORY = extras.getString("categoria");
        LEVEL = extras.getString("nivel");
        gm = new Game(this);
        Construye();
    }

    public void Verificar(View v)
    {
        Button b = (Button)v;
        String str = b.getText().toString();
        b.setEnabled(false);
        if(worda.contains(str))
        {
            for (int i = -1; (i = worda.indexOf(str, i + 1)) != -1; )
            {
                mp = MediaPlayer.create(this, R.raw.win);
                mp.start();
                TextView txt = (TextView) findViewById(i);
                txt.setText(str);
                wordalength--;
            }
            if(wordalength == 0)
            {
                Toast.makeText(this,"ganaste",Toast.LENGTH_LONG).show();
                Construye();
                puntos++;
                txtPuntos.setText(String.valueOf(puntos));
                gm.updateScore(String.valueOf(puntos), CATEGORY, LEVEL);
            }
        }
        else
        {
            intentos--;
            mp = MediaPlayer.create(this, R.raw.fail);
            mp.start();
            Vibrator vb = (Vibrator) getApplicationContext().getSystemService(Context.VIBRATOR_SERVICE);
            vb.vibrate(500);
            img.setImageDrawable(null);
            txtIntentos.setText(String.valueOf(intentos));
            if(LEVEL.equals("FÁCIL"))
            {
                switch (intentos)
                {
                    case 5:
                        img.setBackgroundResource(R.drawable.ima2);
                        break;
                    case 4:
                        img.setBackgroundResource(R.drawable.ima3);
                        break;
                    case 3:
                        img.setBackgroundResource(R.drawable.ima41);
                        break;
                    case 2:
                        img.setBackgroundResource(R.drawable.ima4);
                        break;
                    case 1:
                        img.setBackgroundResource(R.drawable.ima51);
                        break;
                    case 0:
                        img.setBackgroundResource(R.drawable.ima5);
                        Toast.makeText(this,"La palabra era: " + worda,Toast.LENGTH_LONG).show();
                        Construye();
                        break;
                }
            }
            else
            {
                switch (intentos)
                {
                    case 3:
                        img.setBackgroundResource(R.drawable.ima2);
                        break;
                    case 2:
                        img.setBackgroundResource(R.drawable.ima3);
                        break;
                    case 1:
                        img.setBackgroundResource(R.drawable.ima4);
                        break;
                    case 0:
                        img.setBackgroundResource(R.drawable.ima5);
                        Toast.makeText(this,"La palabra era: " + worda,Toast.LENGTH_LONG).show();
                        Construye();
                        break;
                }
            }
        }
    }

    void Construye()
    {
        if(LEVEL.equals("FÁCIL"))
        {
            intentos = 6;
            txtIntentos.setText("6");
        }
        else
        {
            intentos = 4;
            txtIntentos.setText("4");
        }
        txtCategoria.setText(CATEGORY);
        lyt.removeAllViews();
        img.setImageDrawable(null);
        img.setBackgroundResource(R.drawable.ima1);
        for(View touchable : btns)
        {
            if( touchable instanceof Button )
            {
                touchable.setEnabled(true);
            }
        }
        Random r = new Random();
        worda = gm.getWord(String.valueOf(r.nextInt(80)), CATEGORY);
        wordalength = worda.length();
        for(int i = 0; i < wordalength; i++)
        {
            TextView row = new TextView(this);
            row.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
            row.setId(i);
            row.setTextSize(TypedValue.COMPLEX_UNIT_SP, 30);
            row.setPadding(0, 0, 10, 0);
            row.setWidth(40);
            row.setBackgroundResource(R.drawable.borde);
            lyt.addView(row);
        }
    }
}

En este activity tenemos un ImageView donde pondremos la imagen del ahorcado según los intentos, un MediaPlayer para reproducir sonido (si falló o acertó), un ArrayList de Views (para los botones de las letras) y una objeto de la clase Game. En el método onCreate recuperamos los parámetros que nos envían desde el MainActivity (categoría y nivel) y los asignamos a sus rspectivas variables, instanciamos la clase Game y llamamos al método Construye que asigna los intentos según el valor que tenga la variable de nivel, la categoría la coloca en el TextView; también se encarga de quitar todo lo que contenga el LinearLayout word (que es donde se va a colocar la palabra letra por letra del juego), poner la imagen inicial del juego, habilitar todos los botones y finalmente generar la palabra con la función getWord de la clase Game pasandole un numero aleatorio del 0 al 79 para asignarla a la variable worda y asignarle el tamaño de esta a la variable wordalength para hacer el for y crear los TextView dinámicos de nuestra palabra que pondremos en el LinearLayout word.

Y tenemos un método Verificar que es el que es llamado por todos los botones donde recibimos el texto de ese boton presionado a través del parámetro View y preguntamos si la variable worda (que es la que tiene la palabra actual del juego) contiene ese texto (ósea la letra presionada), si es el caso entramos en un for para ver si dicha letra esta en la palabra una o más veces y por cada interacción accedemos al id del TextView de la palabra y le colocamos la letra para que el usuario vea que acertó y a la variable que tiene el tamaño de la palabra le dismuimos el valor en 1, preguntamos si esa variable es igual a cero (es decir ya el usuario acertó todas las letras) y le mostramos que ganó y actualizamos el puntaje con la función updateScore pasándole los puntos (aumentados), la categoría y el nivel actual. Si no es el caso debemos hacer lo correspondiente a cuando el usuario fallo con la letra presionada: disminuimos los intentos, hacemos sonar el fail más la vibración y preguntamos en que nivel se esta jugando para entrar en un switch-case y así mostrar la imagen correspondiente (Fácil: 6 intentos = 6 imágenes del ahorcado = más lento y Difícil: 4 intentos = 4 imágenes del ahorcado = más rápido), cuando lleguemos a la última imágen le notificamos que perdió, le mostramos la palabra que no pudo acertar y llamamos al método Construye para reiniciar el juego.

activity_score.XML


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="co.dstic.ahorcado.ScoreActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/footer"
        android:orientation="vertical">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceLarge"
            android:text="Puntuaciones"
            android:id="@+id/textView"
            android:layout_marginBottom="50dp"
            android:textSize="40sp"
            android:textColor="#ef4444"
            android:textStyle="bold" />

        <ListView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/lstPuntuaciones" />       

    </LinearLayout>

    <LinearLayout
        android:id="@+id/footer"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:orientation="vertical">
        <Button
            android:id="@+id/score"
            android:text="Regresar al Menú"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:onClick="Regresar"
            android:background="@drawable/boton"
            android:layout_marginBottom="5dp"
            android:textColor="#ffffff"
            android:textStyle="bold" />
    </LinearLayout>

</RelativeLayout>

ScoreActivity.JAVA


import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import java.util.ArrayList;

public class ScoreActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_score);
        ListView lstPuntuaciones = (ListView)findViewById(R.id.lstPuntuaciones);
        Game gm = new Game(this);
        ArrayList<String> results = gm.getScore();
        lstPuntuaciones.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, results));
    }

    public void Regresar(View v)
    {
        finish();
    }
}

Para terminar tenemos el activity donde vamos a mostrar el puntaje, para lograr eso creamos un objeto de la clase Game y declaramos un ArrayList para recuperar la información que nos envía la función getScore para finalmente ponerla en el adaptador de nuestro ListView que va a servir como vista de los puntajes.

Bueno eso es todo espero que les sirva mucho para aprender y practicar. les dejo una carpeta comprimida para que descarguen el ejemplo.

Todos los archivos de código están en el proyecto de descarga: imágenes usadas, resources para los botones customizados,etc.

Si te gustan mis tutoriales no dudes en seguirme en mis redes sociales para estar al tanto y suscribirte a mi canal de youtube.

Comentarios


genesis vargas

Soy Genesis Vargas Jiménez, autor de éste blog. Me gusta desarrollar software en todas las plataformas (web, móvil y desktop) y compartir conocimiento para ayudar a muchas personas.

Desde el 2015 soy MVP Microsoft en Visual Studio y tecnologías de desarrollo, reconocimiento que me enorgullece mucho.

MVP Genesis Vargas J

A PHP Error was encountered

Severity: Core Warning

Message: Module 'timezonedb' already loaded

Filename: Unknown

Line Number: 0

Backtrace: