lunes, 21 de marzo de 2011

Introducción a AndEngine (Parte I)

Qué es AndEngine

AndEngine es un Engine 2d usando Opengl para juegos para la plataforma Android.

En AndEngine se usa una terminología propia, explico aquí los conceptos más básicos

  • BaseGameActivity: El BaseGameActivity es la raiz del juego, que contiene el motor y crea la vista donde se va a dibujar todo. Hay siempre exactamente un solo Engine por cada BaseGameActivity.
  • Engine: El Engine es el motor interno del juego, se encarga de ir dibujando en pantalla y actualizando objetos en la escena, que contiene todo el contenido que tu juego lleva. Normalmente hay una escena por por Engine, a menos que vayas a usar un SplitScreenEngines.
  • IResolutionPolicy: Una implementacion de IResolutionPolicy interface es parte del EngineOptions. Te hace abstraerte de la resolución del terminal, tú trabajas para una resolución y el AndEngine se encarga del resto.
  • Camera: Un objeto Camera define el rectangulo visible actualmente de la escena actual, no tiene porqué ser la escena completa. Normalmente hay una cámara por escena. Hay subclases específicas que permiten hacer zoom y mover la cámara suavemente.
  • Scene: La clase Scene es el contenedor para todos los objetos que se van a dibujar en la escena. Una escena puede tener Layers, que son capas para ordenar objetos. Hay subclases de la Scene como CameraScene/HUD/MenuScene que tienen comportamientos específicos.
  • Entity: Una entidad es un objeto que puede ser dibujado, como Imagenes, rectángulos, Texto, Líneas. Una entidad tiene posición/rotación/zoom/color...
  • Texture: Una textura es una imagen que se guarda en memoria. En Android, las imágenes deben ser una potencia de 2.
  • ITextureSource: Una implementacion de ITextureSource-interface se encarga de cargar una imagen en una posición en la textura.
  • TextureRegion: Una TextureRegion define un rectangulo en una imagen. Las TextureRegion se usan por Sprites para usar una imagen grande en la que guardamos muchas imagenes pequeñicas.
  • PhysicsConnector: Motor de físicas integrado en el Engine

Obteniendo AndEngine


Para obtener andEngine, puedes bajar los fuentes de su página y también puedes bajar un jar preparadito, que es lo que yo he usado para esta introducción.


Primero bajamos este archivo y lo guardamos en el equipo.


Creación del proyecto en Eclipse


Comenzamos como siempre File -> New Project.




Siguiente y Finish. Ahora creamos una carpeta lib en la raiz del proyecto




Ahora arrastramos el archivo descargado a la carpeta lib de eclipse. Se queda algo así.



Ahora botón derecho en el archivo andengine.jar y le damos a Build Path -> Add to Build Path.



Ahora vamos 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;
 }
}

Ahora cambiamos un poco la estructura del archivo para que se vea todo un poco más claro


package com.pruebas.andengine;

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

public class Main extends BaseGameActivity {
 // ===========================================================
 // Constants
 // ===========================================================
 
 // ===========================================================
 // Fields
 // ===========================================================
 
 // ===========================================================
 // Constructors
 // ===========================================================

 // ===========================================================
 // Getter & Setter
 // ===========================================================

 // ===========================================================
 // Methods for/from SuperClass/Interfaces
 // ===========================================================
 
 @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;
 }
 
 // ===========================================================
 // Methods
 // ===========================================================

 // ===========================================================
 // Inner and Anonymous Classes
 // =========================================================== 
}

Empezando


Ahora vamos a crear una cámara necesaria para el funcionamiento del juego. Creamos variables para definir sobre que resolucion vamos a trabajar y una variable para el TAG que vamos a usar para los mensajes de Log


 // ===========================================================
 // Constants
 // ===========================================================
 static final int CAMERA_WIDTH = 480;
 static final int CAMERA_HEIGHT = 320;
 
 private static final String TAG = "AndEngineTest";

 // ===========================================================
 // Fields
 // ===========================================================
 
 private ZoomCamera mCamera;

Ahora implementamos el procedimiento onLoadEngine()


 @Override
 public Engine onLoadEngine() {
  this.mCamera = new ZoomCamera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
  return new Engine(new EngineOptions(true, ScreenOrientation.LANDSCAPE, new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), this.mCamera));
 }

Así definimos la cámara, esencial para poder ver algo. Ahora implementamos el procedimiento onLoadScene() y le ponemos un color de fondo.



       @Override
        public Scene onLoadScene() {
                this.mEngine.registerUpdateHandler(new FPSLogger());

                final Scene scene = new Scene(1);
                scene.setBackground(new ColorBackground(0, 0, 0.8784f));
 
                return scene;
        }

Después de organizar los imports y dejarlo todo bonico nos queda así:


package com.pruebas.andengine;

import org.anddev.andengine.engine.Engine;
import org.anddev.andengine.engine.camera.ZoomCamera;
import org.anddev.andengine.engine.options.EngineOptions;
import org.anddev.andengine.engine.options.EngineOptions.ScreenOrientation;
import org.anddev.andengine.engine.options.resolutionpolicy.RatioResolutionPolicy;
import org.anddev.andengine.entity.scene.Scene;
import org.anddev.andengine.entity.scene.background.ColorBackground;
import org.anddev.andengine.entity.util.FPSLogger;
import org.anddev.andengine.ui.activity.BaseGameActivity;

public class Main extends BaseGameActivity {
 // ===========================================================
 // Constants
 // ===========================================================
 static final int CAMERA_WIDTH = 480;
 static final int CAMERA_HEIGHT = 320;
 
 private static final String TAG = "AndEngineTest";
 
 
 // ===========================================================
 // Fields
 // ===========================================================
 
 private ZoomCamera mCamera;
 
 // ===========================================================
 // Constructors
 // ===========================================================

 // ===========================================================
 // Getter & Setter
 // ===========================================================

 // ===========================================================
 // Methods for/from SuperClass/Interfaces
 // ===========================================================
 
 @Override
 public void onLoadComplete() {
  // TODO Auto-generated method stub
  
 }

 @Override
 public Engine onLoadEngine() {
  this.mCamera = new ZoomCamera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);
  return new Engine(new EngineOptions(true, ScreenOrientation.LANDSCAPE, new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT), this.mCamera));
 }

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

 @Override
 public Scene onLoadScene() {
  this.mEngine.registerUpdateHandler(new FPSLogger());

        final Scene scene = new Scene(1);
        scene.setBackground(new ColorBackground(0, 0, 0.8784f));

        return scene;
 }
 
 // ===========================================================
 // Methods
 // ===========================================================

 // ===========================================================
 // Inner and Anonymous Classes
 // =========================================================== 
}



Ahora vamos a arrancar la aplicación para ver un color de fondo. Vamos a run Configurations





Apply -> Run y ya podemos ver en nuestro terminal nuestro primer programa con AndEngine.



Con esto termina la primera parte del tutorial, en la segunda entrega el objetivo es pintar objetos en pantalla, definir una escena mayor que lo que se puede ver en pantalla y moverse por la pantalla con TouchEvents

34 comentarios:

DarkKaiser dijo...

¡Muchísimas gracias! ¡Ánimo, sigue así!
Estoy pensando en hacer un juego como trabajo de fin de curso y llevo semanas investigando andengine, parece muy bueno pero la falta de documentación dificulta mucho el aprendizaje... Hay que ir consultando ejemplos y comentarios del foro..

Este primer tutorial de introducción me ha aclarado muchas cosas a pesar de su sencillez, mañana pondré en práctica el segundo. Seguiré todos tus avances.

El juego que planeo hacer es el típico plataformas que avanzas hacia la derecha y eliminas enemigos disparando.

Creo que puedo aprender mucho de tus tutoriales. Te animo a que continúes ^^

Angel dijo...

Gracias por el comentario, el primer comentario del blog jeje.

Si, el framework está muy bien, pero cuesta encontrar documentación, sobre todo en castellano.

En principio, las primeras fases del tutorial serán sencillas e iré subiendo en dificultad conforme llegue a donde quiero llegar, que es hacer el juego completo.

Un saludo ;)

soy_ismael dijo...

Muchas gracias por tu esfuerzo! Muy bien explicado.

Saludos,
Ismael.

Smallpawn dijo...

Felicidades y gracias. Me están siendo de mucha ayuda tus tutoriales.

andres dijo...

Hola,

Me encanto el tutorial..
Queria agradecerte.. se comprende perfectamente..
Pero a la hora de intentar utilizarlo me tira el siguiente error:
[2011-05-02 16:25:05 - AndEngineTest] Error generating final archive: Found duplicate file for APK: AndroidManifest.xml
Origin 1: _
Origin 2: C:\MOTODEV_Andres\AndEngineTest\lib\andengine.jar


No comprendo cual es el problema?
dejo la duda quizás alguien supo como solucionarlo..

jordi dijo...

Yo tengo el mismo error de manifiesto duplicado y nho encuentro solucion

Angel dijo...

Baja los fuentes de aqui y prueba con estos. Con esos fuentes va seguro.

svn checkout http://ch-soccer.googlecode.com/svn/trunk/ tutorial-read-only -r 3

jordi dijo...

pues agradezco tu rápida respuesta pero me deja un poco desorientado. No se bien que hacer y donde aplicar esta linea que me das.

Angel dijo...

Hola Jordi, svn es un ejecutable de subversion, lo puedes bajar de su página: http://subversion.tigris.org/

Con ese programa, en un la linea de comandos, poniendo eso que he puesto te bajas los fuentes del primer tutorial, mira algo de informacion en internet acerca del uso de subversion si no te aclaras.

Un saludo.

jordi dijo...

No me aclaro pero me temo que pude haber cometido algún error en la instalación de eclipse porque tengo problemas con javaHL. Se lo que sea he decidido que voy hacer borrón y cuenta nueva. Así que estoy apunto de recuperar el sistema y solo instalar lo necesario para desarrollar. Gracias por la ayuda.

andres dijo...

TRANQUILOS,
El problema es la libreria que importan, que pasa el .jar tiene dentro un manifest; que se superpone con el de nuestro proyecto.
Yo lo resolvi bajando nuevamente la librería pero desde otro lado y funciona bien.
No recuerdo de donde la baje.
saludos

jordi dijo...

He conseguido que funcione, pero he tenido que quitar los @Override de las funciones para que me deje compilar. No se si asi vale o lo tengo que corregir de alguna manera.

jordi dijo...

Soy mu feliz viendo la pelota. Gracias.

The Dark Side of Me dijo...

disculpa que te moleste... no puedo descargar el andengine de 1.5 mb de el link que pones... podrias subirlo a mediafire o algun otro servidor por favor...
desde ya muchas gracias

Anael dijo...

Oye cuando voy a mover la pantalla sale un error inesperado forzar cierre? Que sera?

Menti dijo...

Hola buenas, mi programa esta clavado al tuyo, (porque tambien hice un copy/paste al ver que no funcionaba) y la pantalla se queda en Gris, con el titulo del programa, pero en Gris, ni se ve ese color azul, ni la pelotita que deberia verse en el tutorial numero dos. Sabras porque es?

Javier Umbe dijo...

Muy buen trabajo!! te felicito por la labor que estás haciendo de verdad, llevo varias semanas haciendo cosas e investigando sobre AndEngine, pero estaba muy limitado por la poca información que hay, y sobre todo, como dices, en castellano. Voy a seguir tus tutoriales, para aprender más, y seguro que me ayudará, desde aquí te animo a que sigas con este magnífico trabajo y no lo abandones, gracias!!

Eugenio dijo...

Hola!! muchas gracias por este trabajo! pero tengo un problema, copio el codigo igual que esta y me sale un error compilando esta linea
final Scene scene = new Scene(1);

me dice que el metodo Scene(int) no esta definido, alguien sabe porque puede ser??

muchas gracias!

Eugenio dijo...

Consegui arreglarlo era problema de que el andEngine.jar no estaba bien, probe con otro que si funciona, y esto va sin problemas. Muchas gracias por su trabajo.

zhonnetiks dijo...

He intentado bajarme el el AndEngine en formato .jar del enlace que pusiste pero no va; he dado con este http://wiki.andengine.org/Getting_And_Updating_AndEngine y me va de lujo.

Perfecto el tutorial para adentrarse en la materia ;)

Teniente Fray dijo...

Hola, yo tengo un problema. Os digo lo que utilizo porque no se si esa es la razón del fallo: Mac OS X 10.6 y Eclipse 3.6 con todos los paquetes de Android correctamente instalados y el jar de andengine (la última versión también instalada). El código, sin ningún error, no me ejecuta en el simulador (ya sea versión 1.6, 2.2, cualquiera...) ya que al ejecutarla me dice que esta aplicación necesita forzar su cierre. ¿Le ha pasado esto a alguien más? Tampoco me funciona el código de ejemplo de Nicolas, me da el mismo problema.
Por cierto, muchísimas gracias por el tutorial! Si consigo que me funcione esto sacaré mi PFC a través de andengine, jeje.

Teniente Fray dijo...

Ok, ya lo he resuelto. Era un problema con el manifest!! jeje XD

De verdad que muchas gracias por el aporte de la página, da gusto encontrarse las cosas así.

LocalBurn dijo...

Hola,
no se porque no puedo instalar el andengine al eclipse.
Alguien me podria hacer una "guia paso a paso" con los links y mandarmela por mail?¿
Muchas gracias
localburn@gmail.com

jesusnoseq dijo...

Se agradece poder aprender de vez cuando con tutoriales en español :)
PD:El enlace de arriba, el del archivo jar, está roto pero buscando se encuentra XD
http://wiki.andengine.org/AndEngine_Jars

Xifa dijo...

ya no se debe usar el archivo .jar para utilizar el andengine, denle una chekeada a este tutorial para aprender como se hace
http://www.youtube.com/watch?v=JVmuKPHAC8k

Zeneke dijo...

Por qué ya no se puede? En qué te basas?

Óscar dijo...

Gracias por el tutorial!

tanrobles2011 dijo...

Muchas Gracias el Tutorial esta muy bueno.

ekirne dijo...

Esta estupendo!! pero tengo problemillas con Scene(int) dice q es deprecated, y no se me inicia el emulador puede ser porque la version sea la 2.3?

Rodrigo Depetris dijo...

Gente alguien me puede dar una mano?, no puedo hacer correr el codigo, me tira siempre error inesperado, Forzar cierre. Probe varios .jar de distintos tamaños y me hace con todos lo mismo :@

Unknown dijo...

Gracias.
Gran tutorial.

Itsaso Agirre Lorenzo dijo...

Muchas gracias por tu aporte hay pocos tutoriales en castellano

Itsaso Agirre Lorenzo dijo...
Este comentario ha sido eliminado por el autor.
Edgard Ocampo dijo...

Ola, Tengo un problema con el orden que se muestra en las Imágenes, al tener 3 Sprite; un Sprite para el Fondo, otro para una imagen que es la mitad del fondo, y otra que es la cuarta parte del fondo.
Aunque sé, que el orden que parecerá las imágenes depende del orden en que se escribió el código en el método OnloadScene.
@Override
public Scene onLoadScene() {
mEngine.registerUpdateHandler(new FPSLogger());
sc=new Scene();
//CARGA DE LA ECENA DE FONDO QUE ES LA IMAGEN GRANDE 1re Orden
fdoS=new Sprite(0, 0, fdoTR);
sc.attachChild(fdoS);
//CARGA DE LA ECENA DE LA IMAGEN MEDIANA 2do Orden
medS=new Sprite(0, 0, fdoTR);
sc.attachChild(fdoS);
//CARGA DE LA ECENA DE LA IMAGEN PEQUEÑA 3re Orde
peqS=new Sprite(0, 0, fdoTR);
sc.attachChild(fdoS);
return sc.
}
Como se puede observar en el código de arriba, el orden de los códigos escritos muestran el orden de la imagen. El cual esto no parece conveniente usar. Quisiera saber si existe algún método u objeto a usar para definir este orden.

Publicar un comentario