=pod =head1 NAME SDLx::Sprite::Animated - create animated SDL sprites easily! =head1 CATEGORY Extension =head1 SYNOPSIS use SDLx::Sprite::Animated; # simplest possible form, where 'hero.png' is an image containing # fixed-length sprites in sequence. It doesn't matter if they are # placed vertically or horizontally, as long as the the widest # side is a multiple of the (narrowest) other. The widget will # automatically divide it in the proper frames, provided there is # no slack space between each frame. my $animation = SDLx::Sprite::Animated->new->load('hero.png'); # that's it! Defaults are sane enough to DWIM in simple cases, # so you just have to call draw() on the right place. If you # need to setup your animation or have more control over it, # feel free to use the attributes and methods below. # these are the most useful methods to use in your game loop # (or wherever you want to manipulate the animation): $animation->next; $animation->previous; $animation->reset; $animation->current_frame; # current frame number $animation->current_loop; # current loop number # you can control positioning just like a regular SDLx::Sprite: $animation->rect $animation->x; $animation->y; # just like a regular Sprite, we fetch our source rect from ->clip, # updating it on each call to ->next (or ->previous, or ->reset). # If source rects for your animation are further appart (or less) # than the rect's width and height, you can adjust the animation # x/y offsets: $animation->step_x(15); $animation->step_y(30); $animation->draw($screen); # remember to do this! :) # we can also call ->next() automatically after each draw(): $animation->start; $animation->stop; # default is to go to the next frame at each draw(). If this is # too fast for you, change the attribute below: $animation->ticks_per_frame(10); # select type of animation loop when it reaches the last frame: $animation->type('circular'); # restarts loop at the beginning $animation->type('reverse'); # goes backwards $animation->max_loops(3); 0 or undef for infinite looping # as usual, you can setup most of the above during object spawning my $animation = SDLx::Sprite::Animated->new( image => 'hero.png', rect => SDL::Rect->new(...), step_x => 20, step_y => 0, ... ); =head1 DESCRIPTION An animation is a series of frames that are played in order. Frames are loaded from an image, usually referred to as a Sprite Sheet or Sprite Strip. This module let's you interact with such strips and create sprite animations just as easily as you would manipulate a regular SDLx::Sprite object. =head1 WARNING! VOLATILE CODE AHEAD This is a new module and the API is subject to change without notice. If you care, please join the discussion on the #sdl IRC channel in I. All thoughts on further improving the API are welcome. You have been warned :) =head1 ATTRIBUTES AND METHODS SDLx::Sprite::Animated is a B of L<< SDLx::Sprite >>, inheriting all its attributes and methods. Please refer to that module's documentation for information on those. The one difference in behavior is that, while a standard SDLx::Sprite uses C<< ->clip() >> to select the part of the surface to display, SDLx::Sprite::Animated treats C<< ->clip() >> as the B rect, from which to start the animation. The following attributes and methods are available: =head2 new =head2 new( %options ) Creates a new SDLx::Sprite::Animated object. No option is mandatory. It accepts all the options from a regular SDLx::Sprite object plus these: =over 4 =item * step_x => $integer Uses $integer as the number of pixels to move on the x-axis (left-to-right, 0 being no dislocation whatsoever, when the strip goes from top to bottom) to reach the next frame. =item * step_y => $integer Uses $integer as the number of pixels to move on the y-axis (top-to-bottom, 0 being no dislocation whatsoever, when the strip goes from left to right) to reach the next frame. =item * max_loops => $integer Uses $integer as the number of times to loop the animation (when it reaches the end of the strip). =item * ticks_per_frame => $integer Uses $integer to set how many calls to draw() must be issued before we go to the next frame during autoplay (i.e. between calls to start() and stop()). =item * type => $string Uses $string to set the type of animation loop when it reaches the last frame in the strip. See the type() method below for information on available looping types. =item * sequences => { $string => [ [ $x1, $y1 ], [ $x2, $y2 ], ... ], ... } Uses the supplied hashref to define named sequences of frames. =item * sequence => $string Uses $string to set the current sequence. =back =head2 step_x() =head2 step_x( $integer ) Uses $integer as the number of pixels to move on the x-axis (left-to-right, 0 being no dislocation whatsoever, when the strip goes from top to bottom) to reach the next frame. Defaults to the same width as the clip() rect. =head2 step_y() =head2 step_y( $integer ) Uses $integer as the number of pixels to move on the y-axis (top-to-bottom, 0 being no dislocation whatsoever, when the strip goes from left to right) to reach the next frame. Defaults to the same height as the clip() rect. =head2 max_loops() =head2 max_loops( $integer ) Uses $integer as the number of times to loop the animation (when it reaches the end of the strip). After that B<< all calls to previous() or next() will be no-ops >>. Set it to C<0> or C to allow infinite loops. Default is 0 (infinite). =head2 ticks_per_frame() =head2 ticks_per_frame( $integer ) Uses $integer to set how many calls to draw() must be issued before we go to the next frame during autoplay (i.e. between calls to start() and stop()). Default is just 1 tick per frame, so you might want to change this if it's too fast. =head2 type() =head2 type( $string ) Uses $string to set the type of animation loop when it reaches the last frame in the strip. Available looping types are: =over 4 =item * 'circular' Restarts loop at the beginning of the strip. If you have 4 frames, the flow will be 1-2-3-4-1-2-3-4-1-2-3-4-1-2-... up until the number of loops you set in the max_loops() attribute. =item * 'reverse' Loops back and forth on the strip. If you have 4 frames, the flow will be 1-2-3-4-3-2-1-2-3-4-3-2-... up until the number of loops you set in the max_loops() attribute. =back Case is irrelevant for type(), so for example 'Circular', 'CIRCULAR' and 'CiRcUlAr' are all accepted as 'circular'. The return value is guaranteed to be lowercase. Default value is 'circular'. =head2 set_sequences( $string => [ [ $x1, $y1 ], [ $x2, $y2 ], ... ], ... ) Uses the supplied hashref to define named sequences of frames. Replaces any previously defined sequences. =head2 sequence( $string ) Uses $string to set the current sequence. Goes to the first frame in the sequence and resets the loop counter. =head2 next() Goes to the next frame in the strip. Calling this method will also reset the tick counter used by ticks_per_frame(). If max_loops() has reached its limit, this will be a no-op. Returns the object, allowing method chaining. =head2 previous() Goes to the previous frame in the strip. Calling this method will also reset the tick counter used by ticks_per_frame(). If max_loops() has reached its limit, this will be a no-op. Returns the object, allowing method chaining. =head2 reset() Goes to the first frame in the strip, meaning whatever clip is set to. If max_loops() has reached its limit, this will be a no-op. Returns the object, allowing method chaining. =head2 current_frame() Returns the current frame number. Note that this is 1-based (first frame is 1, second is 2, etc). =head2 current_loop() Returns the loop counter, i.e. which run number is it at. This is also 1-based (first time is 1, second time is 2, etc). Note that we only keep track of the counter if max_loops() is set to a finite number. Otherwise, this will be a no-op. =head1 start() After you call this method, the object will issue a call to C<< ->next() >> automatically for you every time C<< ->draw() >> is called C<< ticks_per_frame() >> times. If you want to stop autoplay, see C<< stop() >> below. Default is off (no autoplay). =head1 stop() Stops autoplay. After you call this, the object will need you to call C<< ->previous() >> and C<< ->next() >> explicitly to change frames. To resume autoplay from wherever you are, use C<< start() >>. If you want to restart autoplay from the initial frame, just do: $sprite->reset->start; =head1 AUTHORS See L. =head1 SEE ALSO L<< SDL::Surface >>, L<< SDL >>