jueves, 7 de junio de 2012

Estructura básica de un juego con AndEngine


Ahora explicare la estructura básica para el desarrollo con AndEngine. Primero que nada veamos uno a uno los métodos que son heredados desde BaseGameActivity.

Ya sabemos que primero hay que definir que nuestra clase herede de BaseGameActivity, ya que este es el corazón del juego. Esta clase contiene un engine para una activity y que se encarga de crear un SurfaceView que es donde el contenido  que se genere será dibujado.

Para cada BaseGameActivity existe un engine y para ir de un BaseGameActivity a otro debemos usar los Intents (que es la forma de llamar una activity desde otra, un ejemplo de esto es cuando una aplicación de android llama a la aplicación de la agenda para mostrar los contactos, eso es un intent).

Para visualizar mejor estos métodos veremos un código para que se pueda comprender un poco mejor.



public class AndEngineTest extends BaseGameActivity {
//Seteamos el tamaño de la pantalla
 private static final int CAMERA_WIDTH = 720;
 private static final int CAMERA_HEIGHT = 480;


//Instanciamos una camara
 private Camera mCamera;


//Este metodo se encarga de inicializar el Engine (Luego lo retorna)
 @Override
 public Engine onLoadEngine() {
//Creamos la camara con los datos de la pantalla
  this.mCamera = new Camera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
 //Retornamos el engine 
return new Engine(new EngineOptions(true, ScreenOrientation.LANDSCAPE, new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), this.mCamera));
 }


//Aca cargaremos los recursos necesarios para el juego como imágenes, sonidos, fuentes...
 @Override
 public void onLoadResources() {
 }


//Aca se preparan todos los objetos que entraran en el juego (o en este nivel por lo menos)
 @Override
 public Scene onLoadScene() {
  final Scene scene = new Scene(1);
  return scene;
 }


//Este método se ejecuta después que los métodos anteriores estén listos
 @Override
 public void onLoadComplete() {
}


onLoadEngine()  -> Este método se encarga de definir la cámara, además podemos verificar que los recursos del dispositivos cumplan los requerimientos de nuestra aplicación ente otras cosas.

onLoadResources()  -> Acá se encarga de designar y crear objetos bitmaps, textures, imágenes, audio, etc. En este método es que cargaremos todos los recursos que vayamos a utilizar en nuestra aplicación.

Scene onLoadScene()  ->  En este método lo que haremos es cargar todos nuestros recursos a la scene, aquí es donde se desarrollara el juego.

onLoadComplete()  ->  Este método se ejecuta después de que los 3 anteriores estén listos.

Algunos conceptos a manejar

Sprite : Los Sprites son todos los elementos que se van a utilizar en el juego como ser los personajes, enemigos, bloques, botones, etc. Existen dos tipos en esta libreria que son:
      - Sprite: Estas son  una imagen simple.
      - AnimatedSprite: Es un Sprite pero compuesto de imágenes, con estos podemos formar efectos gif.

Camera : Esta clase contiene el ancho y largo de la pantalla, la forma en la cual  trabajaremos LANDSCAPE para horizontal y PORTRAIT para trabajar en vertical, ademas de que podemos configurarla para que se adecue a cualquier pantalla ya sea de un smartphone o de una tablet.

Scene: La clase escena es como su nombre lo indica, el lugar donde colocaremos los sprites, y es donde se va a desplegar nuestra aplicación.

 BitMap : Es un mapa de bits que contiene las imagenes  que vayamos a utilizar, esta solo las contiene de forma abstracta, ya que la clase que veremos a continuacion es quien las proyecta sobre nuestra Scene.


Texture : Es la clase que contiene las imagenes, y estas pueden tomar una subdivision del BitMap pueden ser de dos tipos:
    - Normales : Que maneja un bitmap que contiene una sola imagen.(estas manejan las imagenes de la clase Sprite )
    - Tiled : Que maneja un bitmap que contiene dos o mas imagenes(estas manejan las imagenes de la clase AnimatedSprite ).

Engine : En si esta clase contiene a todas las mencionadas y es la principal.


AndEngine


Vamos a utilizar un framework llamado Andengine para facilitar la programación de algunos componentes.
Vamos a crear u nuevo proyecto con andengine.

Primero descargar andengine (andengine.jar) desde este enlace --> AndEngine

Ahora creamos un nuevo proyecto

luego creamos una carpeta en la raíz del proyecto de nombre lib



luego copiamos el archivo AndEngine.jar a la carpeta lib



Con esto listo le damos con el botón derecho a andengine.jar (que e encuentra en la carpta lib) y seleccionamos Build path --> Add to build path.

Con esto ya tenemos referenciado al proyecto AndEngine.

Ahora nos queda ir  al archivo Main.java y cambiamos Activity por BaseGameActivity. Eliminamos el constructor, organizamos los imports, implementamos los métodos de BaseGameActivity y nos queda algo como esto.


package com.pruebas.andengine;

import org.anddev.andengine.engine.Engine;
import org.anddev.andengine.entity.scene.Scene;
import org.anddev.andengine.ui.activity.BaseGameActivity;
import android.os.Bundle;

public class Main extends BaseGameActivity {
 @Override
 public void onLoadComplete() {
  // TODO Auto-generated method stub
   
 }

 @Override
 public Engine onLoadEngine() {
  // TODO Auto-generated method stub
  return null;
 }

 @Override
 public void onLoadResources() {
  // TODO Auto-generated method stub
   
 }

 @Override
 public Scene onLoadScene() {
  // TODO Auto-generated method stub
  return null;
 }
}



Estamos listos para comenzar a desarrollar con el motor AndEngine.



Luego un ejemplo =)















lunes, 9 de abril de 2012

CREANDO UN MENU DE PREFERENCIAS


Para crear un menú de preferencias lo primero que tenemos que hacer es crear una carpeta en la /values/xml y dentro crear un archivo xml del tipo preference con el nombre settings.xml (hacemos esto para conseguir la persistencia necesaria para la aplicación, ya que al ser del tipo preferecnce quedan automáticamente guardados en el dispositivo donde podremos acceder fácilmente si es que se desea)

El archivo settings.xml contendrá lo sgte.

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
     android:key="preferencias_principal">
   
   
    <CheckBoxPreference
        android:key="musica"
        android:title="Reproducir música"
        android:summary="Se reproduce la música de fondo" />
   
    <ListPreference
        android:key="graficos"
        android:title="Tipo de Gráficos"
        android:summary="Se escoge la representación de gráficos"
        android:entries="@array/tiposGraficos"
        android:entryValues="@array/tiposGraficosValores"
        android:defaultValue="1"/>
   
</PreferenceScreen>


Además creamos un archivo xml en la carpeta values llamado arrays.xml que contiene lo siguiente.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="tiposGraficos">
        <item>vectorial</item>
        <item>bitmap</item>
        <item>3D</item>      
    </string-array>
   
    <string-array name="tiposGraficosValores">
        <item>0</item>
        <item>1</item>
        <item>2</item>      
    </string-array>
</resources>


Esto es lo que contiene la lista de preferencias de el archivo de preferencias, primero contiene el item y luego sus valores.

Ahora creamos su respectiva clase para esta activity que contendrá lo siguiente.


package org.videojuego.juego;

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.settings);

}

}


Ahora solo nos queda registrar esta activity en el AndroidManifest.xml. añadimos los siguiente.


        <!-- Activity correspondiente a la pantalla de Preferencias -->
        <activity
            android:name=".Preferencias"
            android:label="Preferencias" >
        </activity>

Con esto ya deberíamos tener listo el menú, solo nos quedaría empezar con la parte gráfica del juego.

VAMOS A CREAR UNA ACTIVITY QUE SERA LANZADA DESDE NUESTRO ACTIVITY PRINCIPAL


Vamos a crear el activity para el botón "Acerca de..". Eso lo hacemos creando un archivo xml en la carpeta /layout/acercade.xml al igual que nuestra activity principal main.xml. Este archivo acercade.xml contrendrá lo siguiente...

<?xml version="1.0" encoding="utf-8"?>
    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/contenidoAcercaDe" />



Esto solo mostrara un texto por pantalla que esta contenido en el archivo strings.xml con el titulo de contenidoAcercaDe.

Ahora nos toca editar el contenido de Juego.java (va a ser lo primero que vamos a programar, fuera de el aspecto visual) vamos  a crear un boton que sera nuestro boton acerca de, vamos a explciar el metodo onCreate que se debe instanciar siempre que se ejectua un activity y se hereda de la lcase Activity. Y dentro de este metodo vamos a crear un lsitener para este nuevo boton que va a estar pendiente cuando se hace un click sobre este que llamara a un metodo lanzarAcercaDe que sera el que llame a la activity correspondiente y la muertre por pantalla. esto quedaria asi..
package org.videojuego.juego;



//Con el ctrl+shift+o se hacen los imports  automáticamente cuando se necesiten
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

//Esta es la clase principal y extiende de Activity
public class Juego extends Activity {

//Creamos un botón para el AcercaDe
public Button btnAcercaDe;

//Método que se crea cuando se lanza la activity, y se hereda de la clase Activity
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
       
       btnAcercaDe=(Button) findViewById(R.id.Button3);
       //Creamos un listener que escuche siempre a ese boton y cuando se presione lanzamos la activity
       btnAcercaDe.setOnClickListener(new OnClickListener() {
      public void onClick(View view) {
// TODO Auto-generated method stub
lanzarAcercaDe();
      }
       });
     
     
    }
   
    //Método que lanza la activity AcercaDe
    public void lanzarAcercaDe()
    {
    Intent i = new Intent(this, AcercaDe.class);
    startActivity(i);
    }
   
}

Ahora debemos crear una clase AcercaDe.java que sera la que sera lanzada por el método AcercaDe() de la clase Juego.java y contendrá lo siguiente..

package org.videojuego.juego;

import android.app.Activity;
import android.os.Bundle;

public class AcercaDe extends Activity{

@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.acercade);

}
}

Esto solamente lanza el acerca de por pantalla.

Ahora solo nos queda registra la activity en nuestro AndroidManifest.xml. Este es el archivo principal de la aplicación, ya que acá contiene todas las características de la aplicación propiamente tal y acá debemos registrar todos los activitys que contiene la aplicación con sus características principales.

Este archivo seria de la siguiente manera.


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="org.videojuego.juego"
    android:versionCode="1"
    android:versionName="1.0" >

    <!-- La versión mínima en la que se puede usar la aplicación -->
    <uses-sdk android:minSdkVersion="7" />

   
    <!-- Se define la aplicación, sus atributos y las activitys que contenga la aplicación  -->
    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
       
        <!-- Activity principal -->
        <activity
            android:name=".Juego"
            android:label="@string/app_name" >
       
            <!-- Acá nos dice que esta activity se lanza desde el MAIN -->
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
       
        <!-- Activity correspondiente a la pantalla de AcercaDe -->
        <activity
            android:name=".AcercaDe"
            android:label="Acerca de ..."
            android:theme="@android:style/Theme.Dialog" > <!-- Si no ponemos esta linea se presenta como una pantalla negra nada mas, pero con este estilo se ve como un texto emergente -->
        </activity>
       
    </application>

</manifest>


Ahora solo nos queda hacer el debug de la aplicación y podremos ver el funcionamiento de el botón Acerca de...
Al igual que el botón acercaDe  también podremos crear el boton salir, pero en vez de lanzar una activity, lanza un finish(); esto lo que hace es dejar el programa pausado en segundo plano hasta que este sea llamado nuevamente.

Pronto capturas .-

VAMOS A CREAR UN MENU


Para empezar el proyecto de crear un juego para androidd tenemos que crear un nuevo  proyecto con los siguientes datos.

Project name: Juego (Pueden poner el nombre que quieran)
Build target: Android 2.1 (pueden escojer el que queiran, yo escogi este solo por el hecho de que desde android 2,1 hacia arriba esta soportado el multitouch)
Aplication name: Aplicacion
Package name: org.videojuego.juego
Create activity: Juego
Min SDk Verrsion : 7 (la versión mínima que la aplicación puede funcionar)

-----------------------------------------------------------------------------------------------------------

Para crear un menú lo primero que tenemos que hacer es crear en la ruta /res/layout/main.xml, esta seria la activity principal de la aplicación, este consiste en un  archivo XML que al hacer doble click en ella, nos aparecen 2 pestañas, en la primera (Graphical Layout) una forma gráfica de crear el layout, acá podemos usar drag and drop para crear una interfaz y en la segunda pestaña (main.xml) esta la forma de crearlo pero usando codigo xml. Para crear esta interfaz, primero debemos tener un Layout del tipo LinearLayout, esto significa que se pueden poner los elementos (views) de forma de una lista de elementos, osea uno abajo de otro o uno al lado de otro (dependiendo si escogemos LinearLayout Vertical o LinearLayout Horizontal. Luego Ponemos un text view y 4 botones. Pondré el código xml y luego explicare lo que significa alguna de sus características.

Este es el encabezado clásico de xml
<?xml version="1.0" encoding="utf-8"?>

Empezamos con un linear layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"          Su ancho llenara la pantalla
    android:layout_height="fill_parent"         Su alto llenara la pantalla
    android:orientation="vertical"                 La orientación es vertical
    android:gravity="center"                        Sus elementos se encontraran el el centro
    android:padding="30dip">                    La posición sera 30 dip (independiente del tamaño de la pantalla)


    Luego viene un textview
    <TextView
        android:layout_width="fill_parent"                 Su ancho cubre la pantalla
        android:layout_height="wrap_content"          Pero su alto se adapta al contenido de este
        android:text="@string/tituloAplicacion"         Lo que dirá este textview esta contenido en Strings.xml en la carpeta /res/values y su nombre sera titulo Aplicación
        android:gravity="center"                               Su posición sera centrado
        android:textSize="25sp"                               El tamaño del texto sera 25sp (independiente del tamaño de pantallaa)
        android:layout_marginBottom="20dip" />     El tamaño del textview sera de 20dip (independiente del tipo de pantalla)
 

    Ahora continuamos con un boton
    <Button android:id="@+id/Button1"                 El id del botón dera Button1
        android:layout_height="wrap_content"         Su alto se adapta al contenido de este
        android:layout_width="fill_parent"                Pero su ancho se adapta al ancho de la pantalla
        android:text="@string/Arrancar"/>               Y lo que dice este botón se encontrara en Strings.xml al igual que el textview
 
Los siguientes botones se crean igual que el Button1
    <Button android:id="@+id/Button2"
        android:layout_height="wrap_content"
        android:layout_width="fill_parent"
        android:text="@string/Configurar"/>
 
    <Button android:id="@+id/Button3"
        android:layout_height="wrap_content"
        android:layout_width="fill_parent"
        android:text="@string/Acercade"/>
 
    <Button android:id="@+id/Button4"
        android:layout_height="wrap_content"
        android:layout_width="fill_parent"
        android:text="@string/Salir"/>

</LinearLayout>


El archivo /res/strings.xml se tiene q ver de esta manera.

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">Juego</string>
    <string name="Arrancar">Jugar</string>
    <string name="Configurar">Configurar</string>
    <string name="Acercade">Acerca de</string>
    <string name="Salir">Salir</string>
    <string name="tituloAplicacion">Prueba de titulo</string>
    <string name="contenidoAcercaDe">Esta es una prueba de como se ve un activity de una pantalla de Acerca de..</string>

</resources>


En este archivo strings.xml  contendrá todos los textos de la aplicación, para que se hace esto, para que cuando se tenga q cambiar un texto, este no se tenga que buscar en el código propiamente tal de la aplicación. Veremos que esto es una gran ventaja, ya que podremos crear un archivo llamado strings-en.xml con el mismo aspecto que strings.xml pero con los textos subtitulados y andorid  automáticamente selecciona este archivo si es que el idioma del dispositivo se encuentra en ingles.

Además podemos de igual forma con una archivo alternativo como en ele caso de strings.xml y strings-en.xml podemos crear una carpeta /layout-land/main.xml con las características que tendrá la aplicación si es que esta se pone de forma horizontal, esta es una gran ventaja, ya que separamos totalmente el diseño de la aplicación del código de esta, así ocupando otro xml podemos manejar la aplicación de manera vertical y horizontal sin tocar nada del código.


Pronto capturas .-