| Term::Animation
NAME
Term::Animation - ASCII sprite animation framework
SYNOPSIS
use Term::Animation;
# Constructors
$anim = Term::Animation->new();
$anim = Term::Animation->new($curses_window);
ABSTRACT
A framework to produce sprite animations using ASCII art.
DESCRIPTION
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
object.
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.
EXAMPLES
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
$anim->new_entity(
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
$anim->animate();
# 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
$anim->end();
This illustrates how to draw your animation into an existing Curses
window.
use Term::Animation;
use Curses;
# Term::Animation will not call initscr for you if
# you pass it a window
initscr();
$win = newwin(5,10,8,7);
$anim = Term::Animation->new($win);
Everything else would be identical to the previous example.
METHODS
*new*
$anim = Term::Animation->new();
$anim = Term::Animation->new($curses_window);
The constructor. Optionally takes an existing curses window to draw
in.
*new_entity*
$anim->new_entity(
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(...);
$anim->add_entity($entity);
See Term::Animation::Entity/PARAMETERS and
Term::Animation::Entity/new in Term::Animation::Entity for details
on calling this method.
*color_name*
$name = $anim->color_name( $color );
Returns the full name of a color, given either a full name or a
single character abbreviation.
*color_id*
$id = $anim->color_id( $color );
Returns the single character abbreviation for a color, given either
a full name or abbreviation.
*is_valid_color*
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').
*color*
my $state = $anim->color();
$anim->color($new_state);
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.
*background*
$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.
*animate*
$anim->animate();
Perform a single animation cycle. Runs all of the callbacks, does
collision detection, and updates the display.
*track_framerate*
$anim->track_framerate(1);
$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.
*framerate*
$frames_per_second = $anim->framerate();
Returns the approximate number of frames being displayed per second,
as indicated by calls to the *animate* method.
*screen_size*
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.
*update_term_size*
$anim->update_term_size();
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.
*add_entity*
$anim->add_entity( $entity1, $entity2, $entity3 );
Add one or more animation entities to the animation.
*del_entity*
$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.
*remove_all_entities*
$anim->remove_all_entities();
Removes every animation object. This is useful if you need to start
the animation over (eg. after a screen resize)
*entity_count*
$number_of_entities = $anim->entity_count();
Returns the number of entities in the animation.
*get_entities*
$entity_list = $anim->get_entities();
Returns a reference to a list of all entities in the animation.
*get_entities_of_type*
$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.
*is_living*
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*
$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*
$width = $anim->width();
Returns the width of the screen
*height*
$height = $anim->height();
Returns the height of the screen
*size()*
$size = $anim->size();
Returns the number of characters in the curses window (width *
height)
*redraw_screen*
$anim->redraw_screen();
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*
# 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
*end*
$anim->end();
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
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') {
$entity->callback_args('y');
# move by -1, 0 or 1
$y += int(rand(3)) - 1;
} else {
$entity->callback_args('x');
$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") {
$entity->kill();
return();
}
# 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.
COLOR
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#
---. .-. .---
--\'v'/--
\ /
" "
#;
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#
BBBB BBB BBBB
BBBWYWBBB
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"
);
AUTHOR
Kirk Baucom,
SEE ALSO
Curses
| |