воскресенье, 30 сентября 2012 г.

Очистка мира-box2d andengine



Andengine.
Удаление объектов world-box2d должно производиться в такте andengine.
Вот код.
сначала удаляются все тела, потом соединения


public class MyPhysicsWorld extends FixedStepPhysicsWorld {

...

public void clean() {
  boolean bFlagDestroy=true
  clearForces();
  clearPhysicsConnectors();
  Iterator<Body> allMyBodies = getBodies();
  while (allMyBodies.hasNext()) {
     bFlagDestroy=true;
     final Body currentBody = allMyBodies.next();
     destroyBody(currentBody);
  }
  Iterator<Joint> allMyJoints = getJoints();
  while (allMyJoints.hasNext()) {
     final Joint currentJoint = allMyJoints.next();
     destroyJoint(currentJoint);
  }
  reset();
}

...

 @Override
 public void onUpdate(float pSecondsElapsed) {
   if (mClean) {
      mClean=false;
      clean1();
   }
   super.onUpdate(pSecondsElapsed);
 }


}

Удаление спрайтов со сцены andengine


AndEngine, GLES 1.  Удаление спрайтов со сцены
Удаление спрайтов со сцены должно производиться в такте движка. Почему имеено в такте ?  Потому что  вызов Scene.attachChild(entity) добавляет entity  в
SmartList<IEntity>  класса Entity, от которого наследован класс  Scene.  Во время каждого такта сцена пробегает по списку и вызывает onUpdate для каждого элемента списка.  (Кстати, элемент может отказаться от получения данного уведомления путем вызова setIgnoreUpdate(true)).
Если мы удалим спрайт со сцены вне такта, то сцена об этом знать не будет и при следующем пробеге вывалится exception index out of bounds, т.к. список стал короче.

Вот как правильно производить удаление со сцены:

public class GameScene extends Scene {

public GameScene() {

}

public void setClean()
{
     mClean=true;
}

... 

public void clean() 
{
  this.clearTouchAreas();
  while (getChildCount() > 0) {
      Entity layer = (Entity) getChild(0);
      while (layer.getChildCount() > 0) {
           Entity obj = (Entity) layer.getChild(0);
           while (obj.getChildCount() > 0) {
              Entity sg_child = (Entity) obj.getChild(0);
              obj.detachChild(sg_child);
              sg_child.setIgnoreUpdate(true);
              sg_child = null;
           }
           layer.detachChild(obj);
           obj.setIgnoreUpdate(true);
           obj = null;
         }
         detachChild(layer);
         layer.setIgnoreUpdate(true);
         layer = null;
    }
}



@Override
protected void onManagedUpdate(float pSecondsElapsed) {
   if (mClean)
   {
      mClean=false;
      clean();
   }
   super.onManagedUpdate(pSecondsElapsed);
}

}