1SDL::Tutorial::AnimatioUns(e3r)Contributed Perl DocumentSaDtLi:o:nTutorial::Animation(3)
2
3
4

NAME

6       SDL::Tutorial::Animation
7
8   CATEGORY
9       Tutorials
10

SYNOPSIS

12               # to read this tutorial
13               $ perldoc SDL::Tutorial::Animation
14
15               # to create a demo animation program based on this tutorial
16               $ perl -MSDL::Tutorial::Animation=sdl_anim.pl -e 1
17

ANIMATING A RECTANGLE

19       Now that you can display a rectangle on the screen, the next step is to
20       animate that rectangle.  As with movies, there's no actual motion.
21       Computer animations are just very very fast slideshows.  The hard work
22       is creating nearly identical images in every slide (or frame, in
23       graphics terms).
24
25       Okay, it's not that difficult.
26
27       There is one small difficulty to address, however.  Once you blit one
28       surface onto another, the destination is changed permanently.  There's
29       no concept of layers here unless you write it yourself.  If you fail to
30       take this into account (and just about everyone does at first), you'll
31       end up with blurry graphics moving around on the screen.
32
33       There are two approaches to solve this problem, redrawing the screen on
34       every frame and saving and restoring the background for every object
35       drawn.
36
37   Redrawing the Screen
38       Since you have to draw the screen in the right order once to start with
39       it's pretty easy to make this into a loop and redraw things in the
40       right order for every frame.  Given a SDLx::App object $app, a
41       SDL::Rect $rect, and a SDL::Color $color, you only have to create a new
42       SDL::Rect $bg, representing the whole of the background surface and a
43       new mapped color $bg_color, representing the background color.  The
44       colors need to be mapped to the format of the current display. This is
45       done by SDL::Video::map_RGB.
46
47
48
49       my $color = SDL::Video::map_RGB (       $app->format,       $rect_r,
50             $rect_g,       $rect_b, );
51
52       my $bg_color = SDL::Video::map_RGB (       $app->format,
53             $bg_r,       $bg_g,       $bg_b, );
54
55
56
57       You can write a "draw_frame()" function as follows:
58
59
60
61               sub draw_frame
62               {
63                       my ($app, %args) = @_;
64
65                       SDL::Video::fill_rect($app,  $args{bg},   $args{bg_color}   );
66                       SDL::Video::fill_rect($app, $args{rect}, $args{rect_color} );
67                       SDL::Video::update_rects($app, $args{bg} );
68               }
69
70
71
72       Since you can change the "x" and "y" coordinates of a rect with the
73       "x()" and "y()" methods, you can move a rectangle across the screen
74       with a loop like this:
75
76
77
78               for my $x (0 .. 640)
79               {
80                       $rect->x( $x );
81                       draw_frame( $app,
82                               bg   => $bg,   bg_color   => $bg_color,
83                               rect => $rect, rect_color => $color,
84                       );
85               }
86
87
88
89       If $rect's starting y position is 190 and its height and width are 100,
90       the rectangle (er, square) will move across the middle of the screen.
91
92       Provided you can keep track of the proper order in which to redraw
93       rectangles and provided you don't need the optimal speed necessary
94       (since blitting every object takes more work than just blitting the
95       portions you need), this works quite well.
96
97   Undrawing the Updated Rectangle
98       If you need more speed or want to make a different complexity tradeoff,
99       you can take a snapshot of the destination rectangle before you blit
100       onto it.  That way, when you need to redraw, you can blit the old
101       snapshot back before blitting to the new position.
102
103       Note:  I have no idea how this will work in the face of alpha blending,
104       which, admittedly, I haven't even mentioned yet.  If you don't know
105       what this means, forget it.  If you do know what this means and know
106       why I'm waving my hands here, feel free to explain what should and what
107       does happen and why.  :)
108
109       With this technique, the frame-drawing subroutine has to be a little
110       more complicated.  Instead of the background rect, it needs a rect for
111       the previous position.  It also needs to do two updates (or must
112       perform some scary math to figure out the rectangle of the correct size
113       to "update()".  No thanks!).
114
115
116
117               sub undraw_redraw_rect
118               {
119                       my ($app, %args) = @_;
120
121                       SDL::Video::fill_rect($app, $args{old_rect}, $args{bg_color}   );
122                       SDL::Video::fill_rect($app,  $args{rect},     $args{rect_color} );
123                       SDL::Video::update_rects($app, $args{old_rect} );
124                       SDL::Video::update_rects($app, $args{rect} );
125               }
126
127
128
129       We'll need to create a new SDL::Rect, $old_rect, that is a duplicate of
130       $rect, at the same position at first.  You should already know how to
131       do this.
132
133       As before, the loop to call "undraw_redraw_rect()" would look something
134       like:
135
136
137
138               for my $x (0 .. 640)
139               {
140                       $rect->x( $x );
141
142                       undraw_redraw_rect( $app,
143                               rect       => $rect,  old_rect => $old_rect,
144                               rect_color => $color, bg_color => $bgcolor,
145                       );
146
147                       $old_rect->x( $x );
148               }
149
150
151
152       If you run this code, you'll probably notice that it's tremendously
153       faster than the previous version.  It may be too fast, where the
154       alternate technique was just fast enough.  There are a couple of good
155       ways to set a fixed animation speed regardless of the speed of the
156       processor and graphics hardware (provided they're good enough, which is
157       increasingly often the case), and we'll get to them soon.
158

SEE ALSO

160       SDL::Tutorial::Drawing
161           basic drawing with SDL Perl
162
163       SDL::Tutorial::Images
164           animating images
165

AUTHOR

167       chromatic, <chromatic@wgz.org>
168
169       Written for and maintained by the Perl SDL project,
170       <http://sdl.perl.org/>.  See "AUTHORS" in SDL.
171

BUGS

173       No known bugs.
174
176       Copyright (c) 2003 - 2004, chromatic.  All rights reserved.  This
177       module is distributed under the same terms as Perl itself, in the hope
178       that it is useful but certainly under no guarantee.
179
180
181
182perl v5.32.0                      2020-07-28       SDL::Tutorial::Animation(3)
Impressum