Anuncios

Bienvenidos sean a este post, hoy nos dedicaremos pura y exclusivamente a ver como agregar unas opciones basicas para nuestro primer juego.

Anuncios

Para comenzar vamos a Android Studio, del panel del lado izquierdo iremos a la carpeta res y haremos click con el boton derecho y seleccionaremos New -> Android Resource File, esto nos abrira una nueva ventana la cual completaremos de la siguiente manera:

  • File name: preferencias (todo en minusculas)
  • Resource type: XML
  • Root Element: PreferenceScreen
  • Source set: main
  • Directory name: xml
Anuncios

Una vez seleccionado todos los valores de esta forma pulsen Ok para generar el nuevo archivo, con el nuevo archivo generado lo modificaremos de la siguiente manera:

preferencias.xml

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:key="preferencias_ppal" >

    <CheckBoxPreference
        android:key="depuracion"
        android:title="Habilitar Depuracion"
        android:summary="Habilita o deshabilita datos para la depuracion" />
    <CheckBoxPreference
        android:key="grilla"
        android:title="Habilitar Grilla"
        android:summary="Habilita o deshabilita datos para la grilla" />

</PreferenceScreen>
Anuncios
Anuncios

En este codigo tendremos dos opciones, una para habilitar o no los mensajes de depuracion y otro para ver la grilla o no, nuestro siguiente paso sera habilitar esta preferencia, y para ello debemos usar una actividad pero nuestro primer paso sera crear una nueva clase Java y para ello debemos ir a Java -> org.example.cazadordesub, hacen click con el boton derecho, elijan New -> Java Class, aparecera un nuevo cuadro y lo completaremos de la siguiente manera:

  • Nombre: Preferencias
  • Type: Class

El resto de los campos deben dejarlos en blanco o con la opcion predeterminada, con todo esto completado presionen Ok para cerrar la ventana y generar el nuevo archivo.

Anuncios

Una vez generado el archivo vamos a proceder a cambiar el codigo creado automaticamente con el siguiente:

Preferencias.java

package org.example.cazadordesub;

import android.os.Bundle;
import android.preference.PreferenceActivity;

public class Preferencias extends PreferenceActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.preferencias);
    }
}
Anuncios
Nota: Los paquetes necesarios los agregan a medida que escriben y tambien puede suceder que les notifique que este deshechado (deprecated) pero no se preocupen porque lo podran seguir usando... por lo menos por ahora.
Anuncios
Anuncios

En esta clase primero extenderemos a PreferenceActivity, luego agregaremos el metodo onCreate para cargar el codigo XML, para este caso usaremos a addPreferencesFromResource, en el cual pasaremos la ubicacion de nuestro archivo (R.xml.preferencias), con esto ya tenemos nuestra clase encargada de cargar el archivo XML generado para las preferencias, nuestro siguiente paso sera agregar la actividad en AndroidManifest.xml, para ello agregaremos el siguiente bloque dentro del bloque application:

        <activity android:name=".Preferencias"
            android:label="Preferencias del juego" />
Anuncios

Este bloque nos habilitara a la clase Preferencias como una actividad, el siguiente item sera para la etiqueta de identificacion, nuestro siguiente paso sera habilitar la actividad en MainActivity, para ello agregaremos las proximas modificaciones, primero agregaremos la siguiente funcion dentro de la clase:

    public void lanzarPreferencias(View view){
        Intent i = new Intent(this, Preferencias.class);
        startActivity(i);
    }
Anuncios

Con esta nueva funcion crearemos una intencion para nuestra nueva clase, Preferencias, lo siguiente es iniciar dicha intencion como una actividad, para nuestra siguiente modificacion la haremos en onCreate y agregaremos el siguiente bloque:

        Button botonP = (Button) findViewById(R.id.preferencias);
        botonP.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                lanzarPreferencias(null);
            }
        });
Anuncios
Anuncios

En este caso volvemos a crear un objeto de la clase Button y la relacionamos con el boton de las preferencias, nuestra accion es para utilizar el nuevo objeto con setOnClickListener y lo utilizamos para llamar a la funcion lanzarPreferencias, con esto tenemos creada las preferencias y las hemos habilitado para trabajar con ellas, ahora solo nos falta recuperar la informacion en las mismas, para ello haremos nuevas modificaciones, la primera de ella sera declarar nuevos objetos y variables al principio de la clase:

    boolean grilla;
    int alfa;
    SharedPreferences preferencias;
Anuncios

Las dos primeras variables son para controlar la aparicion de la grilla, el objeto sera el encargado de manejar nuestras preferencias, nuestra siguiente modificacion sera agregar esta linea en la funcion nuevo:

preferencias = PreferenceManager.getDefaultSharedPreferences(this);
Anuncios

Esta define al objeto que declaramos antes y nos permitira tener acceso al archivos de las preferencias predeterminadas, siguiendo dentro de la funcion nuevo modificaremos la definicion de depuracion de esta forma:

depuracion = preferencias.getBoolean("depuracion",false);
Anuncios

Con esto definiremos el valor para depuracion por medio del metodo getBoolean donde le diremos que busque a la preferencia con la clave (key) rotulada como depuracion, el segundo valor es el predeterminado en caso de no encontrar el anterior, aun en la funcion nuevo agregaremos la siguiente linea:

grilla = preferencias.getBoolean("grilla", false);
Anuncios

Al igual que en el caso anterior busca el valor rotulado como grilla y el valor predeterminado es false, nuestra siguiente modificacion sera en dibujar, para ello al principio agregaremos el siguiente condicional:

        if (grilla)
            alfa = 255;
        else
            alfa = 0;
Anuncios

Este se encargara de verificar el valor de grilla, en caso de ser true (verdadero) define al valor de alfa como 255, en caso contrario define a alfa como 0, nuestra siguiente modificacion sera cambiar esta linea:

pincel.setColor(Color.argb(255,0,0,0));

De la siguiente manera:

pincel.setColor(Color.argb(alfa,0,0,0));
Anuncios

Esta se encargara de pintar las lineas o no, si bien las mismas siguen existiendo al usar a alfa como 0 no las mostrara, nuestra siguiente modificacion sera agregar la siguiente linea antes de dibujar el cuadrado con canvas:

pincel.setColor(Color.argb(255,0,0,0));
Anuncios

Porque esta volvera a setear el alfa a maximo valor en pincel para poder dibujar, por ultimo en dibujar modificaremos el llamado a imprimirDebug de la siguiente forma:

        if (depuracion) {
            imprimirDebug();
        }
Anuncios

Este verifica si depuracion es igual a true, en caso de ser cierto llama a imprimirDebug de lo contrario no llama a ninguna funcion, por ultimo vamos a modificar imprimirDebug para mostrar los dos nuevos valores que agregamos, para ello al final del ultimo Log.d agreguen este bloque:

        canvas.drawText("grilla = " + grilla,
                50, tamBloque * 14, pincel);
        canvas.drawText("alfa = " + alfa,
                50, tamBloque * 15, pincel);
Anuncios

Con esto ya cubrimos todas las modificaciones de nuestro juego, antes de pasar a ver el resultado final veamos el codigo final de nuestra clase MainActivity:

package org.example.cazadordesub;

import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Point;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.Display;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

import java.util.Random;

public class MainActivity extends Activity {
    int numHorPixels;
    int numVerPixels;
    int tamBloque;
    int ancGrilla;
    int altGrilla;
    int vertTocado;
    int horizTocado;
    int subHorPosicion;
    int subVerPosicion;
    boolean impacto;
    int disparos;
    boolean depuracion;
    boolean grilla;
    int alfa;
    int distDesdeSub;
    Display vista;
    Point tamano;

    ImageView juegoVista;
    Bitmap bitmapBlanco;
    Canvas canvas;
    Paint pincel;

    SharedPreferences preferencias;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button botonI = (Button) findViewById(R.id.inicio);
        Button botonP = (Button) findViewById(R.id.preferencias);
        botonI.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                nuevo();
                dibujar();
            }
        });
        botonP.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                lanzarPreferencias(null);
            }
        });

        Log.d("Depurando","En el onCreate");
    }

    public void lanzarPreferencias(View view){
        Intent i = new Intent(this, Preferencias.class);
        startActivity(i);
    }

    void dibujar()
    {
        if (grilla)
            alfa = 255;
        else
            alfa = 0;
        bitmapBlanco = Bitmap.createBitmap(numHorPixels,
                numVerPixels, Bitmap.Config.ARGB_8888);
        canvas = new Canvas(bitmapBlanco);
        juegoVista = new ImageView(this);
        pincel = new Paint();
        setContentView(juegoVista);

        juegoVista.setImageBitmap(bitmapBlanco);
        canvas.drawColor(Color.argb(255,255,255,255));
        pincel.setColor(Color.argb(alfa,0,0,0));
        for(int i=0; i < altGrilla; i++) {
            canvas.drawLine(0, tamBloque * i,
                    numHorPixels - 1, tamBloque * i, pincel);
        }
        for(int i =0; i < ancGrilla; i++){
            canvas.drawLine(tamBloque * i,0,
                tamBloque * i, numVerPixels -1, pincel);
        }
        pincel.setColor(Color.argb(255,0,0,0));
        canvas.drawRect(horizTocado * tamBloque,
                vertTocado * tamBloque,
                (horizTocado * tamBloque) + tamBloque,
                (vertTocado * tamBloque) + tamBloque,
                pincel);

        pincel.setTextSize(tamBloque * 1.5f);
        pincel.setColor(Color.argb(255,0,0,255));
        canvas.drawText("Disparos realizados: " +
                disparos + " - Distancia del submarino: " +
                distDesdeSub, tamBloque, tamBloque * 1.75f, pincel);

        Log.d("Depurando","En el dibujar()");
        if (depuracion) {
            imprimirDebug();
        }
    }

    void nuevo()
    {
        vista = getWindowManager().getDefaultDisplay();
        preferencias = PreferenceManager.getDefaultSharedPreferences(this);
        tamano = new Point();
        vista.getSize(tamano);
        numHorPixels = tamano.x;
        numVerPixels = tamano.y;
        ancGrilla = 40;
        tamBloque = numHorPixels / ancGrilla;
        altGrilla = numVerPixels / tamBloque;
        disparos = 0;
        distDesdeSub = 0;
        impacto = false;
        depuracion = preferencias.getBoolean("depuracion",false);
        grilla = preferencias.getBoolean("grilla", false);
        Random alazar = new Random();
        subHorPosicion = alazar.nextInt(ancGrilla);
        subVerPosicion = alazar.nextInt(altGrilla);
        horizTocado = -100;
        vertTocado = -100;

        Log.d("Depurando","En el nuevo()");
    }

    void disparar(int x, int y) {
        disparos++;
        horizTocado = x / tamBloque;
        vertTocado = y / tamBloque;
        impacto = horizTocado == subHorPosicion
                && vertTocado == subVerPosicion;
        int horBrecha = horizTocado - subHorPosicion;
        int verBrecha = vertTocado - subVerPosicion;
        distDesdeSub = (int) Math.sqrt((horBrecha * horBrecha)
                + (verBrecha * verBrecha));
        if (impacto) {
            boom();
        }
        else {
            dibujar();
        }

        Log.d("Depurando","En el disparar()");
    }

    void boom()
    {
        juegoVista.setImageBitmap(bitmapBlanco);
        canvas.drawColor(Color.argb(255,255,0,0));
        pincel.setColor(Color.argb(255,255,255,255));
        pincel.setTextSize(tamBloque * 10);
        canvas.drawText("BOOM!", tamBloque * 4,
                tamBloque * 14, pincel);
        pincel.setTextSize(tamBloque * 2);
        canvas.drawText("Dispara para jugar de nuevo!",
                tamBloque * 8,
                tamBloque * 18, pincel);
        nuevo();

        Log.d("Depurando","Hizo Boom! Verdaderamente");
    }

    void imprimirDebug()
    {
        pincel.setTextSize(tamBloque);
        canvas.drawText("numHorPixels = " + numHorPixels,
                50, tamBloque * 3, pincel);
        canvas.drawText("numVerPixels = " + numVerPixels,
                50, tamBloque * 4, pincel);
        canvas.drawText("tamBloque = " + tamBloque,
                50, tamBloque * 5, pincel);
        canvas.drawText("ancGrilla = " + ancGrilla,
                50, tamBloque * 6, pincel);
        canvas.drawText("altGrilla = " + altGrilla,
                50, tamBloque * 7, pincel);
        canvas.drawText("subHorPosicion = " + subHorPosicion,
                50, tamBloque * 8, pincel);
        canvas.drawText("subVerPosicion = " + subVerPosicion,
                50, tamBloque * 9, pincel);
        canvas.drawText("horizTocado = " + horizTocado,
                50, tamBloque * 10, pincel);
        canvas.drawText("verTocado = " + vertTocado,
                50, tamBloque * 11, pincel);
        canvas.drawText("impacto = " + impacto,
                50, tamBloque * 12, pincel);
        canvas.drawText("depuracion = " + depuracion,
                50, tamBloque * 13, pincel);
        canvas.drawText("grilla = " + grilla,
                50, tamBloque * 14, pincel);
        canvas.drawText("alfa = " + alfa,
                50, tamBloque * 15, pincel);
    }

    @Override
    public boolean onTouchEvent(MotionEvent evento)
    {
        horizTocado = (int)evento.getX();
        vertTocado = (int)evento.getY();
        if ((evento.getAction() &
                MotionEvent.ACTION_MASK) == MotionEvent.ACTION_UP){
            disparar(horizTocado,vertTocado);
        }
        Log.d("Depurando","En el onTouchEvent");
        Log.d("Depurando","horizTocado: " + horizTocado);
        Log.d("Depurando","vertTocado: " + vertTocado);
        return true;
    }
}
Anuncios

Y este va a ser nuestro codigo final de AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="org.example.cazadordesub">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity"
            android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
            android:screenOrientation="landscape">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".Preferencias"
            android:label="Preferencias del juego" />
    </application>

</manifest>
Anuncios

Con esto hemos concluido todas nuestras modificaciones, veamos el siguiente video para entender mejor el concepto

Anuncios

Como pueden ver en el video no solamente tenemos todas las opciones funcionando correctamente sino que nuestro juego sigue trabajando de forma correcta, se puede mejorar mucho mas pero a este juego lo dejaremos hasta aca, por el momento, si desean experimentar y agregar mas elementos, por ejemplo un boton para volver al inicio, quedan en completa libertad, si desean saber mas sobre preferencias, actividades e intenciones les recomiendo mirar este post donde estan todos los posts del curso inicial de Android.

Anuncios

En resumen, hoy hemos visto como crear preferencias, todas las configuraciones necesarias, como crear una actividad en el manifiesto de Android, como crear la intencion para iniciar la actividad, y por ultimo como recuperar estos valores para nuestro juego, espero les haya sido util sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.

Anuncios

Tengo un Patreon donde podes acceder de manera exclusiva a material para este blog antes de ser publicado, sigue los pasos del link para saber como.

Tambien podes donar

Es para mantenimiento del sitio, gracias!

$1.00