Anteriormente en Droideando
Objetivo de hoy
Hoy tenemos varios objetivos:
- Ponerle una pantalla de splash al juego
- Crear el fondo realista de un campo de futbol
Pantalla de Splash
Todo juego que se precie tiene que empezar con un splash bien bonito. Vamos a ver como podemos hacer ello con AndEngine. Nos ofrece una clase BaseSplashActivity. Nos vamos en "Package Explorer" a src/com.pruebas.andengine y creamos una nueva clase.
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiQAAn-9Kbhpu_1k4QQim50_cJW66bHOR7u9cJwjaHaVl-0JA-dlt0l14_Q_5nj2j4zoX3lG3UwgwehR7ttAuByj4mCc8qh9GpMvsWhucpj_Ji8YmwCnJeDIMrofUDoE-5l7DqmaKQS8dT/s1600/paso1.png)
Le ponemos en Name SplashExample, y vamos a SuperClass y le damos a buscar la clase BaseSplashActivity y aceptamos.
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7GAq2HBFnNqMrLOTzRKSStCABUjl9E2i_yjP37xZhjx0upVxSys2jJBDVrz1OOl24ZVKKq9CGhaiJUbQLQRzX91qppEfo8uNcZK3xHNgHkEpq27ZOqRfdmdLHf2m7jQD0zEepfsn3TU1k/s1600/paso2.png)
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicsAoW2wCJKuKarzZzfrjZFMtDHWqk5gmbxUmr0togfJDf7EWu_WVjiDuWJaAsUwuinQny1AzbAeGGBal3CNGGl5kd32_mmiO8pGKZSH-NMELvE5NwkoTkVFDPpWDLlMNniaIMTN_pqUm8/s1600/paso3.png)
Nos genera una clase como esta.OJO: el método getFollowUpActivity por un error del formateador que uso para ésto muestra como comentarios html, ni caso... dejadlo como os lo genera Eclipse.
package com.pruebas.andengine;
import org.anddev.andengine.engine.options.EngineOptions.ScreenOrientation;
import org.anddev.andengine.opengl.texture.source.ITextureSource;
import org.anddev.andengine.ui.activity.BaseSplashActivity;
import android.app.Activity;
public class SplashExample extends BaseSplashActivity {
@Override
//Ojo, porque esto no se ve bien aqui, dejadlo como Eclipse lo genera
protected Class<? extends Activity> getFollowUpActivity() {
// TODO Auto-generated method stub
return null;
}
@Override
protected ScreenOrientation getScreenOrientation() {
// TODO Auto-generated method stub
return null;
}
@Override
protected float getSplashDuration() {
// TODO Auto-generated method stub
return 0;
}
@Override
protected ITextureSource onGetSplashTextureSource() {
// TODO Auto-generated method stub
return null;
}
}
Ahora vamos a tocar algunas de los métodos de la clase para que muestre el splash que queremos. Si no tienes ninguna imagen de splash que quieras usar, puedes bajarte la que pongo a continuación. OJO: Recuerda guardarla como assets/gfx/splash.png
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDQ04L_ZiZEy0xd0vOzacVRB1fDODv3jvwm7EaLBI3Jd5vDxEiVDU4F2vLxxQbctTEAqkJLdFfaVRX0asFRUu3sO1W4UGT7Be5UHr6VmKCmVkmLe9zRBqBs8ZSoIQ7-UXngSWJ2PUvlRQF/s1600/splash.png)
Ahora tocamos la clase para que muestre el splash desde la imagen. primero definimos unas constantes
// ===========================================================
// Constants
// ===========================================================
private static final int SPLASH_DURATION = 3;
private static final float SPLASH_SCALE_FROM = 1f;
SPLASH_DURATION define el numero de segundos del splash, 3 está bien. La segunda constante es el origen desde el que se escala... por ejemplo, si pones 0.5f el splash aparecerá pequeñito y llegará a ocupar toda la pantalla.
En el primer procedimiento getFollowUpActivity(), lo que debemos devolver es la Actividad que se va a ejecutar después del splash. En este caso Main.
@Override
protected Class<? extends Activity> getFollowUpActivity() {
return Main.class;
}
En el segundo método getScreenOrientation(), debemos devolver la orientación de la pantalla, en este caso es apaisada.
protected ScreenOrientation getScreenOrientation() {
return ScreenOrientation.LANDSCAPE;
}
Tercer método getSplashDuration(), devolvemos la constante
@Override
protected float getSplashDuration() {
return SPLASH_DURATION;
}
Y por último onGetSplashTextureSource(), que devolvemos la textura que hemos guardado antes en el disco...
protected ITextureSource onGetSplashTextureSource() {
return new AssetTextureSource(this, "gfx/splash.png");
}
Ahora implementamos un nuevo método por si queremos hacer el zoom y jugar con él.
protected float getSplashScaleFrom() {
return SPLASH_SCALE_FROM;
}
Bien, ya tenemos la clase del Splash, ahora hay que meterla en el AndroidManifest.xml y poerla por defecto. Para ello nos vamos a editar el AndroidManifest.xml como texto y añadimos la actividad y la ponemos para que se ejecute al empezar el programa.
<activity android:name="SplashExample"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Y eliminamos de la actividad Main los intent-filter para que la única que se ejecute al comenzar el juego sea la del splash. Le damos F11 para correr el proyecto y podmeos ver la pantalla de splash funcionando correctamente.
Creando el fondo del juego
Para crear el fondo del juego hay varias opciones. Primero probé con un RepeatingSpriteBackground, pero no se movía con el scroll de la pantalla, fuera. Mirando por los fuentes de AndEngine he visto una cosa llamada TMXLoader que carga un nivel de un xml y te pone todo en su sitio... me llamó la atención y manos a la obra
Afortunadamente tiene un editor de niveles gratuito y open source para todas las pataformas. Lo primero era crear el sprite con el fondo de cesped. Aqui lo teneis. Como siempre va a assets/gfx.
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHDP-lBANa9BXCTqAOhIZ0UMPpphsZpPuoKqB5tB8zR5Xw3dIShOZsqSN4laY1vY4Jc_kk40mVhrH2_tmVdW6Y_ZuwGK4cE4brsmNw0CVXByuxG6tkFhJenTrUkJDHNdlKKNJCgQhT6_6m/s1600/background_tile.png)
El sistema para crear niveles se basa en pngs que estén divididos como un tablero de ajedrez, para mi caso necesitaba las cuatro esquinas, arriba, abajo, izquierda, derecha y centro, 9 sprites.
![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0-FJPlblbhz8IpHfs9ZMUw2AllVW2k3khryuubw3UCsJ0mwat2gR-HHB9U07v3_vYfl3jHq-uXE1KQRwNlS2kCbylOQDPn-yWtifTj6p5VF6peoDLVSN5wRDpYzrFMi_17dIgtZE3E49s/s1600/background_tile.png)
Pongo el png con los bordes dibujados aqui para que entendais más o menos como lo he estructurado. 9 celdas de 120x120. Ahora me he bajado el editor de mapas. En Debian ha sido muy facil, un buen "sudo apt-get install tiled" y todo solucionado. En debian u otros linux la instalación será similar usando tu gestor de paquetes favorito. En windows puedes ir a su web y bajarlo. OJO: Al instalarlo comprobar en Editar->Preferencias donde pone "Almacenar la capa de patrones como" poned Base64 (con compresion gzip), si no AndEngine da errores y no carga el archivo tmx.
Tras un rato de diversión obtengo el archivo .tmx que es el mapa con una estructura xml. Ahora vamos a añadirlo al proyecto. Creamos una carpeta nueva en assets que se llame tmx para meter aqui nuestros mapas, y creamos un archivo llamado field.tmx. El mio tiene una pinta así.
<map version="1.0" orientation="orthogonal" width="4" height="8" tilewidth="120" tileheight="120">
<tileset firstgid="1" name="background" tilewidth="120" tileheight="120">
<image source="gfx/background_tile.png"/>
</tileset>
<layer name="Capa de Patrones 1" width="4" height="8">
<data encoding="base64" compression="gzip">
H4sIAAAAAAAAA2NlYGBghGI2IGYBYk4oZqYBnx2ImaCYA4gB8HAreoAAAAA=
</data>
</layer>
</map>
Atentos al image-source, apunta a gfx/background_tile.png, si editais el mapa desde tiled luego igual teneis que tocar a donde apuntan las imagenes.
Antes de empezar a meter código, yo tengo el Main.java 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.Scene.IOnSceneTouchListener;
import org.anddev.andengine.entity.scene.background.ColorBackground;
import org.anddev.andengine.entity.sprite.Sprite;
import org.anddev.andengine.entity.util.FPSLogger;
import org.anddev.andengine.input.touch.TouchEvent;
import org.anddev.andengine.input.touch.detector.ScrollDetector;
import org.anddev.andengine.input.touch.detector.SurfaceScrollDetector;
import org.anddev.andengine.input.touch.detector.ScrollDetector.IScrollDetectorListener;
import org.anddev.andengine.opengl.texture.Texture;
import org.anddev.andengine.opengl.texture.TextureOptions;
import org.anddev.andengine.opengl.texture.region.TextureRegion;
import org.anddev.andengine.opengl.texture.region.TextureRegionFactory;
import org.anddev.andengine.ui.activity.BaseGameActivity;
import android.util.Log;
public class Main extends BaseGameActivity implements IScrollDetectorListener,
IOnSceneTouchListener {
// ===========================================================
// Constants
// ===========================================================
static final int CAMERA_WIDTH = 480;
static final int CAMERA_HEIGHT = 320;
private static final String TAG = "AndEngineTest";
// ===========================================================
// Fields
// ===========================================================
private ZoomCamera mCamera;
private Texture mTexture;
private TextureRegion mFaceTextureRegion;
private SurfaceScrollDetector mScrollDetector;
// ===========================================================
// 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);
final int alturaTotal = CAMERA_HEIGHT * 3;
this.mCamera.setBounds(0, CAMERA_WIDTH, 0, alturaTotal);
this.mCamera.setBoundsEnabled(true);
return new Engine(new EngineOptions(true, ScreenOrientation.LANDSCAPE,
new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT),
this.mCamera));
}
@Override
public void onLoadResources() {
this.mTexture = new Texture(64, 64,
TextureOptions.BILINEAR_PREMULTIPLYALPHA);
this.mFaceTextureRegion = TextureRegionFactory.createFromAsset(
this.mTexture, this, "gfx/ui_ball_1.png", 0, 0);
this.mEngine.getTextureManager().loadTexture(this.mTexture);
}
@Override
public Scene onLoadScene() {
this.mEngine.registerUpdateHandler(new FPSLogger());
final Scene scene = new Scene(1);
scene.setBackground(new ColorBackground(0, 0, 0.8784f));
scene.setOnAreaTouchTraversalFrontToBack();
this.mScrollDetector = new SurfaceScrollDetector(this);
this.mScrollDetector.setEnabled(true);
final int centerX = (CAMERA_WIDTH - this.mFaceTextureRegion.getWidth()) / 2;
final int centerY = (CAMERA_HEIGHT - this.mFaceTextureRegion
.getHeight()) / 2;
final Sprite ball = new Sprite(centerX, centerY,
this.mFaceTextureRegion);
scene.getLastChild().attachChild(ball);
scene.setOnSceneTouchListener(this);
scene.setTouchAreaBindingEnabled(true);
return scene;
}
@Override
public void onScroll(ScrollDetector pScollDetector, TouchEvent pTouchEvent,
float pDistanceX, float pDistanceY) {
this.mCamera.offsetCenter(-pDistanceX, -pDistanceY);
}
@Override
public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent) {
this.mScrollDetector.onTouchEvent(pSceneTouchEvent);
return true;
}
// ===========================================================
// Methods
// ===========================================================
// ===========================================================
// Inner and Anonymous Classes
// ===========================================================
}
Vamos a crear una variable para el TMXTiledMap.
private TMXTiledMap mTMXTiledMap;
En el procedimiento onLoadScene() cuando ponemos el color de fondo con el comando
scene.setBackground(new ColorBackground(0, 0, 0.8784f));
Cambiamos ese código por éste otro
final TMXLoader tmxLoader = new TMXLoader(this, this.mEngine
.getTextureManager(),
TextureOptions.BILINEAR_PREMULTIPLYALPHA,
new ITMXTilePropertiesListener() {
@Override
public void onTMXTileWithPropertiesCreated(
final TMXTiledMap pTMXTiledMap,
final TMXLayer pTMXLayer,
final TMXTile pTMXTile,
final TMXProperties<tmxtileproperty> pTMXTileProperties) {
}
});
this.mTMXTiledMap = tmxLoader.loadFromAsset(this, "tmx/field.tmx");
} catch (final TMXLoadException tmxle) {
Debug.e(tmxle);
}
final TMXLayer tmxLayer = this.mTMXTiledMap.getTMXLayers().get(0);
scene.getFirstChild().attachChild(tmxLayer);
Con esto ya podemos darle a F11 y ver como queda la cosa... bien, no??. Bueno tiene un pequeño problema, por lo menos en el terminal que yo estoy probando, cuando hago scroll me salen unas lineas negras en la junta de las texturas. Investigando un poco por los foros de AndEngine veo la manera de solucionarlo. Vamos a la parte donde creamos la textura de fondo... y cambiamos TextureOptions.BILINEAR_PREMULTIPLYALPHA por TextureOptions.NEAREST. Luego vamos a la parte donde creamos la cámara en onLoadEngine() y ponemos esto para la creación de la cámara para que ajuste a enteros la posición de la cámara y se vea ese feo efecto en la teléfono.
this.mCamera = new ZoomCamera(0, 0, CAMERA_WIDTH, CAMERA_HEIGHT) {
@Override
public void onApplyMatrix(GL10 pGL) {
GLHelper.setProjectionIdentityMatrix(pGL);
GLU.gluOrtho2D(pGL, (int) this.getMinX(), (int) this.getMaxX(),
(int) this.getMaxY(), (int) this.getMinY());
}
};
Ale, asunto solucinoado, ya tenemos esto funcionando correctamente. Así se me queda el Main.java.
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.layer.tiled.tmx.TMXLayer;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXLoader;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXProperties;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXTile;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXTileProperty;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXTiledMap;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXLoader.ITMXTilePropertiesListener;
import org.anddev.andengine.entity.layer.tiled.tmx.util.exception.TMXLoadException;
import org.anddev.andengine.entity.scene.Scene;
import org.anddev.andengine.entity.scene.Scene.IOnSceneTouchListener;
import org.anddev.andengine.entity.sprite.Sprite;
import org.anddev.andengine.entity.util.FPSLogger;
import org.anddev.andengine.input.touch.TouchEvent;
import org.anddev.andengine.input.touch.detector.ScrollDetector;
import org.anddev.andengine.input.touch.detector.SurfaceScrollDetector;
import org.anddev.andengine.input.touch.detector.ScrollDetector.IScrollDetectorListener;
import org.anddev.andengine.opengl.texture.Texture;
import org.anddev.andengine.opengl.texture.TextureOptions;
import org.anddev.andengine.opengl.texture.region.TextureRegion;
import org.anddev.andengine.opengl.texture.region.TextureRegionFactory;
import org.anddev.andengine.ui.activity.BaseGameActivity;
import org.anddev.andengine.util.Debug;
public class Main extends BaseGameActivity implements IScrollDetectorListener,
IOnSceneTouchListener {
// ===========================================================
// Constants
// ===========================================================
static final int CAMERA_WIDTH = 480;
static final int CAMERA_HEIGHT = 320;
private static final String TAG = "AndEngineTest";
// ===========================================================
// Fields
// ===========================================================
private ZoomCamera mCamera;
private Texture mTexture;
private TextureRegion mFaceTextureRegion;
private SurfaceScrollDetector mScrollDetector;
private TMXTiledMap mTMXTiledMap;
// ===========================================================
// 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);
final int alturaTotal = CAMERA_HEIGHT * 3;
this.mCamera.setBounds(0, CAMERA_WIDTH, 0, alturaTotal);
this.mCamera.setBoundsEnabled(true);
return new Engine(new EngineOptions(true, ScreenOrientation.LANDSCAPE,
new RatioResolutionPolicy(CAMERA_WIDTH, CAMERA_HEIGHT),
this.mCamera));
}
@Override
public void onLoadResources() {
this.mTexture = new Texture(64, 64,
TextureOptions.BILINEAR_PREMULTIPLYALPHA);
this.mFaceTextureRegion = TextureRegionFactory.createFromAsset(
this.mTexture, this, "gfx/ui_ball_1.png", 0, 0);
this.mEngine.getTextureManager().loadTexture(this.mTexture);
}
@Override
public Scene onLoadScene() {
this.mEngine.registerUpdateHandler(new FPSLogger());
final Scene scene = new Scene(1);
try {
final TMXLoader tmxLoader = new TMXLoader(this, this.mEngine
.getTextureManager(), // TextureOptions.BILINEAR_PREMULTIPLYALPHA,
TextureOptions.NEAREST, new ITMXTilePropertiesListener() {
@Override
public void onTMXTileWithPropertiesCreated(
final TMXTiledMap pTMXTiledMap,
final TMXLayer pTMXLayer,
final TMXTile pTMXTile,
final TMXProperties<tmxtileproperty> pTMXTileProperties) {
}
});
this.mTMXTiledMap = tmxLoader.loadFromAsset(this, "tmx/field.tmx");
} catch (final TMXLoadException tmxle) {
Debug.e(tmxle);
}
final TMXLayer tmxLayer = this.mTMXTiledMap.getTMXLayers().get(0);
scene.getFirstChild().attachChild(tmxLayer);
scene.setOnAreaTouchTraversalFrontToBack();
this.mScrollDetector = new SurfaceScrollDetector(this);
this.mScrollDetector.setEnabled(true);
final int centerX = (CAMERA_WIDTH - this.mFaceTextureRegion.getWidth()) / 2;
final int centerY = (CAMERA_HEIGHT - this.mFaceTextureRegion
.getHeight()) / 2;
final Sprite ball = new Sprite(centerX, centerY,
this.mFaceTextureRegion);
scene.getLastChild().attachChild(ball);
scene.setOnSceneTouchListener(this);
scene.setTouchAreaBindingEnabled(true);
return scene;
}
@Override
public void onScroll(ScrollDetector pScollDetector, TouchEvent pTouchEvent,
float pDistanceX, float pDistanceY) {
this.mCamera.offsetCenter(-pDistanceX, -pDistanceY);
}
@Override
public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent) {
this.mScrollDetector.onTouchEvent(pSceneTouchEvent);
return true;
}
// ===========================================================
// Methods
// ===========================================================
// ===========================================================
// Inner and Anonymous Classes
// ===========================================================
}
Bueno, por hoy está bien. Para el siguiente capítulo vamos a Implementar nuestro propio Detector, como el IScrollDetector pero para juegos estilo catapulta. Ya lo tengo hecho, pero una cosa es hacerlo y otra ponerlo aquí y explicarlo. Mañana más.
35 comentarios:
Gracias! Muy currado el tutorial.
Entre otras cosas me ha llamado la atención aprender a utilizar el SuperClass Selection (no lo conocía xDD) y el software "tiled" se ve interesante otra cosa más para estudiar ^^,'
He encontrado algunos posibles errores en el código en los que en algunos tengo la solución y otros no.
La primera parte del tutorial funciona con algunos retoques y la segunda por ahora no..
Te lo comento por mail para no llenar esto.
saludos, sigue así!
Gracias por la correción. El problema está en el formateador de xml y de java, que se ha vuelto loco.
Voy a buscar otro para usar.
Un saludo.
Impresionante!!
Llevo algún que otro día buscando y recolectando toda la doc. posible sobre este motor.
Y como sabes la mayoría de info está en inglés. tardo 5 veces más en entender ciertos conceptos jeje (llevo en esto muy poco).
Por supuesto los foros de Andengine son geniales pero tus tutoriales no tienen precio.
Sobretodo por la forma agradable y sencilla de explicarlos. Muchísimas gracias por contribuir a hacer que el estudio de Android y de este motor, sea mucho más llevadero.
Por mi parte el objetivo es hacer un LiveWallpaper aprovechando las bondades de Andengine y con el tiempo algo más complejo como un juego.
Muchísimas gracias de nuevo y, si me permites, te hago una preguntilla sobre los 2 primeros tutoriales de Andengine. (el 3º todavía no lo he estudiado)
- El el 1º tuto das un link directo al andengine.jar que pesa unos 1.5 MB. El mio que lo bajé del link que da Nicolas pesa 843KB.
Supongo que uno lleva el Manifest.xml, exportJarToAll.xml, etc. Y el otro está sin "añadidos" (que , por cierto, me funcionó de perlas en el emulador con tus 2 primeros tutoriales).
Podrías decirme que tipo de andengine.jar es el más aconsejable para un proyecto con este motor ó un link donde automáticamente esté el archivo actualizado?
Saludos y disculpa por la magnitud del post
Gracias por el comentario Ricard.
Pues la verdad no se exactamente que diferencia hay entre los dos jar... yo ahora que lo he mirado también estoy usando uno que ocupa 863.174 bytes. Cambiaré en enlace en el primer tutorial. Yo tampoco soy un experto en esto, con Java/Android llevo 3 meses jugueteando y con AndEngine llevo desde el primer tutorial, una semana creo.
Siento no saber solucionar tu duda... Si algo no te sale del tutorial porque hay una errata dímelo y lo soluciono, que me interesa que ésto se quede lo más fino posible. También si ves algo que hay una manera mejor de hacerlo, dimelo por favor, que en Java soy totalmente novato y probablemente habrá mejores maneras de hacerlas.
Un saludo :)
Hola Angel,
Gracias por la rapidez!!
Respecto a lo que comentas, en cuanto a los errores o pulir código, no dudes en que lo haré con tal de poder aportar algo "a la causa", aunque de momento, reconozco que me llevas 3 pueblos de adelanto ;) y no te podré ayudar más que en la identificación de algunos errores.
Por lo demás decirte que las 2 primeras partes del tutorial son impecables y todo funciona genial. El único error (aunque creo que es mio) viene en el debug, donde la ClassLoader.class no puede "attachar" el android.jar y aunque la ruta C:/Program Files/Android/sdk/platforms/android-4/android.jar es correcta...no inicia la aplicación en modo debug.
Pero como he dicho creo que esto es cosa mía por lo que destinaré unas horas para solucionar el tema.
ReSaludos ;)
Disculpa,
Lo tenía delante de las narices... Me he estado leyendo el tutorial de "Depurar proyectos en Android (Source not found)" y solucionado!!
Como siempre muchas gracias y buenas noches!!
Hola Angel,
Al igual que Ephram, también me da error ciertas partes de código y aunque no se la solución que él ha aportado, en mi caso lo he resuelto sustituyendo la parte que hace referencia a:
new ITMXTilePropertiesListener() {
@Override
public void onTMXTileWithPropertiesCreated(
final TMXTiledMap pTMXTiledMap,
final TMXLayer pTMXLayer,
final TMXTile pTMXTile,
final TMXProperties pTMXTileProperties) {
}
}
Por:
@Override
public void onTMXTileWithPropertiesCreated(TMXTiledMap pTMXTiledMap, TMXLayer pTMXLayer, TMXTile pTMXTile, TMXProperties pTMXTileProperties) {
}
});
Y aunque no dudo en que deben existir otras soluciones mejores, a mi me funciona correctamente. Por supuesto estaré encantado de leer tus sugerencias al respecto.
Muchas gracias!!!
Saludos
La solución buena es esta:
new ITMXTilePropertiesListener();
Sin tanto follón, por desconocimiento mio de java y por basarme en codigo de los ejemplos la habia liado un poco.
muchas gracias por publicar estos tutoriales... soy novato y estoy teniendo algunos problemas para correr la aplicacion en esta tercera parte.. el splashscreen me corre normal. pero al volver al main. me da un error y no encuentro cual es el problema.. copie y pegue el codigo tuyo directamente y aun asi, nada...
si pudieses ayudarme, te lo agradeceria.
por si lo olvidaba.. super estos tutoriales... keep up the good work !!!
uppss... googleando sobre el problema me he tropezado con que tengo que importar el .so file pero no tengo idea de como hacer eso. ya que al descargar el andengine solo tengo andengine.jar y andenginephysicsbox2dextension.jar
se supone que tambien tenga que descargar los .so o es un procedimiento para incorporarlos a la libreria??
sorry si parece un poco tonto la verdad es que buscando sobre el tema, hay bastante problema pero no mucha informacion sobre como hacerlo..
gracias por adelantado
Hola Angel,
Me imagino que, como muchos de nosotros, no vas sobrado de tiempo, por lo tanto ¡¡muchas gracias de nuevo por responder!!
En referencia a tu solución, a mi no me funciona. Increíblemente ya no me da error el codigo original. Bueno solo me da un aviso de:
/////---- TMXProperties is a raw type. References to generic type TMXProperties should be parameterized -----//// pero me permite lanzar la aplicación ene el emulador.
En cambio, la solución que aportas me da el error de:
/// --- Cannot instantiate the type TMXLoader.ITMXTilePropertiesListener ---///
Empiezo a creer que me faltan años luz de experiencia en java ya que hay cambios que no sé a que son debidos y errores que no llego a comprender.
De todas formas seguiré con este tutorial ya que con los cambios que hice de tu código original no me da aparentemente ningún problema.
Muchas gracias y ánimo con el proyecto!
Saludos
Hola! yo he solucionado el codigo con :
:: Añadiendo a los imports:
import org.anddev.andengine.entity.layer.tiled.tmx.TMXLayer;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXLoader;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXLoader.ITMXTilePropertiesListener;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXProperties;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXTile;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXTileProperty;
import org.anddev.andengine.entity.layer.tiled.tmx.TMXTiledMap;
import org.anddev.andengine.entity.layer.tiled.tmx.util.exception.TMXLoadException;
:: A nivell de codigo ::
final TMXLoader tmxLoader = new TMXLoader(this, this.mEngine.getTextureManager(), TextureOptions.BILINEAR_PREMULTIPLYALPHA, new ITMXTilePropertiesListener() {
public void onTMXTileWithPropertiesCreated(final TMXTiledMap pTMXTiledMap, final TMXLayer pTMXLayer, final TMXTile pTMXTile, final TMXProperties pTMXTileProperties) {
}
});
Hola que tal? puse lo que dice Jordi, pero cuando pasa el splash me salta un error y se cierra la aplicacion. Puede q a alguien le haya pasado algo similar o tienen idea de que puede ser?? muchas gracias
Gustavo, abre el tmx con un editor de texto y mira donde pone la url de la imagen. Asegurate que es gfx/nombreDeTuImagen.tmx
Saludos
Hola, con la última librería que me he descargado de AndEngine (el enlace de la que has usado en la primera parte no funciona) me da un FC cuando termina de mostrar el Splash, y el caso es que la otra actividad mostrada sin splash si que funciona, al parecer falla al pasar de una actividad a otra, ¿a alguien más le ha pasado y sabe como solucionarlo?
Gracias.
Nicolas ha hecho un cambio en los fuentes de andengine y ahora las texturas han cambiado todas de nombre y los fuentes que hay en el proyecto no funcionan. Hay que hacer unos cambios de nombre....
Ahora mismo ando un poco liado con otros proyectos y no tengo tiempo de cambiar todos los fuentes de los tutoriales. Espero que cuando pase el verano me de tiempo a ponerlos al pistón otra vez y continuar las series.
Un saludo.
Estos son los cambios de variables. Cuando tenga un rato libre actualizo los tutoriales con ese cambio de fuentes.
TextureRegionFactory - > BitmapTextureAtlasTextureRegionFactory
ExternalStorageFileTextureSource -> ExternalStorageFileBitmapTextureAtlasSource
Texture -> BitmapTextureAtlas
BuildableTexture -> BuildableBitmapTextureAtlas
hola chicos tengo un problema en esta parte
protected IBitmapTextureAtlasSource onGetSplashTextureAtlasSource() {
return new AssetTextureSource(this, "gfx/splash.png");
}
esto es lo tengo yo y no puedo ponerlo como en el tuto en la primera parte que me puede pasar.
un saludo y gracias.
Es porque tu verison de AndEngine es mas reciente y algunas variables y metodos cambiaron de nombre.
cambia:
AssetTextureSource por AssetBitmapTextureAtlasSource
y agrega el import
import org.anddev.andengine.opengl.texture.atlas.bitmap.source.AssetBitmapTextureAtlasSource;
Espero te funciones
Saludos
Hola amigo, gracias por tus tutoriales, son muy buenos y he aprendido mucho con ellos. Solo que tengo una duda:
Verás, agregue dos clases Splash (splash y splash2). Splash redirecciona a splash2, y splash2 me manda al main, lo hice asi para que me salgan dos imágenes antes del menú principal.
Bien, me di cuenta que cuando hace la transición entre splash y splash2, se vuelve la pantalla negra por un instante y de a misma forma pasa antes de irme al main.
Hay alguna manera de manejar algún tipo de transición personalizada para evitar que se vea ese parpadeo? o para no usar dos pantallas de splash, se puede montar en una misma las intersecciones?
Hola, estoy siguiendo hasta ahora, pero aun no me sale el splash, podrias pegar tu AndroidManifiest.xml hasta ese punto?, tampoco entiendo que se hace con el editor de niveles. pego el field.tmx pero me sale error
Hola
A mi me funciona el Splash pero cuando llama a la actividad principal se cae.
YO igual les dejo intent-filter en el Maniefiesto y pasa esto.
Pero si se los saco me dice que no encuentra la actividad.
Saludos
Ya lo solucione... pensé un poco: Como esto funciona por actividades, agregué otra actividad llamando a la clase principal y listo.
Muestra el Splash y después el juego.
Me respondí solo ;-)
Saludos
tengo problemas en el splash si lo pongo, luego me sale un forzar cierre y nose como solucionarlo...
haber si podria ayudarme alguien gracias
Y como iba yo a saber que la versión tiene mucho que ver?. Amigos, también tuve que ver el problema del SplashScreen que luego de ejecutar, mostraba la imagen de inicio pero al querer saltar a la aplicación principal, ahi me lanzaba una excepción no controlada. Yo estuve compilando para la versión 1.2 del android. Luego cambié a la versión más reciente 7, y ahora si ya me funciona. Claro tienen que actualizar eso de ITexture, ya no existe con el ultimo jar de AndEngine. Aqui el AndroidManifest.xml para el que le haga falta
Por cierto... tienen que declarar al Activity que van a llamar desde el splash screen, todo esto en el AndroidManifiest.xml
....
android:versionCode="1"
android:versionName="1.0" >
...
ooops!, no puedo escribirles el código:
package="XXX.XXX"
android:versionCode="1"
android:versionName="1.0"
'uses-sdk android:minSdkVersion="7" /'
'application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" android:debuggable="true"'
'activity
android:name=".MainVista"
android:label="@string/app_name" '
'/activity'
'activity android:name=".SplashScreen" android:label="@string/app_name" android:icon="@drawable/ic_launcher"'
'intent-filter'
'action android:name="android.intent.action.MAIN"/'
'category android:name="android.intent.category.LAUNCHER"/'
'/intent-filter'
'/activity'
'/application'
'/manifest'
NOTA: Si no entiendes este código mejor presiona alt+f4 jejeje. Ayuda: reemplaza los ' por < o por > para cada etiqueta, aqui no se puede escribir código XML :(
Suerte.
Tengo el mismo problema de attach que Ozuno pero no me funcionó el crear otra actividad como él... alguna idea amigos?
Tenía mal declarado el nombre de una Activity en el Manifest... fallo tonto y dificil de ver xD
Publicar un comentario