Term::Animation - ASCII sprite animation framework

      use Term::Animation;

      # Constructors
      $anim = Term::Animation->new();
      $anim = Term::Animation->new($curses_window);

    A framework to produce sprite animations using ASCII art.

    This module provides a framework to produce sprite animations using
    ASCII art. Each ASCII 'sprite' is given one or more frames, and placed
    into the animation as an 'animation object'. An animation object can
    have a callback routine that controls the position and frame of the

    If the constructor is passed no arguments, it assumes that it is running
    full screen, and behaves accordingly. Alternatively, it can accept a
    curses window (created with the Curses *newwin* call) as an argument,
    and will draw into that window.

    This example moves a small object across the screen from left to right.

        use Term::Animation;
        use Curses;

        $anim = Term::Animation->new();

        # set the delay for getch
        halfdelay( 2 );

        # create a simple shape we can move around
        $shape = "<=O=>";

        # turn our shape into an animation object
                     shape         => $shape,        # object shape
                     position      => [3, 7, 10],    # row / column / depth
                     callback_args => [1, 0, 0, 0],  # the default callback
                                                     #  routine takes a list
                                                     #  of x,y,z,frame deltas
                     wrap          => 1              # turn screen wrap on

        # animation loop
        while(1) {
          # run and display a single animation frame

          # use getch to control the frame rate, and get input at the
          # same time. (not a good idea if you are expecting much input)
          my $input = getch();
          if($input eq 'q') { last; }

        # cleanly end the animation, to avoid hosing up the user's terminal

    This illustrates how to draw your animation into an existing Curses

        use Term::Animation;
        use Curses;

        # Term::Animation will not call initscr for you if
        # you pass it a window

        $win = newwin(5,10,8,7);

        $anim = Term::Animation->new($win);

    Everything else would be identical to the previous example.

          $anim = Term::Animation->new();
          $anim = Term::Animation->new($curses_window);

        The constructor. Optionally takes an existing curses window to draw

                shape         => $shape,
                position      => [ 1, 2, 3 ],
                callback_args => [ 1, 0, 0 ]

        Creates a new Term::Animation::Entity object and adds it to the
        animation. This is identical to:

          my $entity = Term::Animation::Entity->new(...);

        See Term::Animation::Entity/PARAMETERS and
        Term::Animation::Entity/new in Term::Animation::Entity for details
        on calling this method.

          $name = $anim->color_name( $color );

        Returns the full name of a color, given either a full name or a
        single character abbreviation.

          $id = $anim->color_id( $color );

        Returns the single character abbreviation for a color, given either
        a full name or abbreviation.

          my $is_valid = $anim->is_valid_color($color_name);

        Returns true if the supplied string is a valid color name ('blue')
        or a valid color id ('b').

          my $state = $anim->color();

        Enable or disable ANSI color. This MUST be called immediately after
        creating the animation object if you want color, because the Curses
        start_color call must be made immediately. You can then turn color
        on and off whenever you want.

          $anim->background( $color );

        Change the background color. The default background color is black.
        You can only have one background color for the entire Curses window
        that the animation is running in.


        Perform a single animation cycle. Runs all of the callbacks, does
        collision detection, and updates the display.

          $tracking_framerate = $anim->track_framerate();

        Get or set the flag that indicates whether the module should keep
        track of the animation framerate. This is enabled by default.

          $frames_per_second = $anim->framerate();

        Returns the approximate number of frames being displayed per second,
        as indicated by calls to the *animate* method.

          my ($width, $height, $assumed_size) = $anim->screen_size();

        Returns the width and height of the screen. The third value returned
        is a boolean indicating whether or not the default screen size was
        used, because the size could not be determined.


        Call this if you suspect the terminal size has changed (eg. if you
        get a SIGWINCH signal). Call *remove_all_entities* after this if you
        want to recreate your animation from scratch.

          $anim->add_entity( $entity1, $entity2, $entity3 );

        Add one or more animation entities to the animation.

          $anim->del_entity( $entity_name );
          $anim->del_entity( $entity_ref );

        Removes an entity from the animation. Accepts either an entity name
        or a reference to the entity itself.


        Removes every animation object. This is useful if you need to start
        the animation over (eg. after a screen resize)

          $number_of_entities = $anim->entity_count();

        Returns the number of entities in the animation.

          $entity_list = $anim->get_entities();

        Returns a reference to a list of all entities in the animation.

          $entity_list = $anim->get_entities_of_type( $type );

        Returns a reference to a list of all entities in the animation that
        have the given type.

          my $is_living = $anim->is_living( $entity );

        Return 1 if the entity name or reference is in the animation and is
        not scheduled for deletion. Returns 0 otherwise.

          $entity_ref = $anim->entity( $entity_name );

        If the animation contains an entity with the given name, the
        Term::Animation::Entity object associated with the name is returned.
        Otherwise, undef is returned.

          $width = $anim->width();

        Returns the width of the screen

          $height = $anim->height();

        Returns the height of the screen

          $size = $anim->size();

        Returns the number of characters in the curses window (width *


        Clear everything from the screen, and redraw what should be there.
        This should be called after *update_term_size*, or if the user
        indicates that the screen should be redrawn to get rid of artifacts.

          # gen_path (x,y,z, x,y,z, [ frame_pattern ], [ steps ])

          $anim->gen_path( $x1, $y1, $z1, $x2, $y2, $z2, [ 1, 2, 0, 2 ], 'longest' );

        Given beginning and end points, this will return a path for the
        entity to follow that can be given to the default callback routine,
        *move_entity*. The first set of x,y,z coordinates are the point the
        entity will begin at, the second set is the point the entity will
        end at.

        You can optionally supply a list of frames to cycle through. The
        list will be repeated as many times as needed to finish the path. If
        no list of frames is supplied, only the first frame will be used.

        You can also request the number of steps you would like for the
        entity to take to finish the path. The default is 'shortest'. Valid
        arguments are: longest The longer of the X and Y distances shortest
        The shorter of the X and Y distances X,Y or Z The x, y or z distance
         Explicitly specify the number of steps to take


        Run the Curses endwin function to get your terminal back to its
        normal mode. This is called automatically when the object is
        destroyed if the animation is running full screen (if you did not
        pass an existing Curses window to the constructor).

    Callback routines for all entities are called each time *animate* is
    called. A default callback routine is supplied, *move_entity*, which is
    sufficient for most basic movement. If you want to create an entity that
    exhibits more complex behavior, you will have to write a custom callback
    routine for it.

    Callback routines take two arguments, a reference to the
    Term::Animation::Entity object that it should act on, and a reference to
    the Term::Animation instance that called it. Any arguments required to
    tell the callback what to do with the object, or any state that needs to
    be maintained, should be put in the *callback_args* element of the
    object. *callback_args* is only referenced by the callback routine, and
    thus can contain any datastructure that you find useful.

    Here is an example custom callback that will make an entity move
    randomly around the screen:

      sub random_movement {
          my ($entity, $anim) = @_;

          # get the current position of the entity
          my ($x, $y, $z) = $entity->position();

          # we'll use callback_args to store the last axis we moved in
          my $last_move = $entity->callback_args();

          # if we moved in x last time, move in y this time
          if($last_move eq 'x') {
              # move by -1, 0 or 1
              $y += int(rand(3)) - 1; 
          } else {
              $x += int(rand(3)) - 1; 

          # return the absolute x,y,z coordinates to move to
          return ($x, $y, $z);

    The return value of your callback routine should be of the form:

        return ($x, $y, $z, $frame)

    $x, $y and $z represent the X, Y and Z coordinates to which the object
    should move. $frame is the frame number that the object should display,
    if it has multiple frames of animation. Any values that are unspecified
    or undef will remain unchanged.

    You can also call the default callback from within your callback, if you
    want it to handle movement for you. For example, if your callback is
    simply used to decide when an entity should die:

      sub wait_for_file {
          my ($entity, $anim) = @_;

          # kill this entity if a certain file shows up
          if(-e "/path/to/file") {

          # use the default callback to handle the actual movement
          return $entity->move_entity($anim);

    If you use this, be aware that *move_entity* relies on *callback_args*,
    so you cannot use it to store your own arbitrary data.

    ANSI color is available for terminals that support it. Only a single
    background color can be used for the window (it would look terrible in
    most cases otherwise anyway). Colors for entities are specified by using
    a 'mask' that indicates the color for each character. For example, say
    we had a single frame of a bird:

      $bird = q#

      ---. .-. .---
           \ /
           " "

    To indicate the colors you want to use for the bird, create a matching
    mask, with the first letter of each color in the appropriate position
    (except black, which is 'k'). Pass this mask as the *color* parameter.

      $mask = q#

           B B
           Y Y

    When specifying a color, using uppercase indicates the color should be
    bold. So 'BLUE' or 'B' means bold blue, and 'blue' or 'b' means non-bold
    blue. 'Blue' means you get an error message.

    You can also provide a default color with the default_color parameter.
    This color will be used for any character that does not have an entry in
    the mask. If you want the entire entity to be a single color, you can
    just provide a default color with no mask.

    The available colors are: red, green, blue, cyan, magenta, yellow, black
    and white.

    Here's an example call to build_object for the bird above.

        $anim->new_entity (
                  name              => "Bird",
                  shape             => $bird,
                  position          => [ 5, 8, 7 ],
                  callback_args     => [ 1, 2, 0, 0 ],
                  color             => $mask,
                  default_color     => "BLUE"

    Kirk Baucom,