воскресенье, 1 апреля 2012 г.

AndEngine. Движение спрайта по определенному маршруту

Ссылка на пример из документации http://code.google.com/p/andengineexamples/source/browse/src/org/anddev/andengine/examples/PathModifierExample.java.

Согласитесь, весьма распространенная задача - заставить спрайт двигаться через определенные чекпойнты. Делается это довольно просто, в onCreateScene (а может быть, где-нибудь еще) создается объект Path из пакета org.andengine.entity.modifier.*. В качестве аргумента конструктора указывается количество точек, через которые будет проходить спрайт. Если точек менее двух - вывалится Exception:

final Path path = new Path( route.size()+1 );

Заполняется массив точек:

path.to( mCurrentSprite.getX(), mCurrentSprite.getY() );            // от текущей позиции спрайта
path.to(100,100);
path.to(100,250);
....

Где mCurrentSprite - объект, наследованный от Sprite.

Создаем модификатор типа PathModifier:

  mEntityModifier = new PathModifier(SceneGame.DEFAULT_TIME_MOVING_OF_SHIP, path, null, new IPathModifierListener() {

   @Override
   public void onPathStarted(PathModifier pPathModifier,
     IEntity pEntity) {
    // TODO Auto-generated method stub
                                // код, который должен исполняться при старте маршрута
    
   }
 
   @Override
   public void onPathWaypointStarted(PathModifier pPathModifier,
     IEntity pEntity, int pWaypointIndex) {
                              // TODO Auto-generated method stub
                              // код, который выполняется при старте нового чекпойнта   
                        }

   
   
   @Override
   public void onPathWaypointFinished(PathModifier pPathModifier,
     IEntity pEntity, int pWaypointIndex) {
    // TODO Auto-generated method stub
                                // код, который выполняется при финише прохождения чекпойнта   
   }

   @Override
   public void onPathFinished(PathModifier pPathModifier,
     IEntity pEntity) {
                              // TODO Auto-generated method stub   
                              // код, который должен исполняться при финише маршрута
   }
  }); 

В примере из документации эта конструкция оборачивается в LoopEntityModifier(). Если это сделать, спрайт будет возвращаться в точку старта. Я когда в это дело только въезжал, очень долго не мог понять почему мой спрайт на сцене после анимации не меняет своего положения :)

И конечно, вешаем его на наш спрайт:

mCurrentSprite.registerEntityModifier(mEntityModifier);

В-принципе, на этом уже можно поставить точку. Если исполнить данный код, спрайт будет двигаться по заданному маршруту
В методы mEntityModifier можно записать всё, что нам необходимо для анимации спрайта. У меня например спрайт - кораблик поворачивается носом к следующему чекпойнту:
 @Override
 public void onPathWaypointStarted(PathModifier pPathModifier,
   IEntity pEntity, int pWaypointIndex) {
  if( pWaypointIndex < mRoute.size()-1 ){
   Point point1 = mRoute.get( pWaypointIndex );
   Point point2 = mRoute.get( pWaypointIndex+1 );
   float angle = (float) getAngleBetweenPoints(point1, point2);
   mCurrentSprite.setRotation(angle);
  } 
 }

 private double getAngleBetweenPoints(Point point1, Point point2){
  return Math.toDegrees( Math.atan2(point2.getY() - point1.getY(), point2.getX() - point1.getX()) );
 }

А в примерах из документации AndEngine он изменяет анимацию:
    switch(pWaypointIndex) {
     case 0:
      player.animate(new long[]{200, 200, 200}, 6, 8, true);
      break;
     case 1:
      player.animate(new long[]{200, 200, 200}, 3, 5, true);
      break;
     case 2:
      player.animate(new long[]{200, 200, 200}, 0, 2, true);
      break;
     case 3:
      player.animate(new long[]{200, 200, 200}, 9, 11, true);
      break;
    }


2 комментария:

trueFedeX комментирует...

Спасибо за статью!

frops комментирует...

Тяжело, и не очень все понятно, путница какая-то ( Ничего личного. Молодец, что пишешь, все равно.