sábado, 1 de diciembre de 2012

Tutorial TMX Tiled Map AngEngine GLES 2.0

Lo primero que tenemos que hacer es importar la librería de AndEngine GLES 2.0 AndEngineTMXTiledMapExtension que se importa igual que nuestra librería de AndEngine pero cambiando el enlace. Este es el enlace que debéis poner: https://github.com/nicolasgramlich/AndEngineTMXTiledMapExtension.git
Pinchar aquí para ir al tutorial Instalar AndEngine.
Una vez que la tenemos importada creamos nuestro proyecto AndEngine. Ahora cliqueamos con el botón secundario encima de nuestro proyecto y vamos a propierties. Ahora nos vamos a Android y en la parte de abajo donde sale Library pulsamos add. Seleccionamos AndEngineTMXTiledMapExtension y ya tenemos en nuestro proyecto enlazada la librería.
Ahora vamos a crear nuestro Tiled Map. Yo utilizo el programa Tiled Map Editor que lo podeís descargar de http://www.mapeditor.org/ y es totalmente gratuito.
Tras instalarlo, abrimos el programa y nos vamos a editar-->preferencias. Y nos aseguramos que las capas de patrones se guardan como Base64(con compresión gzip).


Ahora procedemos a crear nuestro Tiled Map y tras guardarlo lo editamos con bloc de notas o worpad para añadir gfx/ donde esta la refencia a nuestro archivo png y que luego no tengamos problemas al abrir nuestro Tiled Map.
Asi se queda nuestro archivo tmx:
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.0" orientation="orthogonal" width="20" height="12" tilewidth="40" tileheight="40">
 <tileset firstgid="1" name="tiled" tilewidth="40" tileheight="40">
  <image source="gfx/tiled.png" width="80" height="80"/>
 </tileset>
 <layer name="Capa de Patrones 1" width="20" height="12">
  <properties>
   <property name="hierba" value="1"/>
  </properties>
  <data encoding="base64" compression="gzip">
   H4sIAAAAAAAAC62TSQ4AIAgDKfD/NxsTT4SlJhzmBI7FRUVEl7EBED2W+ECs72pMPn9UbjS+bO/Kl/Wy58eA4HPhsnTzs75pfiz72HzTu4v13/uY/Nv/7HIAAsD5jMADAAA=
  </data>
 </layer>
</map>
Podéis descargar los archivo necesarios para este tutorial de mi página en github haciendo click aquí.
Ahí os he subido la clase java al completo, las imagenes necesarias y el archivo tmx.
Tras haber creado el mapa creamos una carpeta dentro de assets llamada tmx e introducimos nuestro archivo tmx. Y en la carpeta gfx pegamos la imagen que hemos utilizado para crear nuestro mapa.
Ahora estamos en disposición de ponernos a escribir codigo.
Creamos dentro de nuestra clase:
        private static final int CAMERA_WIDTH = 400;
private static final int CAMERA_HEIGHT = 240;

private BoundCamera mBoundCamera;

private BitmapTextureAtlas mBitmapTextureAtlas;
private ITextureRegion mJugadorTextureRegion;
private TMXTiledMap mTMXTiledMap;
private Sprite jugador;
private Scene scene;
Lo único nuevo has ahora es BoundCamera que se utiliza para que la cámara no sea fija y TMXTiledMap que es nuestro mapa.
Ahora nos vamos a EngineOptions y pegamos lo siguiente:
public EngineOptions onCreateEngineOptions() {

this.mBoundCamera = new BoundCamera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT);

return new EngineOptions(true, ScreenOrientation.LANDSCAPE_FIXED,
new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT),
this.mBoundCamera);
}
Lo que hemos hecho es definir el tamaño de nuestra BoundCamera  y que en las opciones de el motor la vista sera la BoundCamera.
En onCreateResources pegamos:
public void onCreateResources() {
BitmapTextureAtlasTextureRegionFactory.setAssetBasePath("gfx/");

this.mBitmapTextureAtlas = new BitmapTextureAtlas(
this.getTextureManager(), 40, 40,
TextureOptions.NEAREST_PREMULTIPLYALPHA);
this.mJugadorTextureRegion = BitmapTextureAtlasTextureRegionFactory
.createFromAsset(this.mBitmapTextureAtlas, this, "x.png", 0, 0);

this.mBitmapTextureAtlas.load();
}


lo que he hecho es definir un sprite igual que en anteriores tutoriales.
Ahora vamos al grueso del asunto que esta dentro de onCreateScene:
Creamos nuestra escena:
                this.mEngine.registerUpdateHandler(new FPSLogger());

scene = new Scene();


Después cargamos nuestro TiledMap con el siguiente código:
try {
final TMXLoader tmxLoader = new TMXLoader(this.getAssets(),
this.mEngine.getTextureManager(),
TextureOptions.NEAREST_PREMULTIPLYALPHA,
this.getVertexBufferObjectManager());
this.mTMXTiledMap = tmxLoader.loadFromAsset("tmx/map.tmx");

} catch (final TMXLoadException e) {
}


En textureOptions ponemos NEAREST_PREMULTIPLYALPHA en vez de BILINEAR_PREMULTIPLYALPHA para que no se noten la juntas.
Y cargamos en tmxLoader nuestro archivo tmx.
Ahora vamos a cargar nuestra capa, ya que solo tenemos una.
final TMXLayer tmxLayer = this.mTMXTiledMap.getTMXLayers().get(0);
scene.attachChild(tmxLayer);


si tuviéramos mas crearíamos mas tmxLayer cambiando el numero de get para cada una. El numero de get es 0 porque se empieza a enumerar desde 0, si tuviéramos 2 capas cargaríamos primero 0 y luego 1.
Ahora definimos los limites de la cámara y los activamos, para que no se salga de nuestro mapa.
this.mBoundCamera.setBounds(0, 0, tmxLayer.getWidth(),
tmxLayer.getHeight());
this.mBoundCamera.setBoundsEnabled(true);
Ahora definimos nuestro sprite y asignamos a la cámara que se mueva centrando el sprite en la cámara.

jugador = new Sprite(0, 0, this.mJugadorTextureRegion,
this.getVertexBufferObjectManager());
this.mBoundCamera.setChaseEntity(jugador);
scene.attachChild(jugador);

Para finalizar onCreateScene vamos a activa touchListener y la escena.

scene.setOnSceneTouchListener(this);
return scene;

Ya casi hemos terminado, en mi caso he creado un método para que al tocar la pantalla se mueva el sprite con forma de X y a su vez la cámara.
El método es el siguiente:

public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent) {

if (pSceneTouchEvent.getAction() == TouchEvent.ACTION_DOWN) {

final float touchX = pSceneTouchEvent.getX();
final float touchY = pSceneTouchEvent.getY();

jugador.setPosition(touchX - (jugador.getWidth() / 2), touchY
- (jugador.getHeight() / 2));

}

return false;

}
Para finalizar tenemos que implementar los eventos touch en nuestra clase:
public class BaseActivity extends SimpleBaseGameActivity implements
IOnSceneTouchListener {
Con esto ya hemos terminado el tutorial os dejo la imagen del mapa para que veáis como queda al final:
Un saludo.

3 comentarios:

  1. Muy bueno tu tutorial gracias!!
    En esta parte tube que poner detachSelf(), sabes que haces exactamente ese metodo?

    TMXLayer tmxLayer = this.mTMXTiledMap.getTMXLayers().get(0);
    tmxLayer.detachSelf();

    gameScene.attachChild(tmxLayer);

    ResponderEliminar
  2. hola el tutorial esta muy entendible gracias por compartirlo, quisiera saber si es posible validar colisiones en el tiled map, como cuando se chica contra una pared... si es así como se puede hacer'??

    ResponderEliminar