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