PageRenderTime 12ms CodeModel.GetById 1ms app.highlight 4ms RepoModel.GetById 2ms app.codeStats 0ms

/lib/pods/SDL/Tutorial/Animation.pod

http://github.com/PerlGameDev/SDL
Unknown | 195 lines | 133 code | 62 blank | 0 comment | 0 complexity | 73b639b98c01110718f35be167ae5346 MD5 | raw file
  1
  2=pod
  3
  4=head1 NAME
  5
  6SDL::Tutorial::Animation
  7
  8=head2 CATEGORY
  9
 10Tutorials
 11
 12=head1 SYNOPSIS
 13
 14	# to read this tutorial
 15	$ perldoc SDL::Tutorial::Animation
 16
 17	# to create a demo animation program based on this tutorial
 18	$ perl -MSDL::Tutorial::Animation=sdl_anim.pl -e 1
 19
 20=head1 ANIMATING A RECTANGLE
 21
 22Now that you can display a rectangle on the screen, the next step is to animate
 23that rectangle.  As with movies, there's no actual motion.  Computer animations are just very very fast slideshows.  The hard work is creating nearly identical images in every slide (or frame, in graphics terms).
 24
 25Okay, it's not that difficult.
 26
 27There is one small difficulty to address, however.  Once you blit one surface
 28onto another, the destination is changed permanently.  There's no concept of
 29layers here unless you write it yourself.  If you fail to take this into
 30account (and just about everyone does at first), you'll end up with blurry
 31graphics moving around on the screen.
 32
 33There are two approaches to solve this problem, redrawing the screen on every
 34frame and saving and restoring the background for every object drawn.
 35
 36=head2 Redrawing the Screen
 37
 38Since you have to draw the screen in the right order once to start with it's
 39pretty easy to make this into a loop and redraw things in the right order for
 40every frame.  Given a L<SDLx::App> object C<$app>, a L<SDL::Rect> C<$rect>, and
 41a L<SDL::Color> C<$color>, you only have to create a new SDL::Rect C<$bg>,
 42representing the whole of the background surface and a new mapped color 
 43C<$bg_color>, representing the background color.  The colors need to be mapped 
 44to the format of the current display. This is done by L<SDL::Video::map_RGB>.
 45
 46S< >
 47
 48my $color = SDL::Video::map_RGB (
 49	 $app->format,
 50	 $rect_r,
 51	 $rect_g,
 52	 $rect_b,
 53);
 54
 55my $bg_color = SDL::Video::map_RGB (
 56	 $app->format,
 57 	 $bg_r,
 58	 $bg_g,
 59	 $bg_b,
 60);
 61
 62S< >
 63
 64
 65
 66You can write a C<draw_frame()> function as follows:
 67
 68S< >
 69
 70	sub draw_frame
 71	{
 72		my ($app, %args) = @_;
 73
 74		SDL::Video::fill_rect($app,  $args{bg},   $args{bg_color}   );
 75		SDL::Video::fill_rect($app, $args{rect}, $args{rect_color} );
 76		SDL::Video::update_rects($app, $args{bg} );
 77	}
 78
 79S< >
 80
 81Since you can change the C<x> and C<y> coordinates of a rect with the C<x()>
 82and C<y()> methods, you can move a rectangle across the screen with a loop like
 83this:
 84
 85S< >
 86
 87	for my $x (0 .. 640)
 88	{
 89		$rect->x( $x );
 90		draw_frame( $app,
 91			bg   => $bg,   bg_color   => $bg_color,
 92			rect => $rect, rect_color => $color,
 93		);
 94	}
 95
 96S< >
 97
 98If C<$rect>'s starting y position is 190 and its height and width are 100, the
 99rectangle (er, square) will move across the middle of the screen.
100
101Provided you can keep track of the proper order in which to redraw rectangles
102and provided you don't need the optimal speed necessary (since blitting every
103object takes more work than just blitting the portions you need), this works
104quite well.
105
106=head2 Undrawing the Updated Rectangle
107
108If you need more speed or want to make a different complexity tradeoff, you can
109take a snapshot of the destination rectangle I<before> you blit onto it.  That
110way, when you need to redraw, you can blit the old snapshot back before
111blitting to the new position.
112
113B<Note:>  I have no idea how this will work in the face of alpha blending,
114which, admittedly, I haven't even mentioned yet.  If you don't know what this
115means, forget it.  If you do know what this means and know why I'm waving my
116hands here, feel free to explain what should and what does happen and why.  :)
117
118With this technique, the frame-drawing subroutine has to be a little more
119complicated.  Instead of the background rect, it needs a rect for the previous
120position.  It also needs to do two updates (or must perform some scary math to
121figure out the rectangle of the correct size to C<update()>.  No thanks!).
122
123S< >
124
125	sub undraw_redraw_rect
126	{
127		my ($app, %args) = @_;
128
129		SDL::Video::fill_rect($app, $args{old_rect}, $args{bg_color}   );
130		SDL::Video::fill_rect($app,  $args{rect},     $args{rect_color} );
131		SDL::Video::update_rects($app, $args{old_rect} );
132		SDL::Video::update_rects($app, $args{rect} );
133	}
134
135S< >
136
137We'll need to create a new SDL::Rect, C<$old_rect>, that is a duplicate of
138C<$rect>, at the same position at first.  You should already know how to do
139this.
140
141As before, the loop to call C<undraw_redraw_rect()> would look something like:
142
143S< >
144
145	for my $x (0 .. 640)
146	{
147		$rect->x( $x );
148
149		undraw_redraw_rect( $app,
150			rect       => $rect,  old_rect => $old_rect,
151			rect_color => $color, bg_color => $bgcolor,
152		);
153
154		$old_rect->x( $x );
155	}
156
157S< >
158
159If you run this code, you'll probably notice that it's tremendously faster than
160the previous version.  It may be too fast, where the alternate technique was
161just fast enough.  There are a couple of good ways to set a fixed animation
162speed regardless of the speed of the processor and graphics hardware (provided
163they're good enough, which is increasingly often the case), and we'll get to
164them soon.
165
166=head1 SEE ALSO
167
168=over 4
169
170=item L<SDL::Tutorial::Drawing>
171
172basic drawing with SDL Perl
173
174=item L<SDL::Tutorial::Images>
175
176animating images
177
178=back
179
180=head1 AUTHOR
181
182chromatic, E<lt>chromatic@wgz.orgE<gt>
183
184Written for and maintained by the Perl SDL project, L<http://sdl.perl.org/>.
185See L<SDL/AUTHORS>.
186
187=head1 BUGS
188
189No known bugs.
190
191=head1 COPYRIGHT
192
193Copyright (c) 2003 - 2004, chromatic.  All rights reserved.  This module is
194distributed under the same terms as Perl itself, in the hope that it is useful
195but certainly under no guarantee.