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