fixed read_file()
[sdlgit/SDL-Site.git] / pages / SDL-Tutorial-Images.html-inc
CommitLineData
b3ef54ec 1<div class="pod">
2<!-- INDEX START -->
3<h3 id="TOP">Index</h3>
4
5<ul><li><a href="#NAME">NAME</a></li>
6<li><a href="#SYNOPSIS">SYNOPSIS</a></li>
7<li><a href="#ANIMATING_IMAGES">ANIMATING IMAGES</a>
8<ul><li><a href="#Loading_Images">Loading Images</a></li>
9<li><a href="#Displaying_Images">Displaying Images</a></li>
10<li><a href="#Multi_Image_Animation">Multi-Image Animation</a></li>
11</ul>
12</li>
13<li><a href="#SEE_ALSO">SEE ALSO</a></li>
14<li><a href="#AUTHOR">AUTHOR</a></li>
15<li><a href="#BUGS">BUGS</a></li>
16<li><a href="#COPYRIGHT">COPYRIGHT</a>
17</li>
18</ul><hr />
19<!-- INDEX END -->
20
21<h1 id="NAME">NAME</h1><p><a href="#TOP" class="toplink">Top</a></p>
22<div id="NAME_CONTENT">
23<p>SDL::Tutorial::Images</p>
24
25</div>
26<h1 id="SYNOPSIS">SYNOPSIS</h1><p><a href="#TOP" class="toplink">Top</a></p>
27<div id="SYNOPSIS_CONTENT">
28<pre> # to read this tutorial
29 $ perldoc SDL::Tutorial::Images
30
31 # to create a demo animation program based on this tutorial
32 $ perl -MSDL::Tutorial::Images=sdl_images.pl -e 1
33
34</pre>
35
36</div>
37<h1 id="ANIMATING_IMAGES">ANIMATING IMAGES</h1><p><a href="#TOP" class="toplink">Top</a></p>
38<div id="ANIMATING_IMAGES_CONTENT">
39<p>Since you're already familiar with the concepts behind animation, it's time to
40learn how to work with images. As usual, the important point is that computer animation is just <i>simulating</i> motion by painting several slightly different frames to the screen every second.</p>
41<p>There are two ways to vary an image on screen. One is to change its
42coordinates so it's at a slightly different position. This is very easy to do;
43it's just like animating a rectangle. The other way is to change the image
44itself so it's slightly different. This is a little more difficult, as you'll
45need to draw the alternate image beforehand somehow.</p>
46
47</div>
48<h2 id="Loading_Images">Loading Images</h2>
49<div id="Loading_Images_CONTENT">
50<p>As usual, start with an <cite>SDL::App</cite> object representing the image window. Then
51preload the image file. This is easy; just pass the <code>name</code> parameter to the
52<cite>SDL::Surface</cite> constructor:</p>
53<p>&nbsp;</p>
54<pre> use SDL::Surface;
55
56 my $frame = SDL::Surface-&gt;new( -name =&gt; 'frame1.png' );
57
58</pre>
59<p>&nbsp;</p>
60<p><strong>Note:</strong> you'll need to have compiled SDL Perl (and probably SDL) to support
61JPEG and PNG files for this to work.</p>
62<p>That's it; now you have an SDL::Surface object containing the image. You can
63use the <code>height()</code>, <code>width()</code>, and <code>bpp()</code> methods to retrieve its height,
64width, and bits per pixel, if you need them.</p>
65
66</div>
67<h2 id="Displaying_Images">Displaying Images</h2>
68<div id="Displaying_Images_CONTENT">
69<p>Drawing an image onto the screen requires blitting it from one surface to
70another. (Remember, &quot;blitting&quot; means copying bits in memory.) The <code>blit()</code>
71method of SDL::Surface objects comes in handy. Its arguments are a little odd,
72though. Assuming <code>$app</code> is the SDL::App object, as usual:</p>
73<p>&nbsp;</p>
74<pre> use SDL::Rect;
75
76 my $frame_rect = SDL::Rect-&gt;new(
77 -height =&gt; $frame-&gt;height(),
78 -width =&gt; $frame-&gt;width(),
79 -x =&gt; 0,
80 -y =&gt; 0,
81 );
82
83 my $dest_rect = SDL::Rect-&gt;new(
84 -height =&gt; $frame-&gt;height(),
85 -width =&gt; $frame-&gt;width(),
86 -x =&gt; 0,
87 -y =&gt; 0,
88 );
89
90 $frame-&gt;blit( $frame_rect, $app, $dest_rect );
91 $app-&gt;update( $dest_rect );
92
93</pre>
94<p>&nbsp;</p>
95<p>Here we have two <cite>SDL::Rect</cite> objects which represent rectangular regions of a
96Surface. <code>$frame_rect</code> represents the entire area of <code>$frame</code>, while
97<code>$dest_rect</code> represents the area of the main window in which to blit the
98frame. This may be clearer with more descriptive variable names:</p>
99<p>&nbsp;</p>
100<pre> $source_surface-&gt;blit(
101 $area_of_source_to_blit,
102 $destination_surface,
103 $destination_area
104 );
105
106</pre>
107<p>&nbsp;</p>
108<p>As usual, call <code>update()</code> on <code>$app</code> to see the change.</p>
109<p>Requiring the source and destination Rect objects may seem tedious in this
110simple example, but it's highly useful for copying only part of surface to part
111of another. For example, animating this image is a matter of changing the <code>x</code>
112and <code>y</code> coordinates of <code>$dest_rect</code>:</p>
113<p>&nbsp;</p>
114<pre> for my $x ( 1 .. 100 )
115 {
116 $dest_rect-&gt;x( $x );
117 $frame-&gt;blit( $frame_rect, $app, $dest_rect );
118 $app-&gt;update( $dest_rect );
119 }
120
121</pre>
122<p>&nbsp;</p>
123<p>Of course, you'll have to redraw all or part of the screen to avoid artifacts,
124as discussed in the previous tutorial.</p>
125
126</div>
127<h2 id="Multi_Image_Animation">Multi-Image Animation</h2>
128<div id="Multi_Image_Animation_CONTENT">
129<p>That covers moving a single image around the screen. What if you want
130something more? For example, what if you want to animate a stick figure
131walking?</p>
132<p>You'll need several frames, just as in a flip-book. Each frame should be slightly different than the one before it. It's probably handy to encapsulate all of this in a <code>Walker</code> class:</p>
133<p>&nbsp;</p>
134<pre> package Walker;
135
136 use SDL::Surface;
137
138 sub new
139 {
140 my ($class, @images) = @_;
141 my $self = [ map { SDL::Surface-&gt;new( -name =&gt; $_ ) } @images ];
142
143 bless $self, $class;
144 }
145
146 sub next_frame
147 {
148 my $self = shift;
149 my $frame = shift @$self;
150
151 push @$self, $frame;
152 return $frame;
153 }
154
155</pre>
156<p>&nbsp;</p>
157<p>To use this class, instantiate an object:</p>
158<p>&nbsp;</p>
159<pre> my $walker = Walker-&gt;new( 'frame1.png', 'frame2.png', 'frame3.png' );
160
161</pre>
162<p>&nbsp;</p>
163<p>Then call <code>next_frame()</code> within the loop:</p>
164<p>&nbsp;</p>
165<pre> for my $x ( 1 .. 100 )
166 {
167 my $frame = $walker-&gt;next_frame();
168
169 $dest_rect-&gt;x( $x );
170 $frame-&gt;blit( $frame_rect, $app, $dest_rect );
171 $app-&gt;update( $dest_rect );
172 }
173
174</pre>
175<p>&nbsp;</p>
176<p>Again, the rest of the frame drawing is missing from this example so as not to
177distract from this technique. You'll probably want to abstract the undrawing
178and redrawing into a separate subroutine so you don't have to worry about it
179every time.</p>
180<p>It'd be easy to make <code>next_frame()</code> much smarter, selecting an image
181appropriate to the direction of travel, using a bored animation when the
182character is no longer moving, or adding other characteristics to the
183character. As you can see, the hard part of this technique is generating the
184images beforehand. That can add up to a tremendous amount of art and that's
185one reason for the popularity of 3D models... but that's another tutorial much
186further down the road.</p>
187<p>More importantly, it's time to discuss how to make these animations run more
188smoothly. More on that next time.</p>
189
190</div>
191<h1 id="SEE_ALSO">SEE ALSO</h1><p><a href="#TOP" class="toplink">Top</a></p>
192<div id="SEE_ALSO_CONTENT">
193<dl>
194 <dt><cite>SDL::Tutorial</cite></dt>
195 <dd>
196 <p>basic SDL tutorial</p>
197 </dd>
198 <dt><cite>SDL::Tutorial::Animation</cite></dt>
199 <dd>
200 <p>non-image animation</p>
201 </dd>
202</dl>
203
204</div>
205<h1 id="AUTHOR">AUTHOR</h1><p><a href="#TOP" class="toplink">Top</a></p>
206<div id="AUTHOR_CONTENT">
207<p>chromatic, &lt;chromatic@wgz.org&gt;</p>
208<p>Written for and maintained by the Perl SDL project, <a href="http://sdl.perl.org/">http://sdl.perl.org/</a>.</p>
209
210</div>
211<h1 id="BUGS">BUGS</h1><p><a href="#TOP" class="toplink">Top</a></p>
212<div id="BUGS_CONTENT">
213<p>No known bugs.</p>
214
215</div>
216<h1 id="COPYRIGHT">COPYRIGHT</h1><p><a href="#TOP" class="toplink">Top</a></p>
217<div id="COPYRIGHT_CONTENT">
218<p>Copyright (c) 2004, chromatic. All rights reserved. This module is
219distributed under the same terms as Perl itself, in the hope that it is useful
220but certainly under no guarantee.
221</p>
222
223</div>
224</div>