Removed unesscary files
[sdlgit/SDL_perl.git] / lib / SDL / Tutorial / Animation.pm
CommitLineData
bfd90409 1#!/usr/bin/env perl
2#
3# Animation.pm
4#
5# Copyright (C) 2005 David J. Goehrig <dgoehrig@cpan.org>
6#
7# ------------------------------------------------------------------------------
8#
9# This library is free software; you can redistribute it and/or
10# modify it under the terms of the GNU Lesser General Public
11# License as published by the Free Software Foundation; either
12# version 2.1 of the License, or (at your option) any later version.
13#
14# This library is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17# Lesser General Public License for more details.
18#
19# You should have received a copy of the GNU Lesser General Public
20# License along with this library; if not, write to the Free Software
21# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22#
23# ------------------------------------------------------------------------------
24#
25# Please feel free to send questions, suggestions or improvements to:
26#
27# David J. Goehrig
28# dgoehrig@cpan.org
29#
30
31package SDL::Tutorial::Animation;
32
33use strict;
34use SDL;
35use SDL::App;
36use SDL::Rect;
37use SDL::Color;
38
39# change these values as necessary
40my $title = 'My SDL Animation';
41my ($width, $height, $depth) = ( 640, 480, 16 );
42my ($bg_r, $bg_g, $bg_b) = ( 0x00, 0x00, 0x00 );
43my ($rect_r, $rect_g, $rect_b) = ( 0x00, 0x00, 0xff );
44my ($rect_width, $rect_height, $rect_y) = ( 100, 100, 190 );
45
46my $app = SDL::App->new(
47 -width => $width,
48 -height => $height,
49 -depth => $depth,
50);
51
52my $color = SDL::Color->new(
53 -r => $rect_r,
54 -g => $rect_g,
55 -b => $rect_b,
56);
57
58my $bg_color = SDL::Color->new(
59 -r => $bg_r,
60 -g => $bg_g,
61 -b => $bg_b,
62);
63
64my $background = SDL::Rect->new(
65 -width => $width,
66 -height => $height,
67);
68
69my $rect = create_rect();
70
71# your code here, perhaps
72for my $x (0 .. 640)
73{
74 $rect->x( $x );
75 draw_frame( $app,
76 bg => $background, bg_color => $bg_color,
77 rect => $rect, rect_color => $color,
78 );
79}
80
81# remove this line
82sleep 2;
83
84# XXX - if you know why I need to create a new rect here, please tell me!
85$rect = create_rect();
86my $old_rect = create_rect();
87
88# your code also here, perhaps
89for my $x (0 .. 640)
90{
91 $rect->x( $x );
92 draw_undraw_rect( $app,
93 rect => $rect, old_rect => $old_rect,
94 rect_color => $color, bg_color => $bg_color,
95 );
96 $old_rect->x( $x );
97}
98
99# your code almost certainly follows; remove this line
100sleep 2;
101
102sub create_rect
103{
104 return SDL::Rect->new(
105 -height => $rect_height,
106 -width => $rect_width,
107 -x => 0,
108 -y => $rect_y,
109 );
110}
111
112sub draw_frame
113{
114 my ($app, %args) = @_;
115
116 $app->fill( $args{bg}, $args{bg_color} );
117 $app->fill( $args{rect}, $args{rect_color} );
118 $app->update( $args{bg} );
119}
120
121sub draw_undraw_rect
122{
123 my ($app, %args) = @_;
124
125 $app->fill( $args{old_rect}, $args{bg_color} );
126 $app->fill( $args{rect}, $args{rect_color} );
127 $app->update( $args{old_rect} );
128 $app->update( $args{rect} );
129}
130END_HERE
131
1321;
133__END__
134
135=head1 NAME
136
137SDL::Tutorial::Animation
138
139=head1 SYNOPSIS
140
141 # to read this tutorial
142 $ perldoc SDL::Tutorial::Animation
143
144 # to create a demo animation program based on this tutorial
145 $ perl -MSDL::Tutorial::Animation=sdl_anim.pl -e 1
146
147=head1 ANIMATING A RECTANGLE
148
149Now that you can display a rectangle on the screen, the next step is to animate
150that 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).
151
152Okay, it's not that difficult.
153
154There is one small difficulty to address, however. Once you blit one surface
155onto another, the destination is changed permanently. There's no concept of
156layers here unless you write it yourself. If you fail to take this into
157account (and just about everyone does at first), you'll end up with blurry
158graphics moving around on the screen.
159
160There are two approaches to solve this problem, redrawing the screen on every
161frame and saving and restoring the background for every object drawn.
162
163=head2 Redrawing the Screen
164
165Since you have to draw the screen in the right order once to start with it's
166pretty easy to make this into a loop and redraw things in the right order for
167every frame. Given a L<SDL::App> object C<$app>, a L<SDL::Rect> C<$rect>, and
168a L<SDL::Color> C<$color>, you only have to create a new SDL::Rect C<$bg>,
169representing the whole of the background surface and a new SDL::Color
170C<$bg_color>, representing the background color. You can write a
171C<draw_frame()> function as follows:
172
173 sub draw_frame
174 {
175 my ($app, %args) = @_;
176
177 $app->fill( $args{ bg }, $args{ bg_color } );
178 $app->fill( $args{rect}, $args{rect_color} );
179 $app->update( $args{bg} );
180 }
181
182Since you can change the C<x> and C<y> coordinates of a rect with the C<x()>
183and C<y()> methods, you can move a rectangle across the screen with a loop like
184this:
185
186 for my $x (0 .. 640)
187 {
188 $rect->x( $x );
189 draw_frame( $app,
190 bg => $bg, bg_color => $bg_color,
191 rect => $rect, rect_color => $color,
192 );
193 }
194
195If C<$rect>'s starting y position is 190 and its height and width are 100, the
196rectangle (er, square) will move across the middle of the screen.
197
198Provided you can keep track of the proper order in which to redraw rectangles
199and provided you don't need the optimal speed necessary (since blitting every
200object takes more work than just blitting the portions you need), this works
201quite well.
202
203=head2 Undrawing the Updated Rectangle
204
205If you need more speed or want to make a different complexity tradeoff, you can
206take a snapshot of the destination rectangle I<before> you blit onto it. That
207way, when you need to redraw, you can blit the old snapshot back before
208blitting to the new position.
209
210B<Note:> I have no idea how this will work in the face of alpha blending,
211which, admittedly, I haven't even mentioned yet. If you don't know what this
212means, forget it. If you do know what this means and know why I'm waving my
213hands here, feel free to explain what should and what does happen and why. :)
214
215With this technique, the frame-drawing subroutine has to be a little more
216complicated. Instead of the background rect, it needs a rect for the previous
217position. It also needs to do two updates (or must perform some scary math to
218figure out the rectangle of the correct size to C<update()>. No thanks!).
219
220 sub undraw_redraw_rect
221 {
222 my ($app, %args) = @_;
223
224 $app->fill( $args{old_rect}, $args{bg_color} );
225 $app->fill( $args{rect], $args{rect_color} );
226 $app->update( $args{old_rect}, $args{rect} );
227 }
228
229We'll need to create a new SDL::Rect, C<$old_rect>, that is a duplicate of
230C<$rect>, at the same position at first. You should already know how to do
231this.
232
233As before, the loop to call C<undraw_redraw_rect()> would look something like:
234
235 for my $x (0 .. 640)
236 {
237 $rect->x( $x );
238
239 undraw_redraw_rect( $app,
240 rect => $rect, old_rect => $old_rect,
241 rect_color => $color, bg_color => $bgcolor,
242 );
243
244 $old_rect->x( $x );
245 }
246
247If you run this code, you'll probably notice that it's tremendously faster than
248the previous version. It may be too fast, where the alternate technique was
249just fast enough. There are a couple of good ways to set a fixed animation
250speed regardless of the speed of the processor and graphics hardware (provided
251they're good enough, which is increasingly often the case), and we'll get to
252them soon.
253
254=head1 SEE ALSO
255
256=over 4
257
258=item L<SDL::Tutorial::Drawing>
259
260basic drawing with SDL Perl
261
262=item L<SDL::Tutorial::Images>
263
264animating images
265
266=back
267
268=head1 AUTHOR
269
270chromatic, E<lt>chromatic@wgz.orgE<gt>
271
272Written for and maintained by the Perl SDL project, L<http://sdl.perl.org/>.
273
274=head1 BUGS
275
276No known bugs.
277
278=head1 COPYRIGHT
279
280Copyright (c) 2003 - 2004, chromatic. All rights reserved. This module is
281distributed under the same terms as Perl itself, in the hope that it is useful
282but certainly under no guarantee.