1SDL::Tutorial::AnimatioUns(e3r)Contributed Perl DocumentSaDtLi:o:nTutorial::Animation(3)
2
3
4
6 SDL::Tutorial::Animation
7
9 # to read this tutorial
10 $ perldoc SDL::Tutorial::Animation
11
12 # to create a demo animation program based on this tutorial
13 $ perl -MSDL::Tutorial::Animation=sdl_anim.pl -e 1
14
16 Now that you can display a rectangle on the screen, the next step is to
17 animate that rectangle. As with movies, there's no actual motion.
18 Computer animations are just very very fast slideshows. The hard work
19 is creating nearly identical images in every slide (or frame, in graph‐
20 ics terms).
21
22 Okay, it's not that difficult.
23
24 There is one small difficulty to address, however. Once you blit one
25 surface onto another, the destination is changed permanently. There's
26 no concept of layers here unless you write it yourself. If you fail to
27 take this into account (and just about everyone does at first), you'll
28 end up with blurry graphics moving around on the screen.
29
30 There are two approaches to solve this problem, redrawing the screen on
31 every frame and saving and restoring the background for every object
32 drawn.
33
34 Redrawing the Screen
35
36 Since you have to draw the screen in the right order once to start with
37 it's pretty easy to make this into a loop and redraw things in the
38 right order for every frame. Given a SDL::App object $app, a SDL::Rect
39 $rect, and a SDL::Color $color, you only have to create a new SDL::Rect
40 $bg, representing the whole of the background surface and a new
41 SDL::Color $bg_color, representing the background color. You can write
42 a "draw_frame()" function as follows:
43
44 sub draw_frame
45 {
46 my ($app, %args) = @_;
47
48 $app->fill( $args{ bg }, $args{ bg_color } );
49 $app->fill( $args{rect}, $args{rect_color} );
50 $app->update( $args{bg} );
51 }
52
53 Since you can change the "x" and "y" coordinates of a rect with the
54 "x()" and "y()" methods, you can move a rectangle across the screen
55 with a loop like this:
56
57 for my $x (0 .. 640)
58 {
59 $rect->x( $x );
60 draw_frame( $app,
61 bg => $bg, bg_color => $bg_color,
62 rect => $rect, rect_color => $color,
63 );
64 }
65
66 If $rect's starting y position is 190 and its height and width are 100,
67 the rectangle (er, square) will move across the middle of the screen.
68
69 Provided you can keep track of the proper order in which to redraw rec‐
70 tangles and provided you don't need the optimal speed necessary (since
71 blitting every object takes more work than just blitting the portions
72 you need), this works quite well.
73
74 Undrawing the Updated Rectangle
75
76 If you need more speed or want to make a different complexity tradeoff,
77 you can take a snapshot of the destination rectangle before you blit
78 onto it. That way, when you need to redraw, you can blit the old snap‐
79 shot back before blitting to the new position.
80
81 Note: I have no idea how this will work in the face of alpha blending,
82 which, admittedly, I haven't even mentioned yet. If you don't know
83 what this means, forget it. If you do know what this means and know
84 why I'm waving my hands here, feel free to explain what should and what
85 does happen and why. :)
86
87 With this technique, the frame-drawing subroutine has to be a little
88 more complicated. Instead of the background rect, it needs a rect for
89 the previous position. It also needs to do two updates (or must per‐
90 form some scary math to figure out the rectangle of the correct size to
91 "update()". No thanks!).
92
93 sub undraw_redraw_rect
94 {
95 my ($app, %args) = @_;
96
97 $app->fill( $args{old_rect}, $args{bg_color} );
98 $app->fill( $args{rect], $args{rect_color} );
99 $app->update( $args{old_rect}, $args{rect} );
100 }
101
102 We'll need to create a new SDL::Rect, $old_rect, that is a duplicate of
103 $rect, at the same position at first. You should already know how to
104 do this.
105
106 As before, the loop to call "undraw_redraw_rect()" would look something
107 like:
108
109 for my $x (0 .. 640)
110 {
111 $rect->x( $x );
112
113 undraw_redraw_rect( $app,
114 rect => $rect, old_rect => $old_rect,
115 rect_color => $color, bg_color => $bgcolor,
116 );
117
118 $old_rect->x( $x );
119 }
120
121 If you run this code, you'll probably notice that it's tremendously
122 faster than the previous version. It may be too fast, where the alter‐
123 nate technique was just fast enough. There are a couple of good ways
124 to set a fixed animation speed regardless of the speed of the processor
125 and graphics hardware (provided they're good enough, which is increas‐
126 ingly often the case), and we'll get to them soon.
127
129 SDL::Tutorial::Drawing
130 basic drawing with SDL Perl
131
132 SDL::Tutorial::Images
133 animating images
134
136 chromatic, <chromatic@wgz.org>
137
138 Written for and maintained by the Perl SDL project,
139 <http://sdl.perl.org/>.
140
142 No known bugs.
143
145 Copyright (c) 2003 - 2004, chromatic. All rights reserved. This mod‐
146 ule is distributed under the same terms as Perl itself, in the hope
147 that it is useful but certainly under no guarantee.
148
149
150
151perl v5.8.8 2006-08-28 SDL::Tutorial::Animation(3)