@Override
  protected void onManagedUpdate(float pSecondsElapsed) {
    super.onManagedUpdate(pSecondsElapsed);

    if (this.eysEntityYSorter != null) this.eysEntityYSorter.onUpdate(pSecondsElapsed);

    AchievementsManager.onUpdate(pSecondsElapsed);
  }
  public void createExplosion(float x, float y, float radius, float damage, boolean harmPlayer) {

    final float X = x, Y = y;

    final HashMap<Character, Float> CHARACTERS_IN_RANGE = new HashMap<Character, Float>();

    for (final Zombie z : Zombie.getAliveZombies())
      this.onExplosionCheckCharacterCollision(x, y, radius, z, CHARACTERS_IN_RANGE);

    if (harmPlayer)
      this.onExplosionCheckCharacterCollision(x, y, radius, this.pPlayer, CHARACTERS_IN_RANGE);

    final Iterator<Character> CHARACTER_ITERATOR = CHARACTERS_IN_RANGE.keySet().iterator();
    final Iterator<Float> DAMAGE_ITERATOR = CHARACTERS_IN_RANGE.values().iterator();

    while (CHARACTER_ITERATOR.hasNext()) {

      final Character CHAR = CHARACTER_ITERATOR.next();
      final Float DAMAGE = DAMAGE_ITERATOR.next();

      CHAR.setHealthAmount((int) (CHAR.getHealthAmount() - damage * DAMAGE));

      if (CHAR.getHealthAmount() <= 0) AchievementsManager.incrementZombiesKilledByExplosion();
    }

    final ITiledTextureRegion EXPLOSION_TEXTURE = HudRegions.region_explosion;
    final AnimatedSprite EXPLOSION =
        new AnimatedSprite(
            x, y, EXPLOSION_TEXTURE, EnvironmentVars.MAIN_CONTEXT.getVertexBufferObjectManager());

    if (this.explosionCount == 0) EXPLOSION_TEXTURE.getTexture().load();

    EXPLOSION.setScaleCenter(0, 0);
    EXPLOSION.setScale(2f);
    EXPLOSION.setPosition(
        EXPLOSION.getX() - EXPLOSION.getWidthScaled() / 2f,
        EXPLOSION.getY() - EXPLOSION.getHeightScaled() / 2f);
    EXPLOSION.setZIndex(this.getLevel().getMapHeight());
    this.attachChild(EXPLOSION);
    this.explosionCount++;

    EXPLOSION.animate(
        30L,
        false,
        new IAnimationListener() {
          private boolean usedEffects;

          @Override
          public void onAnimationFinished(AnimatedSprite pAnimatedSprite) {
            EnvironmentVars.MAIN_CONTEXT.runOnUpdateThread(
                new Runnable() {
                  @Override
                  public void run() {
                    SessionScene.this.explosionCount--;
                    if (SessionScene.this.explosionCount == 0)
                      EXPLOSION_TEXTURE.getTexture().unload();
                    EXPLOSION.detachSelf();
                    EXPLOSION.dispose();
                  }
                });
          }

          @Override
          public void onAnimationFrameChanged(
              AnimatedSprite pAnimatedSprite, int pOldFrameIndex, int pNewFrameIndex) {

            if (pNewFrameIndex >= 3)
              if (!this.usedEffects) {
                SessionScene.this.createExplosionMark(X, Y);
                SessionScene.this.onExplosionCreateSmoke(X, Y);
                this.usedEffects = true;
              }
          }

          @Override
          public void onAnimationLoopFinished(
              AnimatedSprite pAnimatedSprite, int pRemainingLoopCount, int pInitialLoopCount) {}

          @Override
          public void onAnimationStarted(AnimatedSprite pAnimatedSprite, int pInitialLoopCount) {}
        });

    this.getCameraManager().shakeRandomDirection();

    SessionScene.EXPLOSION_SOUND.play();
  }