/** Performs the animations in given array. */
  public void showAnimation(Animation[] animations) {
    int n = animations.length;
    int duration = 0;

    // Set the theatre for the animations
    for (int i = 0; i < n; ++i) {
      Animation anim = animations[i];
      anim.setTheatre(theatre);
      anim.init();
      duration = Math.max(duration, anim.getStartTime() + anim.getDuration());
    }

    // if the theatre is not captured, do capture it.
    boolean capture = !theatre.isCaptured();
    if (capture) {
      theatre.capture();
    } else {
      theatre.updateCapture();
    }

    // The animation loop
    double amount = 0.0;
    long time = System.currentTimeMillis();
    while (amount < duration) {

      // Animate the animations.
      double work = volume / fps;
      amount += work;
      for (int i = 0; i < n; ++i) {
        Animation anim = animations[i];
        if (!anim.isFinished()) {
          double dur = anim.getDuration();
          if (dur > amount) {
            anim.animate(work);
          } else {
            anim.animate(amount - dur);
            anim.doFinish();
          }
        }
      }

      // Spend the excess time waiting.
      long waitTime = (long) (1000 / fps) + time - (time = System.currentTimeMillis());

      if (waitTime > 0 && !runUntil) {
        try {
          Thread.sleep(waitTime);
        } catch (InterruptedException e) {
        }
      }

      // If the engine is controlled, inform the controller.
      if (controller != null) {
        try {
          controller.checkPoint(this, false);
        } catch (Exception e) {
        }
      }
    }

    for (int i = 0; i < n; ++i) {
      Animation anim = animations[i];
      anim.finalFinish();
    }

    // if theatre was captured before animation, release it.
    if (capture) {
      theatre.release();
    }
  }