/lib/pods/SDL/Tutorial/Animation.pod

http://github.com/PerlGameDev/SDL · Unknown · 195 lines · 133 code · 62 blank · 0 comment · 0 complexity · 73b639b98c01110718f35be167ae5346 MD5 · raw file

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