update
[sdlgit/SDL-Site.git] / pages / SDL-Tutorial-Animation.html-inc
1 <div class="pod">
2 <!-- INDEX START -->
3 <h3 id="TOP">Index</h3>
4
5 <ul>
6 <li>
7 <ul><li><a href="#Redrawing_the_Screen">Redrawing the Screen</a></li>
8 <li><a href="#Undrawing_the_Updated_Rectangle">Undrawing the Updated Rectangle</a></li>
9 </ul>
10 </li>
11 <li><a href="#SEE_ALSO">SEE ALSO</a></li>
12 <li><a href="#AUTHOR">AUTHOR</a></li>
13 <li><a href="#BUGS">BUGS</a></li>
14 <li><a href="#COPYRIGHT">COPYRIGHT</a>
15 </li>
16 </ul><hr />
17 <!-- INDEX END --><a href="assets/Animation.jpg" target="_blank"><img src="assets/Animation.jpg" style="height: 160px" alt="Animation.jpg"/></a><hr />
18
19 <h2 id="Redrawing_the_Screen">Redrawing the Screen</h2>
20 <div id="Redrawing_the_Screen_CONTENT">
21 <p>Since you have to draw the screen in the right order once to start with it's
22 pretty easy to make this into a loop and redraw things in the right order for
23 every frame.  Given a <a href="http://search.cpan.org/perldoc?SDLx::App">SDLx::App</a> object <code>$app</code>, a <a href="SDL-Rect.html">SDL::Rect</a> <code>$rect</code>, and
24 a <a href="SDL-Color.html">SDL::Color</a> <code>$color</code>, you only have to create a new SDL::Rect <code>$bg</code>,
25 representing the whole of the background surface and a new mapped color 
26 <code>$bg_color</code>, representing the background color.  The colors need to be mapped 
27 to the format of the current display. This is done by <a href="/SDL-Video.html#map_RGB">SDL::Video::map_RGB</a>.</p>
28 <p>&nbsp;</p>
29 <p>my $color = SDL::Video::map_RGB (
30          $app-&gt;format,
31          $rect_r,
32          $rect_g,
33          $rect_b,
34 );</p>
35 <p>my $bg_color = SDL::Video::map_RGB (
36          $app-&gt;format,
37          $bg_r,
38          $bg_g,
39          $bg_b,
40 );</p>
41 <p>&nbsp;</p>
42
43
44
45
46
47
48
49 <p>You can write a <code>draw_frame()</code> function as follows:</p>
50 <p>&nbsp;</p>
51 <pre>   sub draw_frame
52         {
53                 my ($app, %args) = @_;
54
55                 SDL::Video::fill_rect($app,  $args{bg},   $args{bg_color}   );
56                 SDL::Video::fill_rect($app, $args{rect}, $args{rect_color} );
57                 SDL::Video::update_rects($app, $args{bg} );
58         }
59
60 </pre>
61 <p>&nbsp;</p>
62 <p>Since you can change the <code>x</code> and <code>y</code> coordinates of a rect with the <code>x()</code>
63 and <code>y()</code> methods, you can move a rectangle across the screen with a loop like
64 this:</p>
65 <p>&nbsp;</p>
66 <pre>   for my $x (0 .. 640)
67         {
68                 $rect-&gt;x( $x );
69                 draw_frame( $app,
70                         bg   =&gt; $bg,   bg_color   =&gt; $bg_color,
71                         rect =&gt; $rect, rect_color =&gt; $color,
72                 );
73         }
74
75 </pre>
76 <p>&nbsp;</p>
77 <p>If <code>$rect</code>'s starting y position is 190 and its height and width are 100, the
78 rectangle (er, square) will move across the middle of the screen.</p>
79 <p>Provided you can keep track of the proper order in which to redraw rectangles
80 and provided you don't need the optimal speed necessary (since blitting every
81 object takes more work than just blitting the portions you need), this works
82 quite well.</p>
83
84 </div>
85 <h2 id="Undrawing_the_Updated_Rectangle">Undrawing the Updated Rectangle</h2>
86 <div id="Undrawing_the_Updated_Rectangle_CONT">
87 <p>If you need more speed or want to make a different complexity tradeoff, you can
88 take a snapshot of the destination rectangle <i>before</i> you blit onto it.  That
89 way, when you need to redraw, you can blit the old snapshot back before
90 blitting to the new position.</p>
91 <p><strong>Note:</strong>  I have no idea how this will work in the face of alpha blending,
92 which, admittedly, I haven't even mentioned yet.  If you don't know what this
93 means, forget it.  If you do know what this means and know why I'm waving my
94 hands here, feel free to explain what should and what does happen and why.  :)</p>
95 <p>With this technique, the frame-drawing subroutine has to be a little more
96 complicated.  Instead of the background rect, it needs a rect for the previous
97 position.  It also needs to do two updates (or must perform some scary math to
98 figure out the rectangle of the correct size to <code>update()</code>.  No thanks!).</p>
99 <p>&nbsp;</p>
100 <pre>   sub undraw_redraw_rect
101         {
102                 my ($app, %args) = @_;
103
104                 SDL::Video::fill_rect($app, $args{old_rect}, $args{bg_color}   );
105                 SDL::Video::fill_rect($app,  $args{rect},     $args{rect_color} );
106                 SDL::Video::update_rects($app, $args{old_rect} );
107                 SDL::Video::update_rects($app, $args{rect} );
108         }
109
110 </pre>
111 <p>&nbsp;</p>
112 <p>We'll need to create a new SDL::Rect, <code>$old_rect</code>, that is a duplicate of
113 <code>$rect</code>, at the same position at first.  You should already know how to do
114 this.</p>
115 <p>As before, the loop to call <code>undraw_redraw_rect()</code> would look something like:</p>
116 <p>&nbsp;</p>
117 <pre>   for my $x (0 .. 640)
118         {
119                 $rect-&gt;x( $x );
120
121                 undraw_redraw_rect( $app,
122                         rect       =&gt; $rect,  old_rect =&gt; $old_rect,
123                         rect_color =&gt; $color, bg_color =&gt; $bgcolor,
124                 );
125
126                 $old_rect-&gt;x( $x );
127         }
128
129 </pre>
130 <p>&nbsp;</p>
131 <p>If you run this code, you'll probably notice that it's tremendously faster than
132 the previous version.  It may be too fast, where the alternate technique was
133 just fast enough.  There are a couple of good ways to set a fixed animation
134 speed regardless of the speed of the processor and graphics hardware (provided
135 they're good enough, which is increasingly often the case), and we'll get to
136 them soon.</p>
137
138 </div>
139 <h1 id="SEE_ALSO">SEE ALSO</h1><p><a href="#TOP" class="toplink">Top</a></p>
140 <div id="SEE_ALSO_CONTENT">
141 <dl>
142         <dt><a href="SDL-Tutorial-Drawing.html">SDL::Tutorial::Drawing</a></dt>
143         <dd>
144                 <p>basic drawing with SDL Perl</p>
145         </dd>
146         <dt><a href="SDL-Tutorial-Images.html">SDL::Tutorial::Images</a></dt>
147         <dd>
148                 <p>animating images</p>
149         </dd>
150 </dl>
151
152 </div>
153 <h1 id="AUTHOR">AUTHOR</h1><p><a href="#TOP" class="toplink">Top</a></p>
154 <div id="AUTHOR_CONTENT">
155 <p>chromatic, &lt;chromatic@wgz.org&gt;</p>
156 <p>updated by kthakore, &lt;kthakore@cpan.org&gt;</p>
157 <p>Written for and maintained by the Perl SDL project, <a href="http://sdl.perl.org/">http://sdl.perl.org/</a>.</p>
158
159 </div>
160 <h1 id="BUGS">BUGS</h1><p><a href="#TOP" class="toplink">Top</a></p>
161 <div id="BUGS_CONTENT">
162 <p>No known bugs.</p>
163
164 </div>
165 <h1 id="COPYRIGHT">COPYRIGHT</h1><p><a href="#TOP" class="toplink">Top</a></p>
166 <div id="COPYRIGHT_CONTENT">
167 <p>Copyright (c) 2003 - 2004, chromatic.  All rights reserved.  This module is
168 distributed under the same terms as Perl itself, in the hope that it is useful
169 but certainly under no guarantee.
170 </p>
171
172 </div>
173 </div>