Previously on AndEngine from Scratch
Today goals
- Create the player sprite.
- Create a Detector to the catapult effect.
Create the player
To create the player i decided to use an AnimatedSprite, but we subclass the AnimatedSprite to be able to personalize it.
To crate the class, go to the folder with the sources in Eclipse. File New -> Class and the Name is Player and the SuperClass is AnimatedSprite. We add a debug TAG and for now is ok.
package com.pruebas.andengine;
import org.anddev.andengine.entity.sprite.AnimatedSprite;
import org.anddev.andengine.input.touch.detector.HoldDetector;
import org.anddev.andengine.input.touch.detector.HoldDetector.IHoldDetectorListener;
import org.anddev.andengine.opengl.texture.region.TiledTextureRegion;
import android.util.Log;
public class Player extends AnimatedSprite {
private static final String TAG = "Player";
public Player(float pX, float pY, TiledTextureRegion pTiledTextureRegion) {
super(pX, pY, pTiledTextureRegion);
}
}
Get back to the Main.java and let's add a variable to hold the active Player object. Let's change the mFaceTextureRegion to mBallTextureRegion to make it pretty and change the type to TiledTextureRegion. My variables looks like this:
// ===========================================================
// Fields
// ===========================================================
private ZoomCamera mCamera;
private Texture mTexture;
private TiledTextureRegion mBallTextureRegion;
private TiledTextureRegion mPlayerTextureRegion;
private SurfaceScrollDetector mScrollDetector;
private TMXTiledMap mTMXTiledMap;
private Player mActivePlayer;
Here is the player sprite, download to your assets/gfx folder as usual.
Here is some experimental ball sprite (i need a real ball to make photos), to the same site, assets/gfx
Now we must change the way to load the textures to load this new two textures. All the textures go to the mTexture Object. The mTexture object need a power of two in width and height in pixels. To hold the textures recently downloaded we need exactly 256X256 pixels. The texture in memory would look like this:
Let's change en onLoadResources() method to load all this new stuff. First of all, the size of the mTexture needs to be 256X256 and now to load the ball texture we use the createTiledFromAsset() function with the parameters:
- this.mTexture: The first is the mTexture object where all the textures are going
- this: Actual class.
- "gfx/ui_ball.png": Path to the image containing the tiled sprites.
- 0,0: The next two integer parameters is where are going yo put the image inside mTexture. In this case, in the top left corner (0,0). The player in the top middle (128,0).
- 2,4: Number of rows an columns in the tile. 2,4 in our case.
@Override
public void onLoadResources() {
this.mTexture = new Texture(256, 256,
TextureOptions.BILINEAR_PREMULTIPLYALPHA);
this.mBallTextureRegion = TextureRegionFactory.createTiledFromAsset(
this.mTexture, this, "gfx/ui_ball.png", 0, 0, 2, 4);
this.mPlayerTextureRegion = TextureRegionFactory.createTiledFromAsset(
this.mTexture, this, "gfx/ui_player.png", 128, 0, 2, 4);
this.mEngine.getTextureManager().loadTexture(this.mTexture);
}
Now, some code on the onLoadScene() method. First we delete the source creating the ball and deactivate the ScrollDetector. The procedure should look like this:
scene.setOnAreaTouchTraversalFrontToBack();
this.mScrollDetector = new SurfaceScrollDetector(this);
this.mScrollDetector.setEnabled(false); //Hemos puesto esto a false
/*
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;
}
Let's create a method to create a player to test the animation.
// ===========================================================
// Methods
// ===========================================================
private void createPlayer() {
final Scene scene = this.mEngine.getScene();
final Player sprite = new Player(200, 100, this.mPlayerTextureRegion);
// scene.registerTouchArea(sprite);
scene.getLastChild().attachChild(sprite);
this.mActivePlayer = sprite;
}
To test, we are gonna put a player in the 200X100 position. Call this new function from onLoadComplete().
@Override
public void onLoadComplete() { // scene.set
createPlayer();
}
In this point, we can debug our program to see what's happen. We can see the background grass and the player. It doesn't respond to scroll because we deactivated it. Let's create the detector.
Creating a Detector
Looking around in the AndEngine sources, the ScrollDetector is a very easy way to create Detectors.
We create a new class in our project. Name: CatapultDetector and SuperClass BaseDetector
(org.anddev.andengine.input.touch.detector.BaseDetector)
package com.pruebas.andengine;
import org.anddev.andengine.input.touch.TouchEvent;
import org.anddev.andengine.input.touch.detector.BaseDetector;
public class CatapultDetector extends BaseDetector {
@Override
protected boolean onManagedTouchEvent(TouchEvent pSceneTouchEvent) {
// TODO Auto-generated method stub
return false;
}
}
We are going to try to make a Detector that works like the ScrollDetector, we need a listener interface.
public static interface ICatapultDetectorListener {
// ===========================================================
// Constants
// ===========================================================
// ===========================================================
// Methods
// ===========================================================
public void onCharge(final CatapultDetector pCatapultDetector,
final TouchEvent pTouchEvent, final float pDistance,
final float pAngle);
public void onShoot(final CatapultDetector pCatapultDetector,
final TouchEvent pTouchEvent, final float pDistance,
final float pAngle);
}
This is a basic listener to test the working of the Detector. The listener object recieves the angle and distance of the soot. We define this class inside the CatapultDetector class like the other detector in AndEngine.
Let's put some variables to the detector.
// ===========================================================
// Constants
// ===========================================================
private static final float TRIGGER_SCROLL_MINIMUM_DISTANCE_DEFAULT = 10;
private static final float ANGLE_CONSTANT = 10;
private static final int DEFAULT_STEPS = 6;
private float DEFAULT_MAX_DISTANCE = 100;
// ===========================================================
// Fields
// ===========================================================
//Minimum distance to execute
private float mTriggerScrollMinimumDistance;
//Listener for the Detector
private final ICatapultDetectorListener mCatapultDetectorListener;
private boolean mTriggered;
//First Touch
private float mFirstX;
private float mFirstY;
//Last Touch
private float mLastX;
private float mLastY;
private int mSteps;
private float mMaxDistance;
We create some methods to use later and getter and setter to mTriggerScrollMinimumDistance
// ===========================================================
// Getter & Setter
// ===========================================================
public void setTriggerScrollMinimumDistance(
float mTriggerScrollMinimumDistance) {
this.mTriggerScrollMinimumDistance = mTriggerScrollMinimumDistance;
}
public float getTriggerScrollMinimumDistance() {
return mTriggerScrollMinimumDistance;
}
// ===========================================================
// Methods
// ===========================================================
protected float getX(final TouchEvent pTouchEvent) {
return pTouchEvent.getX();
}
protected float getY(final TouchEvent pTouchEvent) {
return pTouchEvent.getY();
}
Code a little in the class constructors.
// ===========================================================
// Constructors
// ===========================================================
public CatapultDetector(
final ICatapultDetectorListener pCatapultDetectorListener) {
this(TRIGGER_SCROLL_MINIMUM_DISTANCE_DEFAULT, pCatapultDetectorListener);
}
public CatapultDetector(final float pTriggerScrollMinimumDistance,
final ICatapultDetectorListener pCatapultDetectorListener) {
this.setTriggerScrollMinimumDistance(pTriggerScrollMinimumDistance);
this.mCatapultDetectorListener = pCatapultDetectorListener;
}
And now the main method of the class, where all happens.
// ===========================================================
// Methods for/from SuperClass/Interfaces
// ===========================================================
@Override
protected boolean onManagedTouchEvent(TouchEvent pSceneTouchEvent) {
final float touchX = this.getX(pSceneTouchEvent);
final float touchY = this.getY(pSceneTouchEvent);
switch (pSceneTouchEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
this.mFirstX = touchX;
this.mFirstY = touchY;
this.mLastX = touchX;
this.mLastY = touchY;
this.mTriggered = false;
return true;
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
final float distanceX = touchX - this.mLastX;
final float distanceY = touchY - this.mLastY;
if (pSceneTouchEvent.getAction() == MotionEvent.ACTION_MOVE) {
final float triggerScrollMinimumDistance = this.mTriggerScrollMinimumDistance;
if (this.mTriggered
|| Math.abs(distanceX) > triggerScrollMinimumDistance
|| Math.abs(distanceY) > triggerScrollMinimumDistance) {
final float distance = (float)Math.hypot((double)distanceX,(double)distanceY);
final double angleX = touchX - this.mFirstX;
final double angleY = touchY - this.mFirstY;
final float angle = (float)Math.toDegrees(Math.atan2(angleY, angleX))+ANGLE_CONSTANT;
this.mCatapultDetectorListener.onCharge(this, pSceneTouchEvent, distance, angle);
this.mLastX = touchX;
this.mLastY = touchY;
this.mTriggered = true;
}
else
{
}
}
return true;
default:
return false;
}
}
In The next article we are going to explain more carefully the Detector, but looking the source you can see how it works. Let's back to the Main.java. Create a private variable to hold the Detector Object.
// ===========================================================
// Fields
// ===========================================================
private ZoomCamera mCamera;
private Texture mTexture;
private TiledTextureRegion mBallTextureRegion;
private TiledTextureRegion mPlayerTextureRegion;
private SurfaceScrollDetector mScrollDetector;
private TMXTiledMap mTMXTiledMap;
private Player mActivePlayer;
private CatapultDetector mCatapultDetector; //Nueva variable Creada
Now tell the Main class to implement the new ICatapultDetectorListener interface.
public class Main extends BaseGameActivity implements IScrollDetectorListener,
IOnSceneTouchListener, ICatapultDetectorListener
Now we must implement the missing methods of the interface.
@Override
public void onCharge(CatapultDetector pCatapultDetector,
TouchEvent pTouchEvent, float pDistance, float pAngle) {
Log.d(TAG, "Cargando... {Distancia:" + pDistance + ", angulo: "
+ pAngle + "}");
this.mActivePlayer.setRotation(pAngle);
}
@Override
public void onShoot(CatapultDetector pCatapultDetector,
TouchEvent pTouchEvent, float pDistance, float pAngle) {
Log.d(TAG, "Disparo... {Distancia:" + pDistance + ", angulo: " + pAngle
+ "}");
}
In the onCharge() method, we rotate the player sprite according to the calculated angle. In the onShoot() method, only Debug message. The next step is create in the onLoadScene() method the Detector and assign to the Main Object.
this.mScrollDetector = new SurfaceScrollDetector(this);
this.mScrollDetector.setEnabled(false);
//Creamos el detector de catapulta
this.mCatapultDetector = new CatapultDetector(this);
this.mCatapultDetector.setEnabled(true);
And in the onSceneTouchEvent() method we pass the event to the CatapultDetector.
@Override
public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent) {
if (this.mActivePlayer != null) {
this.mCatapultDetector.onTouchEvent(pSceneTouchEvent);
}
return true;
}
We now can debug again the project and see what's going on. F11... we can see the splash, the background, the player... all fine. Let's tap with the finger on the Screen and do some move around. The payer rotates but not in the desired angle. It's a start. Now my files are like this:
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.AnimatedSprite;
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.opengl.texture.region.TiledTextureRegion;
import org.anddev.andengine.ui.activity.BaseGameActivity;
import org.anddev.andengine.util.Debug;
import android.util.Log;
import com.pruebas.andengine.CatapultDetector.ICatapultDetectorListener;
public class Main extends BaseGameActivity implements IScrollDetectorListener,
IOnSceneTouchListener, ICatapultDetectorListener {
// ===========================================================
// 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 TiledTextureRegion mBallTextureRegion;
private TiledTextureRegion mPlayerTextureRegion;
private SurfaceScrollDetector mScrollDetector;
private TMXTiledMap mTMXTiledMap;
private Player mActivePlayer;
private CatapultDetector mCatapultDetector; //Nueva variable Creada
// ===========================================================
// Constructors
// ===========================================================
// ===========================================================
// Getter & Setter
// ===========================================================
// ===========================================================
// Methods for/from SuperClass/Interfaces
// ===========================================================
@Override
public void onLoadComplete() {
createPlayer();
}
@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(256, 256,
TextureOptions.BILINEAR_PREMULTIPLYALPHA);
this.mBallTextureRegion = TextureRegionFactory.createTiledFromAsset(
this.mTexture, this, "gfx/ui_ball.png", 0, 0, 2, 4);
this.mPlayerTextureRegion = TextureRegionFactory.createTiledFromAsset(
this.mTexture, this, "gfx/ui_player.png", 128, 0, 2, 4);
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(false);
this.mCatapultDetector = new CatapultDetector(this);
this.mCatapultDetector.setEnabled(true);
scene.setOnSceneTouchListener(this);
scene.setTouchAreaBindingEnabled(true);
return scene;
}
@Override
public void onCharge(CatapultDetector pCatapultDetector,
TouchEvent pTouchEvent, float pDistance, float pAngle) {
Log.d(TAG, "Cargando... {Distancia:" + pDistance + ", angulo: "
+ pAngle + "}");
this.mActivePlayer.setRotation(pAngle);
}
@Override
public void onShoot(CatapultDetector pCatapultDetector,
TouchEvent pTouchEvent, float pDistance, float pAngle) {
Log.d(TAG, "Disparo... {Distancia:" + pDistance + ", angulo: " + pAngle
+ "}");
}
@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) {
if (this.mActivePlayer != null) {
this.mCatapultDetector.onTouchEvent(pSceneTouchEvent);
}
return true;
}
// ===========================================================
// Methods
// ===========================================================
private void createPlayer() {
final Scene scene = this.mEngine.getScene();
final Player sprite = new Player(200, 100, this.mPlayerTextureRegion);
scene.getLastChild().attachChild(sprite);
this.mActivePlayer = sprite;
}
// ===========================================================
// Inner and Anonymous Classes
// ===========================================================
}
package com.pruebas.andengine;
import org.anddev.andengine.input.touch.TouchEvent;
import org.anddev.andengine.input.touch.detector.BaseDetector;
import android.view.MotionEvent;
public class CatapultDetector extends BaseDetector {
// ===========================================================
// Constants
// ===========================================================
private static final float TRIGGER_SCROLL_MINIMUM_DISTANCE_DEFAULT = 10;
private static final float ANGLE_CONSTANT = 10;
private static final int DEFAULT_STEPS = 6;
private float DEFAULT_MAX_DISTANCE = 100;
// ===========================================================
// Fields
// ===========================================================
//Minimum distance to execute
private float mTriggerScrollMinimumDistance;
//Listener for the Detector
private final ICatapultDetectorListener mCatapultDetectorListener;
private boolean mTriggered;
//First Touch
private float mFirstX;
private float mFirstY;
//Last Touch
private float mLastX;
private float mLastY;
private int mSteps;
private float mMaxDistance;
// ===========================================================
// Constructors
// ===========================================================
public CatapultDetector(
final ICatapultDetectorListener pCatapultDetectorListener) {
this(TRIGGER_SCROLL_MINIMUM_DISTANCE_DEFAULT, pCatapultDetectorListener);
}
public CatapultDetector(final float pTriggerScrollMinimumDistance,
final ICatapultDetectorListener pCatapultDetectorListener) {
this.setTriggerScrollMinimumDistance(pTriggerScrollMinimumDistance);
this.mCatapultDetectorListener = pCatapultDetectorListener;
}
// ===========================================================
// Methods for/from SuperClass/Interfaces
// ===========================================================
@Override
protected boolean onManagedTouchEvent(TouchEvent pSceneTouchEvent) {
final float touchX = this.getX(pSceneTouchEvent);
final float touchY = this.getY(pSceneTouchEvent);
switch (pSceneTouchEvent.getAction()) {
case MotionEvent.ACTION_DOWN:
this.mFirstX = touchX;
this.mFirstY = touchY;
this.mLastX = touchX;
this.mLastY = touchY;
this.mTriggered = false;
return true;
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
final float distanceX = touchX - this.mLastX;
final float distanceY = touchY - this.mLastY;
if (pSceneTouchEvent.getAction() == MotionEvent.ACTION_MOVE) {
final float triggerScrollMinimumDistance = this.mTriggerScrollMinimumDistance;
if (this.mTriggered
|| Math.abs(distanceX) > triggerScrollMinimumDistance
|| Math.abs(distanceY) > triggerScrollMinimumDistance) {
final float distance = (float)Math.hypot((double)distanceX,(double)distanceY);
final double angleX = touchX - this.mFirstX;
final double angleY = touchY - this.mFirstY;
final float angle = (float)Math.toDegrees(Math.atan2(angleY, angleX));
this.mCatapultDetectorListener.onCharge(this, pSceneTouchEvent, distance, angle);
this.mLastX = touchX;
this.mLastY = touchY;
this.mTriggered = true;
}
else
{
}
}
return true;
default:
return false;
}
}
// ===========================================================
// Getter & Setter
// ===========================================================
public void setTriggerScrollMinimumDistance(
float mTriggerScrollMinimumDistance) {
this.mTriggerScrollMinimumDistance = mTriggerScrollMinimumDistance;
}
public float getTriggerScrollMinimumDistance() {
return mTriggerScrollMinimumDistance;
}
// ===========================================================
// Methods
// ===========================================================
protected float getX(final TouchEvent pTouchEvent) {
return pTouchEvent.getX();
}
protected float getY(final TouchEvent pTouchEvent) {
return pTouchEvent.getY();
}
// ===========================================================
// Inner and Anonymous Classes
// ===========================================================
public static interface ICatapultDetectorListener {
// ===========================================================
// Constants
// ===========================================================
// ===========================================================
// Methods
// ===========================================================
public void onCharge(final CatapultDetector pCatapultDetector,
final TouchEvent pTouchEvent, final float pDistance,
final float pAngle);
public void onShoot(final CatapultDetector pCatapultDetector,
final TouchEvent pTouchEvent, final float pDistance,
final float pAngle);
}
}
Good work today. I'm working on this Detector. The next chapter in the same subject.
Source Code
To get the source code: svn checkout http://ch-soccer.googlecode.com/svn/trunk/ tutorial-read-only -r 7
Basically it force closes after the splash screen because for some reason it first can't find 'libhgl.so'
ReplyDeleteThen it tells me it 'Failed loading bitmap into AssestTextureSource'
Then of course a lot of red after that...
Did you tried the Source from the subversion??
ReplyDeletesvn checkout http://ch-soccer.googlecode.com/svn/trunk/ tutorial-read-only -r 7
If that doesn't work, try Project -> Clean in Eclipse. The sources are tested to work.
Yes I copied the source for every thing from that location but same thing happens. Apparently someone else was having that problem. Is the libhgl.so library the problem or is it something to do with how my tmx file is setup. What all goes into the TMX folder exactly. Does it just contain the .tmx you save from TiledQT or do you have to do something else with it. The tutorial was vague in that area in tutorial 3. Sorry to bother about this but I really really want it work and I would like to put this engine to use.
ReplyDeleteI'm also very new to Android programming so I appreciate you taking the time to bear through this with me. I saw where someone else was having the same problem here too.
Another thing is there are so many versions of the andengine.jar file that I'm not sure which one to use. For your example I used the one at
http://ch-soccer.googlecode.com/svn/trunk/ tutorial-read-only -r 7
But if you try to use that jar with other tutorials, some of the methods have changed.
Tutorial 1 and 2 went perfect, but as soon as we introduce the Splashcreen and TMX stuff, that's where I have the problem and I think it's because I'm doing something wrong with the .tmx or there is something missing in regards to the level file.
I noticed here ( http://ch-soccer.googlecode.com/svn/trunk/ tutorial-read-only -r 7 ) that there is a file in the tmx folder calle field.tmx but when I look at it it's in xml code. What is going on there exactly?
Thank You
Please try the next thing. Go to Debug perspective, and debug your project.
ReplyDeleteThere is down-right a LogCat pagecontrol, go to the Log Page, and push the E button in the upper toolbar of the pagecontrol.
Then Clear log (another button on the toolbar) and push F11 to debug the project.
Plase send me the result of the debug, there is the exact message of the error. If you don't tell me exactly what error is happening, i can't help you, all i can tell you is with an empty workspace i imported the project from the cvs and all works fine in the emulator and in a terminal.
Please, send me the error to angel.ivorra at gmail dot com and i will try to solve your problem.
Thank you
I did get these errors after I thought I had it all perfect... still force closes no matter what I do. I've checked every line of code and I still think it has something to do with the TMX file. That's the only place I'm a little vague, or not fully comprehending. These are the only errors I get but I don't think it will help.
ReplyDelete[2011-04-11 16:28:22 - Logcat]null
com.android.ddmlib.TimeoutException
at com.android.ddmlib.AdbHelper.read(AdbHelper.java:648)
at com.android.ddmlib.AdbHelper.read(AdbHelper.java:616)
at com.android.ddmlib.AdbHelper.readAdbResponse(AdbHelper.java:216)
at com.android.ddmlib.AdbHelper.executeRemoteCommand(AdbHelper.java:378)
at com.android.ddmlib.Device.executeShellCommand(Device.java:284)
at com.android.ddmuilib.logcat.LogPanel$3.run(LogPanel.java:527)
It can't load/find the .tmx file:
ReplyDelete04-12 14:33:08.198: ERROR/AndEngine(331): AndEngine
04-12 14:33:08.198: ERROR/AndEngine(331): org.anddev.andengine.entity.layer.tiled.tmx.util.exception.TMXLoadException: Could not load TMXTiledMap from asset: tmx/field.tmx
04-12 14:33:08.198: ERROR/AndEngine(331): at org.anddev.andengine.entity.layer.tiled.tmx.TMXLoader.loadFromAsset(TMXLoader.java:77)
04-12 14:33:08.198: ERROR/AndEngine(331): at com.pruebas.andengine.Main.onLoadScene(Main.java:108)
04-12 14:33:08.198: ERROR/AndEngine(331): at org.anddev.andengine.ui.activity.BaseGameActivity.doResume(BaseGameActivity.java:159)
04-12 14:33:08.198: ERROR/AndEngine(331): at org.anddev.andengine.ui.activity.BaseGameActivity.onWindowFocusChanged(BaseGameActivity.java:83)
04-12 14:33:08.198: ERROR/AndEngine(331): at com.android.internal.policy.impl.PhoneWindow$DecorView.onWindowFocusChanged(PhoneWindow.java:1981)
04-12 14:33:08.198: ERROR/AndEngine(331): at android.view.View.dispatchWindowFocusChanged(View.java:3788)
04-12 14:33:08.198: ERROR/AndEngine(331): at android.view.ViewGroup.dispatchWindowFocusChanged(ViewGroup.java:658)
04-12 14:33:08.198: ERROR/AndEngine(331): at android.view.ViewRoot.handleMessage(ViewRoot.java:1921)
04-12 14:33:08.198: ERROR/AndEngine(331): at android.os.Handler.dispatchMessage(Handler.java:99)
04-12 14:33:08.198: ERROR/AndEngine(331): at android.os.Looper.loop(Looper.java:123)
04-12 14:33:08.198: ERROR/AndEngine(331): at android.app.ActivityThread.main(ActivityThread.java:4627)
04-12 14:33:08.198: ERROR/AndEngine(331): at java.lang.reflect.Method.invokeNative(Native Method)
04-12 14:33:08.198: ERROR/AndEngine(331): at java.lang.reflect.Method.invoke(Method.java:521)
04-12 14:33:08.198: ERROR/AndEngine(331): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
04-12 14:33:08.198: ERROR/AndEngine(331): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
04-12 14:33:08.198: ERROR/AndEngine(331): at dalvik.system.NativeStart.main(Native Method)
04-12 14:33:08.198: ERROR/AndEngine(331): Caused by: java.io.FileNotFoundException: tmx/field.tmx
04-12 14:33:08.198: ERROR/AndEngine(331): at android.content.res.AssetManager.openAsset(Native Method)
04-12 14:33:08.198: ERROR/AndEngine(331): at android.content.res.AssetManager.open(AssetManager.java:313)
04-12 14:33:08.198: ERROR/AndEngine(331): at android.content.res.AssetManager.open(AssetManager.java:287)
There is more but couldn't fit in one post. Let me know if that helps. Does the tmx folder go into the root of the project instead or something...
ReplyDeleteMake a Project Clean, this worked for me several times.
ReplyDeleteIf it doesn't help, make sure that the preferences of qtiled are like i said in the third tutorial.
Hope it helps you.
OMG I'm just gonna stop posting.... I didn't have the tmx file in there this time but I did before and still get the force close looking for errors now that I know how to debug better.
ReplyDeleteI did do the Base64 Gzip. Are you tiling 4 horizontal and 8 vertical tiles for the field and are you naming the .tmx field.tmx for certain?
ReplyDeletethx
Yes, you can download the source code from the subversion server.
ReplyDeleteAnother great part of the Tutorial, I'm confused about Detector.
ReplyDeleteNeed study it more
Hi Angel,
ReplyDeleteThe app is working whitout any problem, but my background(tmx) doesn't look like how I create on virtual machine. It is a different one. I mean tiles look displaced.
How can it be possible?
P.S: thx very much for the tutorial
Bartu
After a lot of fighting with a crash right after the splash screen I found this issue: http://code.google.com/p/andengine/issues/detail?id=53
ReplyDeleteRename the images to something without the underscore to fix the crashes where it cannot find the .png files.
The app is working great!
ReplyDeleteFor those with a problem, check the name of your field file, and the position. You probably named it to something else.