Update 2.518
[sdlgit/SDL-Site.git] / pages / SDLx-Controller.html-inc
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>
7 <ul><li><a href="#DESCRIPTION">DESCRIPTION</a></li>
8 </ul>
9 </li>
10 <li><a href="#METHODS">METHODS</a>
11 <ul><li><a href="#new">new</a></li>
12 <li><a href="#run">run</a></li>
13 <li><a href="#stop">stop</a></li>
14 <li><a href="#pause">pause</a></li>
15 <li><a href="#add_event_handler">add_event_handler</a></li>
16 <li><a href="#add_move_handler">add_move_handler</a></li>
17 <li><a href="#add_show_handler">add_show_handler</a></li>
18 <li><a href="#remove_move_handler_index">remove_move_handler( $index )</a></li>
19 <li><a href="#remove_event_handler_index">remove_event_handler( $index )</a></li>
20 <li><a href="#remove_show_handler_index">remove_show_handler( $index )</a></li>
21 <li><a href="#remove_all_move_handlers">remove_all_move_handlers</a></li>
22 <li><a href="#remove_all_event_handlers">remove_all_event_handlers</a></li>
23 <li><a href="#remove_all_show_handlers">remove_all_show_handlers</a></li>
24 <li><a href="#remove_all_handlers">remove_all_handlers</a></li>
25 <li><a href="#dt">dt</a></li>
26 <li><a href="#min_t">min_t</a></li>
27 <li><a href="#current_time">current_time</a></li>
28 </ul>
29 </li>
30 <li><a href="#AUTHORS">AUTHORS</a>
31 <ul><li><a href="#ACKNOWLEGDEMENTS">ACKNOWLEGDEMENTS</a>
32 </li>
33 </ul>
34 </li>
35 </ul><hr />
36 <!-- INDEX END -->
37
38 <h1 id="NAME">NAME</h1><p><a href="#TOP" class="toplink">Top</a></p>
39 <div id="NAME_CONTENT">
40 <p>SDLx::Controller - Handles the loops for events, movement and rendering</p>
41
42 </div>
43 <h1 id="SYNOPSIS">SYNOPSIS</h1><p><a href="#TOP" class="toplink">Top</a></p>
44 <div id="SYNOPSIS_CONTENT">
45 <pre>  use SDLx::Controller;
46
47   # create our controller object
48   my $app = SDLx::Controller-&gt;new;
49
50   # register some callbacks
51   $app-&gt;add_event_handler( \&amp;on_event );
52   $app-&gt;add_move_handler( \&amp;on_move );
53   $app-&gt;add_show_handler( \&amp;on_show );
54
55   # run our game loop
56   $app-&gt;run;
57
58
59
60
61 </pre>
62
63 </div>
64 <h2 id="DESCRIPTION">DESCRIPTION</h2>
65 <div id="DESCRIPTION_CONTENT">
66 <p>The core of a SDL application/game is the main loop, where you handle events
67 and display your elements on the screen until something signals the end of
68 the program. This usually goes in the form of:</p>
69 <pre>  while (1) {
70       ...
71   }
72
73 </pre>
74 <p>The problem most developers face, besides the repetitive work, is to ensure
75 the screen update is independent of the frame rate. Otherwise, your game will
76 run at different speeds on different machines and this is never good (old
77 MS-DOS games, anyone?).</p>
78 <p>One way to circumveint this is by capping the frame rate so it's the same no
79 matter what, but this is not the right way to do it as it penalizes better
80 hardware.</p>
81 <p>This module provides an industry-proven standard for frame independent
82 movement. It calls the movement handlers based on time (hi-res seconds) rather
83 than frame rate. You can add/remove handlers and control your main loop with
84 ease.</p>
85
86 </div>
87 <h1 id="METHODS">METHODS</h1><p><a href="#TOP" class="toplink">Top</a></p>
88 <div id="METHODS_CONTENT">
89
90 </div>
91 <h2 id="new">new</h2>
92 <div id="new_CONTENT">
93 <pre> SDLx::Controller-&gt;new(
94      dt    =&gt; 0.5,
95      min_t =&gt; 0,
96      event =&gt; $event_object,
97  );
98
99 </pre>
100 <p>The <code>dt</code> parameter specifies the length, in seconds, of a full movement step, and defaults to 0.1.
101 The <code>dt</code> can  be anything and the game can still look the same.
102 It is only when you change the <code>dt</code> without changing all the things in the movement step that are being multiplied by the first move argument that it will make a difference.
103 If you lower the <code>dt</code>, everything will move faster than it did with it set higher, and vice-versa.
104 This is useful to add slo-mo and fast-forward features to the game, all you would have to do is change the <code>dt</code>.</p>
105 <p><code>min_t</code> specifies the minimum time, in seconds, that has to accumulate before any move or show handlers are called, and defaults to 1 / 60.
106 Having the <code>min_t</code> to 1 / 60 ensures that the controller can update the screen at a maximum of 60 times per second.
107 A &quot;V-Sync&quot; such as this is necessary to prevent video &quot;tear&quot;, which occurs when the app is updating faster than the monitor can display.
108 Setting it to 0, as in the example, will let the app run as fast as it possibly can.</p>
109 <p><code>event</code> is a SDL::Event object that events going to the event callbacks are polled in to. Defaults to <code>SDL::Event-&gt;new()</code>.</p>
110 <p>All parameters are optional.</p>
111 <p>Returns the new object.</p>
112
113 </div>
114 <h2 id="run">run</h2>
115 <div id="run_CONTENT">
116 <p>After creating and setting up your handlers (see below), call this method to
117 activate the main loop. The main loop will run until <code>stop</code> is called.</p>
118 <p>All hooked functions will be called during the main loop, in this order:</p>
119 <dl>
120         <dt>1. Events</dt>
121         <dt>2. Movements</dt>
122         <dt>3. Displaying</dt>
123 </dl>
124 <p>Please refer to each handler below for information on received arguments.
125 Note that the second argument every callback recieves is the <code>SDLx::Controller</code> object.</p>
126
127 </div>
128 <h2 id="stop">stop</h2>
129 <div id="stop_CONTENT">
130 <p>Returns from the <code>run</code> loop.</p>
131
132 </div>
133 <h2 id="pause">pause</h2>
134 <div id="pause_CONTENT">
135 <p>Attempts to pause the application with a call to <code>SDL::Events::wait_event</code>. See <a href="SDL-Events.html">SDL::Events</a>.</p>
136 <p>Takes 1 argument which is a callback. The application waits for the next event with <code>wait_event</code>.
137 When one is recieved, it is passed to the callback as the first argument, along with the <code>SDLx::Controller</code> object as the second argument.
138 If the callback then returns a true value, <code>pause</code> will return.
139 If the callback returns a false value, <code>pause</code> will indefinitely wait for more events, repeating the process, until the callback returns true.</p>
140 <p>This can be used to easily implement a pause when the app loses focus:</p>
141 <pre> sub focus {
142      my ($e, $controller) = @_;
143      if($e-&gt;type == SDL_ACTIVEEVENT) {
144          if($e-&gt;active_state &amp; SDL_APPINPUTFOCUS) {
145              if($e-&gt;active_gain) {
146                  return 1;
147              }
148              else {
149                  $controller-&gt;pause(\&amp;focus);
150                  # recursive, but only once since the window
151                  # can't lose focus again without gaining is first
152              }
153          }
154      }
155      return 0;
156  }
157
158 </pre>
159 <p>Note: if you implement your own pause function, remember to update <code>current_time</code> to the current time when the application unpauses.
160 This should be done with <code>Time::HiRes::time</code>.
161 Otherwise, time will accumulate while the application is paused, and many movement steps will be called all at once when it unpauses.</p>
162 <p>Note 2: a pause will be potentially dangerous to the <code>run</code> cycle (even if you implement your own) unless called by an <code>event</code> callback.</p>
163
164 </div>
165 <h2 id="add_event_handler">add_event_handler</h2>
166 <div id="add_event_handler_CONTENT">
167 <p>Register a callback to handle events. You can add as many subs as you need.
168 Whenever a SDL::Event occurs, all registered callbacks will be triggered in
169 order. Returns the order queue number of the added callback.</p>
170 <p>The first argument passed to registered callbacks is the <a href="SDL-Event.html">SDL::Event</a> object.
171 The second is the <code>SDLx::Controller</code> object.</p>
172 <pre> sub stop {
173     my ($event, $app) = @_;
174     if($event-&gt;type == SDL_QUIT) {
175         $controller-&gt;stop;
176     }
177  }
178  $controller-&gt;add_event_handler(\&amp;stop);
179
180 </pre>
181
182 </div>
183 <h2 id="add_move_handler">add_move_handler</h2>
184 <div id="add_move_handler_CONTENT">
185 <p>Register a callback to update your objects. You can add as many subs as
186 you need. Returns the order queue number of the added callback.</p>
187 <p>All registered callbacks will be triggered in order for as many <code>dt</code> as have happened between calls,
188 and once more for any remaining time less than <code>dt</code>.
189 The first argument passed to the callbacks is the portion of the step, which will be 1 for a full step, and less than 1 for a partial step.
190 Movement values should be multiplied by this value.
191 The full steps correspond to the amount of <code>dt</code> passed between calls, and the partial step corresponds to the call with the remaining time less than <code>dt</code>.
192 The argument can be 0 if no time has passed since the last cycle. Set a <code>min_t</code> if you need to protect against this.</p>
193 <p>The second argument passed to the callbacks is the <code>SDLx::Controller</code> object.
194 The third is the total amount of time passed since the call of <code>run</code>.</p>
195 <p>You should use these handlers to update your in-game objects, check collisions, etc.
196 so you can check and/or update it as necessary.</p>
197 <pre> sub move_ball {
198      my ($step, $app, $t) = @_;
199      $ball-&gt;move_x( $ball-&gt;x_vel * $step );
200      $ball-&gt;move_y( $ball-&gt;y_vel * $step );
201  }
202
203 </pre>
204
205 </div>
206 <h2 id="add_show_handler">add_show_handler</h2>
207 <div id="add_show_handler_CONTENT">
208 <p>Register a callback to render objects. You can add as many subs as you need.
209 Returns the order queue number of the added callback.
210 All registered callbacks will be triggered in order, once per run of the <code>run</code> loop.</p>
211 <p>The first argument passed is the number of ticks since the previous call.
212 The second is the <code>SDLx::Controller</code> object.</p>
213 <pre> sub show_ball {
214      my ($delta, $app) = @_;
215      $app-&gt;draw_rect(
216          [ $ball-&gt;x, $ball-&gt;y, $ball-&gt;size, $ball-&gt;size ],
217          $ball-&gt;colour
218      );
219  }
220
221 </pre>
222
223 </div>
224 <h2 id="remove_move_handler_index">remove_move_handler( $index )</h2>
225 <div id="remove_move_handler_index_CONTENT">
226
227 </div>
228 <h2 id="remove_event_handler_index">remove_event_handler( $index )</h2>
229 <div id="remove_event_handler_index_CONTENT">
230
231 </div>
232 <h2 id="remove_show_handler_index">remove_show_handler( $index )</h2>
233 <div id="remove_show_handler_index_CONTENT">
234 <p>Removes the handler with the given index from the respective calling queue.</p>
235 <p>You can also pass a coderef.
236 The first coderef in the handler list that this matches will be removed.</p>
237 <p>Returns the removed handler.</p>
238
239 </div>
240 <h2 id="remove_all_move_handlers">remove_all_move_handlers</h2>
241 <div id="remove_all_move_handlers_CONTENT">
242
243 </div>
244 <h2 id="remove_all_event_handlers">remove_all_event_handlers</h2>
245 <div id="remove_all_event_handlers_CONTENT">
246
247 </div>
248 <h2 id="remove_all_show_handlers">remove_all_show_handlers</h2>
249 <div id="remove_all_show_handlers_CONTENT">
250 <p>Removes all handlers from the respective calling queue.</p>
251
252 </div>
253 <h2 id="remove_all_handlers">remove_all_handlers</h2>
254 <div id="remove_all_handlers_CONTENT">
255 <p>Quick access to removing all handlers at once.</p>
256
257 </div>
258 <h2 id="dt">dt</h2>
259 <div id="dt_CONTENT">
260
261 </div>
262 <h2 id="min_t">min_t</h2>
263 <div id="min_t_CONTENT">
264
265 </div>
266 <h2 id="current_time">current_time</h2>
267 <div id="current_time_CONTENT">
268 <p>If an argument is passed, modifies the corresponding value to the argument.
269 <code>dt</code> and <code>min_t</code> will keep their old value until the beginning of the next <code>run</code> cycle.</p>
270 <p>Returns the corresponding value.</p>
271
272 </div>
273 <h1 id="AUTHORS">AUTHORS</h1><p><a href="#TOP" class="toplink">Top</a></p>
274 <div id="AUTHORS_CONTENT">
275 <p>See <b>AUTHORS</b> in <cite>SDL</cite>.</p>
276
277 </div>
278 <h2 id="ACKNOWLEGDEMENTS">ACKNOWLEGDEMENTS</h2>
279 <div id="ACKNOWLEGDEMENTS_CONTENT">
280 <p>The idea and base for this module comes from Lazy Foo's <a href="http://www.lazyfoo.net/SDL_tutorials/lesson32/index.php">Frame Independent Movement</a> tutorial,
281 and Glenn Fiedler's <a href="http://gafferongames.com/game-physics/fix-your-timestep/">Fix Your Timestep</a> article on timing.</p>
282
283
284
285
286
287
288
289
290
291
292
293 </div>
294 </div>