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