/examples/SDLx/SDLx_controller_two_squares.pl

http://github.com/PerlGameDev/SDL · Perl · 152 lines · 117 code · 29 blank · 6 comment · 29 complexity · bd0ae8b746628da31870ffbc0ce781ce MD5 · raw file

  1. use strict;
  2. use warnings;
  3. use Carp;
  4. use SDL;
  5. use SDL::Video;
  6. use SDL::Surface;
  7. use SDL::Rect;
  8. use SDL::Event;
  9. use SDL::Events;
  10. use Data::Dumper;
  11. use Math::Trig;
  12. use lib 'lib';
  13. use SDLx::Controller;
  14. my $app = init();
  15. my $ball = {
  16. x => 0,
  17. y => 0,
  18. w => 20,
  19. h => 20,
  20. vel => 20,
  21. x_vel => 0,
  22. y_vel => 0,
  23. };
  24. my $r_ball = {
  25. x => 0,
  26. y => 0,
  27. w => 20,
  28. h => 20,
  29. radians => 0,
  30. rot_vel => 10,
  31. radius => 100,
  32. c_x => $app->w / 2,
  33. c_y => $app->h / 2,
  34. };
  35. sub init {
  36. # Initing video
  37. # Die here if we cannot make video init
  38. Carp::confess 'Cannot init ' . SDL::get_error()
  39. if ( SDL::init(SDL_INIT_VIDEO) == -1 );
  40. # Create our display window
  41. # This is our actual SDL application window
  42. my $a = SDL::Video::set_video_mode(
  43. 800, 600, 32,
  44. SDL_HWSURFACE | SDL_DOUBLEBUF | SDL_HWACCEL
  45. );
  46. Carp::confess 'Cannot init video mode 800x600x32: ' . SDL::get_error()
  47. unless $a;
  48. return $a;
  49. }
  50. my $game = SDLx::Controller->new();
  51. sub on_move {
  52. my $dt = shift;
  53. $ball->{x} += $ball->{x_vel} * $dt;
  54. $ball->{y} += $ball->{y_vel} * $dt;
  55. # Period = $r_ball->{vel}
  56. # cc_speed = 2 * pi * r / T
  57. $r_ball->{radians} += $r_ball->{rot_vel} * $dt;
  58. $r_ball->{x} = $r_ball->{c_x} + sin( $r_ball->{radians} * pi / 180 ) * $r_ball->{radius};
  59. $r_ball->{y} = $r_ball->{c_y} + cos( $r_ball->{radians} * pi / 180 ) * $r_ball->{radius};
  60. return 1;
  61. }
  62. sub on_event {
  63. my $event = shift;
  64. if ( $event->type == SDL_KEYDOWN ) {
  65. my $key = $event->key_sym;
  66. if ( $key == SDLK_PRINT ) {
  67. my $screen_shot_index = 1;
  68. map { $screen_shot_index = $1 + 1 if $_ =~ /Shot(\d+)\.bmp/ && $1 >= $screen_shot_index } <Shot*\.bmp>;
  69. SDL::Video::save_BMP(
  70. $app,
  71. sprintf( "Shot%04d.bmp", $screen_shot_index )
  72. );
  73. }
  74. $ball->{y_vel} -= $ball->{vel} if $key == SDLK_UP;
  75. $ball->{y_vel} += $ball->{vel} if $key == SDLK_DOWN;
  76. $ball->{x_vel} -= $ball->{vel} if $key == SDLK_LEFT;
  77. $ball->{x_vel} += $ball->{vel} if $key == SDLK_RIGHT;
  78. $r_ball->{rot_vel} += 50 if $key == SDLK_SPACE;
  79. } elsif ( $event->type == SDL_KEYUP ) {
  80. my $key = $event->key_sym;
  81. $ball->{y_vel} += $ball->{vel} if $key == SDLK_UP;
  82. $ball->{y_vel} -= $ball->{vel} if $key == SDLK_DOWN;
  83. $ball->{x_vel} += $ball->{vel} if $key == SDLK_LEFT;
  84. $ball->{x_vel} -= $ball->{vel} if $key == SDLK_RIGHT;
  85. } elsif ( $event->type == SDL_QUIT ) {
  86. $_[0]->stop;
  87. }
  88. }
  89. sub on_show {
  90. SDL::Video::fill_rect(
  91. $app,
  92. SDL::Rect->new( 0, 0, $app->w, $app->h ),
  93. SDL::Video::map_RGB( $app->format, 0, 0, 0 )
  94. );
  95. SDL::Video::fill_rect(
  96. $app,
  97. SDL::Rect->new( $ball->{x}, $ball->{y}, $ball->{w}, $ball->{h} ),
  98. SDL::Video::map_RGB( $app->format, 0, 0, 255 )
  99. );
  100. SDL::Video::fill_rect(
  101. $app,
  102. SDL::Rect->new(
  103. $r_ball->{x}, $r_ball->{y}, $r_ball->{w}, $r_ball->{h}
  104. ),
  105. SDL::Video::map_RGB( $app->format, 255, 0, 0 )
  106. );
  107. SDL::Video::flip($app);
  108. return 0;
  109. }
  110. my $move_id = $game->add_move_handler( \&on_move );
  111. my $event_id = $game->add_event_handler( \&on_event );
  112. my $show_id = $game->add_show_handler( \&on_show );
  113. print <<'EOT';
  114. In this example, you should see two small squares, one blue
  115. and one red. The red square should move around in circles, while
  116. you can control the blue one with the keyboard arrow keys.
  117. Also, if you press the "print screen" key, it will save an image
  118. called shot0001.bmp in your current dir. Pressing it again will
  119. create a new screenshot file, with the index incremented. That is,
  120. assuming your system will propagate the "print screen" event :)
  121. To exit the demo, just close the window normally.
  122. EOT
  123. $game->run();