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