I took Nicholas' PathModifier code and just updated it to use A* Paths so it should work fairly decently. I also added a few methods to IPathModifierListener, turning it into the IAStarPathModifierListener. The new methods deal with which direction your next step will be (mostly useful for setting which animation you should use).
Here's the code:
Using java Syntax Highlighting
- package korkd.tower;
- import java.util.ArrayList;
- import org.anddev.andengine.entity.IEntity;
- import org.anddev.andengine.entity.layer.tiled.tmx.TMXTiledMap;
- import org.anddev.andengine.entity.modifier.EntityModifier;
- import org.anddev.andengine.entity.modifier.MoveModifier;
- import org.anddev.andengine.util.modifier.IModifier;
- import org.anddev.andengine.util.modifier.SequenceModifier;
- import org.anddev.andengine.util.modifier.SequenceModifier.ISubSequenceModifierListener;
- import org.anddev.andengine.util.modifier.ease.IEaseFunction;
- import org.anddev.andengine.util.path.Path;
- import org.anddev.andengine.util.path.Path.Step;
- import android.util.FloatMath;
- public class AStarPathModifier extends EntityModifier {
- // ===========================================================
- // Constants
- // ===========================================================
- // ===========================================================
- // Fields
- // ===========================================================
- private final SequenceModifier<IEntity> mSequenceModifier;
- private IAStarPathModifierListener mPathModifierListener;
- private final Path mPath;
- private TMXTiledMap mTMXTiledMap;
- // ===========================================================
- // Constructors
- // ===========================================================
- public AStarPathModifier(final float pDuration, final Path pPath, final TMXTiledMap pTMXTiledMap) {
- this(pDuration, pPath, pTMXTiledMap, null, null, IEaseFunction.DEFAULT);
- }
- public AStarPathModifier(final float pDuration, final Path pPath, final TMXTiledMap pTMXTiledMap, final IEaseFunction pEaseFunction) {
- this(pDuration, pPath, pTMXTiledMap, null, null, pEaseFunction);
- }
- public AStarPathModifier(final float pDuration, final Path pPath, final TMXTiledMap pTMXTiledMap, final IEntityModifierListener pEntityModiferListener) {
- this(pDuration, pPath, pTMXTiledMap, pEntityModiferListener, null, IEaseFunction.DEFAULT);
- }
- public AStarPathModifier(final float pDuration, final Path pPath, final TMXTiledMap pTMXTiledMap, final IAStarPathModifierListener pPathModifierListener) {
- this(pDuration, pPath, pTMXTiledMap, null, pPathModifierListener, IEaseFunction.DEFAULT);
- }
- public AStarPathModifier(final float pDuration, final Path pPath, final TMXTiledMap pTMXTiledMap, final IAStarPathModifierListener pPathModifierListener, final IEaseFunction pEaseFunction) {
- this(pDuration, pPath, pTMXTiledMap, null, pPathModifierListener, pEaseFunction);
- }
- public AStarPathModifier(final float pDuration, final Path pPath, final TMXTiledMap pTMXTiledMap, final IEntityModifierListener pEntityModiferListener, final IEaseFunction pEaseFunction) {
- this(pDuration, pPath, pTMXTiledMap, pEntityModiferListener, null, pEaseFunction);
- }
- public AStarPathModifier(final float pDuration, final Path pPath, final TMXTiledMap pTMXTiledMap, final IEntityModifierListener pEntityModiferListener, final IAStarPathModifierListener pPathModifierListener) throws IllegalArgumentException {
- this(pDuration, pPath, pTMXTiledMap, pEntityModiferListener, pPathModifierListener, IEaseFunction.DEFAULT);
- }
- public AStarPathModifier(final float pDuration, final Path pPath, final TMXTiledMap pTMXTiledMap, final IEntityModifierListener pEntityModiferListener, final IAStarPathModifierListener pPathModifierListener, final IEaseFunction pEaseFunction) throws IllegalArgumentException {
- super(pEntityModiferListener);
- final int pathSize = pPath.getLength();
- if (pathSize < 2) {
- throw new IllegalArgumentException("Path needs at least 2 waypoints!");
- }
- this.mTMXTiledMap = pTMXTiledMap;
- this.mPath = pPath;
- this.mPathModifierListener = pPathModifierListener;
- final MoveModifier[] moveModifiers = new MoveModifier[pathSize - 1];
- final float velocity = (pPath.getLength() * mTMXTiledMap.getTileWidth()) / pDuration;
- final int modifierCount = moveModifiers.length;
- for(int i = 0; i < modifierCount; i++) {
- final float duration = getSegmentLength(i) / velocity;
- moveModifiers[i] = new MoveModifier(duration, getXCoordinates(i), getXCoordinates(i + 1), getYCoordinates(i), getYCoordinates(i + 1), null, pEaseFunction);
- }
- /* Create a new SequenceModifier and register the listeners that
- * call through to mEntityModifierListener and mPathModifierListener. */
- this.mSequenceModifier = new SequenceModifier<IEntity>(
- new ISubSequenceModifierListener<IEntity>() {
- @Override
- public void onSubSequenceStarted(final IModifier<IEntity> pModifier, final IEntity pEntity, final int pIndex) {
- if(pIndex < pathSize)
- {
- switch(pPath.getDirectionToNextStep(pIndex)) {
- case DOWN:
- if(AStarPathModifier.this.mPathModifierListener != null) {
- AStarPathModifier.this.mPathModifierListener.onNextMoveDown(AStarPathModifier.this, pEntity, pIndex);
- }
- break;
- case RIGHT:
- if(AStarPathModifier.this.mPathModifierListener != null) {
- AStarPathModifier.this.mPathModifierListener.onNextMoveRight(AStarPathModifier.this, pEntity, pIndex);
- }
- break;
- case UP:
- if(AStarPathModifier.this.mPathModifierListener != null) {
- AStarPathModifier.this.mPathModifierListener.onNextMoveUp(AStarPathModifier.this, pEntity, pIndex);
- }
- break;
- case LEFT:
- if(AStarPathModifier.this.mPathModifierListener != null) {
- AStarPathModifier.this.mPathModifierListener.onNextMoveLeft(AStarPathModifier.this, pEntity, pIndex);
- }
- break;
- default:
- }
- }
- if(AStarPathModifier.this.mPathModifierListener != null) {
- AStarPathModifier.this.mPathModifierListener.onPathWaypointStarted(AStarPathModifier.this, pEntity, pIndex);
- }
- }
- @Override
- public void onSubSequenceFinished(final IModifier<IEntity> pEntityModifier, final IEntity pEntity, final int pIndex) {
- if(AStarPathModifier.this.mPathModifierListener != null) {
- AStarPathModifier.this.mPathModifierListener.onPathWaypointFinished(AStarPathModifier.this, pEntity, pIndex);
- }
- }
- },
- new IEntityModifierListener() {
- @Override
- public void onModifierStarted(final IModifier<IEntity> pModifier, final IEntity pEntity) {
- AStarPathModifier.this.onModifierStarted(pEntity);
- if(AStarPathModifier.this.mPathModifierListener != null) {
- AStarPathModifier.this.mPathModifierListener.onPathStarted(AStarPathModifier.this, pEntity);
- }
- }
- @Override
- public void onModifierFinished(final IModifier<IEntity> pEntityModifier, final IEntity pEntity) {
- AStarPathModifier.this.onModifierFinished(pEntity);
- if(AStarPathModifier.this.mPathModifierListener != null) {
- AStarPathModifier.this.mPathModifierListener.onPathFinished(AStarPathModifier.this, pEntity);
- }
- }
- },
- moveModifiers
- );
- }
- private float getXCoordinates(int pIndex) {
- return mPath.getStep(pIndex).getTileColumn() * mTMXTiledMap.getTileWidth();
- }
- private float getYCoordinates(int pIndex) {
- return mPath.getStep(pIndex).getTileRow() * mTMXTiledMap.getTileHeight();
- }
- private float getSegmentLength(int pIndex) {
- final int nextSegmentIndex = pIndex + 1;
- final float dx = getXCoordinates(pIndex) - getXCoordinates(nextSegmentIndex);
- final float dy = getYCoordinates(pIndex) - getYCoordinates(nextSegmentIndex);
- return FloatMath.sqrt(dx * dx + dy * dy);
- }
- @Override
- public AStarPathModifier clone() throws CloneNotSupportedException {
- // TODO: deepCopy still needs to be implemented on AStarPath's
- return null;
- }
- // ===========================================================
- // Getter & Setter
- // ===========================================================
- public Path getPath() {
- return this.mPath;
- }
- // ===========================================================
- // Methods for/from SuperClass/Interfaces
- // ===========================================================
- @Override
- public boolean isFinished() {
- return this.mSequenceModifier.isFinished();
- }
- @Override
- public float getSecondsElapsed() {
- return this.mSequenceModifier.getSecondsElapsed();
- }
- @Override
- public float getDuration() {
- return this.mSequenceModifier.getDuration();
- }
- public IAStarPathModifierListener getPathModifierListener() {
- return this.mPathModifierListener;
- }
- public void setPathModifierListener(final IAStarPathModifierListener pPathModifierListener) {
- this.mPathModifierListener = pPathModifierListener;
- }
- @Override
- public void reset() {
- this.mSequenceModifier.reset();
- }
- @Override
- public float onUpdate(final float pSecondsElapsed, final IEntity pEntity) {
- return this.mSequenceModifier.onUpdate(pSecondsElapsed, pEntity);
- }
- // ===========================================================
- // Methods
- // ===========================================================
- // ===========================================================
- // Inner and Anonymous Classes
- // ===========================================================
- public static interface IAStarPathModifierListener {
- // ===========================================================
- // Constants
- // ===========================================================
- // ===========================================================
- // Fields
- // ===========================================================
- public void onPathStarted(final AStarPathModifier pPathModifier, final IEntity pEntity);
- public void onNextMoveLeft(AStarPathModifier aStarPathModifier, IEntity pEntity, int pIndex);
- public void onNextMoveUp(AStarPathModifier aStarPathModifier, IEntity pEntity, int pIndex);
- public void onNextMoveRight(AStarPathModifier aStarPathModifier, IEntity pEntity, int pIndex);
- public void onNextMoveDown(AStarPathModifier aStarPathModifier, IEntity pEntity, int pIndex);
- public void onPathWaypointStarted(final AStarPathModifier pPathModifier, final IEntity pEntity, final int pWaypointIndex);
- public void onPathWaypointFinished(final AStarPathModifier pPathModifier, final IEntity pEntity, final int pWaypointIndex);
- public void onPathFinished(final AStarPathModifier pPathModifier, final IEntity pEntity);
- }
- }
Parsed in 0.068 seconds, using GeSHi 1.0.8.4
and here's an example of a register call to it:
Using java Syntax Highlighting
- this.registerEntityModifier(new AStarPathModifier(path.getPathLength()/2, path.getAStarPath(), mTMXTiledMap, new AStarPathModifier.IAStarPathModifierListener()
- {
- @Override
- public void onPathWaypointStarted(AStarPathModifier pPathModifier, final IEntity pEntity, int pWaypointIndex) {
- }
- @Override
- public void onPathStarted(AStarPathModifier pPathModifier,
- IEntity pEntity) {
- }
- @Override
- public void onPathWaypointFinished(AStarPathModifier pPathModifier,
- IEntity pEntity, int pWaypointIndex) {
- }
- @Override
- public void onPathFinished(AStarPathModifier pPathModifier,
- IEntity pEntity) {
- mArmyPool.recyclePoolItem(mArmy);
- mPlayer.Reached(mDestCastle);
- mSourceCastle = null;
- mDestCastle = null;
- }
- @Override
- public void onNextMoveLeft(AStarPathModifier aStarPathModifier,
- IEntity pEntity, int pIndex) {
- mArmy.animate(new long[]{200, 200, 200}, 9, 11, true);
- }
- @Override
- public void onNextMoveUp(AStarPathModifier aStarPathModifier,
- IEntity pEntity, int pIndex) {
- mArmy.animate(new long[]{200, 200, 200}, 0, 2, true);
- }
- @Override
- public void onNextMoveRight(AStarPathModifier aStarPathModifier,
- IEntity pEntity, int pIndex) {
- mArmy.animate(new long[]{200, 200, 200}, 3, 5, true);
- }
- @Override
- public void onNextMoveDown(AStarPathModifier aStarPathModifier,
- IEntity pEntity, int pIndex) {
- mArmy.animate(new long[]{200, 200, 200}, 6, 8, true);
- }
- }));
- }
Parsed in 0.035 seconds, using GeSHi 1.0.8.4
