1 | /* |
2 | * Copyright 2007-2008 Thomas Gallinari <tg8187@yahoo.fr> |
3 | * Copyright 2007-2008 Alexandre Galinier <alex.galinier@hotmail.com> |
4 | * |
5 | * This program is free software; you can redistribute it and/or |
6 | * modify it under the terms of the GNU General Public License as |
7 | * published by the Free Software Foundation; either version 2 of |
8 | * the License, or (at your option) any later version. |
9 | * |
10 | * This program is distributed in the hope that it will be useful, |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | * GNU General Public License for more details. |
14 | * |
15 | * You should have received a copy of the GNU General Public License |
16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | */ |
18 | |
19 | #ifndef GAME_H |
20 | #define GAME_H |
21 | |
22 | #include "maze.h" |
23 | #include "kapman.h" |
24 | #include "ghost.h" |
25 | #include "bonus.h" |
26 | |
27 | #include <QPointF> |
28 | #include <QTimer> |
29 | #include <QKeyEvent> |
30 | #include <KgSound> |
31 | |
32 | /** |
33 | * @brief This class manages the game main loop : it regularly checks the key press events, computes the character moves and updates their coordinates. |
34 | */ |
35 | class Game : public QObject { |
36 | |
37 | Q_OBJECT |
38 | |
39 | public : |
40 | /** Ratio which modify the timers function of the difficulty */ |
41 | static qreal s_durationRatio; |
42 | |
43 | /** Timer duration for prey state in medium difficulty */ |
44 | static int s_preyStateDuration; |
45 | |
46 | /** Timer duration for bonus apparition in medium difficulty */ |
47 | static int s_bonusDuration; |
48 | |
49 | private : |
50 | |
51 | /** Number of FPS */ |
52 | static const int FPS; |
53 | |
54 | /** The game different states : RUNNING, PAUSED_LOCKED, PAUSED_UNLOCKED */ |
55 | enum State { |
56 | RUNNING, // Game running |
57 | PAUSED_LOCKED, // Game paused and user is not allowed to unpause |
58 | PAUSED_UNLOCKED // Game paused and user is allowed to unpause |
59 | }; |
60 | /** A flag for the State enum */ |
61 | Q_DECLARE_FLAGS(GameStates, State) |
62 | |
63 | /** The game state */ |
64 | State m_state; |
65 | |
66 | /** The Game main timer */ |
67 | QTimer* m_timer; |
68 | |
69 | /** The Bonus timer to make it disappear if it is not eaten after a given time */ |
70 | QTimer* m_bonusTimer; |
71 | |
72 | /** Timer to manage the prey state of the ghosts */ |
73 | QTimer* m_preyTimer; |
74 | |
75 | /** The Maze */ |
76 | Maze* m_maze; |
77 | |
78 | /** The main Character */ |
79 | Kapman* m_kapman; |
80 | |
81 | /** The Ghosts */ |
82 | QList<Ghost*> m_ghosts; |
83 | |
84 | /** The Bonus instance */ |
85 | Bonus *m_bonus; |
86 | |
87 | /** A flag to know if the player has cheated during the game */ |
88 | bool m_isCheater; |
89 | |
90 | /** The remaining number of lives */ |
91 | int m_lives; |
92 | |
93 | /** The won points */ |
94 | long m_points; |
95 | |
96 | /** The current game level */ |
97 | int m_level; |
98 | |
99 | /** The number of eaten ghosts since the beginning of the current level */ |
100 | int m_nbEatenGhosts; |
101 | |
102 | /** Flag if sound is enabled */ |
103 | bool m_soundEnabled; |
104 | |
105 | KgSound m_soundGameOver; |
106 | KgSound m_soundGhost; |
107 | KgSound m_soundGainLife; |
108 | KgSound m_soundEnergizer; |
109 | KgSound m_soundBonus; |
110 | KgSound m_soundPill; |
111 | KgSound m_soundLevelUp; |
112 | |
113 | |
114 | public: |
115 | |
116 | /** |
117 | * Creates a new Game instance. |
118 | */ |
119 | Game(); |
120 | |
121 | /** |
122 | * Deletes the Game instance. |
123 | */ |
124 | ~Game(); |
125 | |
126 | /** |
127 | * Starts the Game. |
128 | */ |
129 | void start(); |
130 | |
131 | /** |
132 | * Pauses the Game. |
133 | * @param p_locked if true the player will be unable to unset the pause. |
134 | */ |
135 | void pause(bool p_locked = false); |
136 | |
137 | /** |
138 | * Pauses / unpauses the game. |
139 | * @param p_locked if true the player will be unable to unset the pause. |
140 | */ |
141 | void switchPause(bool p_locked = false); |
142 | |
143 | /** |
144 | * @return the Maze instance |
145 | */ |
146 | Maze* getMaze() const; |
147 | |
148 | /** |
149 | * @return the Kapman model |
150 | */ |
151 | Kapman* getKapman() const; |
152 | |
153 | /** |
154 | * @return the Ghost models |
155 | */ |
156 | QList<Ghost*> getGhosts () const; |
157 | |
158 | /** |
159 | * @return the Bonus instance |
160 | */ |
161 | Bonus* getBonus() const; |
162 | |
163 | /** |
164 | * @return the main timer |
165 | */ |
166 | QTimer* getTimer() const; |
167 | |
168 | /** |
169 | * @return true if the Game is paused, false otherwise |
170 | */ |
171 | bool isPaused() const; |
172 | |
173 | /** |
174 | * @return true if the player has cheated during the game, false otherwise |
175 | */ |
176 | bool isCheater() const; |
177 | |
178 | /** |
179 | * @return the score |
180 | */ |
181 | int getScore () const; |
182 | |
183 | /** |
184 | * @return the number of remaining lives |
185 | */ |
186 | int getLives() const; |
187 | |
188 | /** |
189 | * @return the current level |
190 | */ |
191 | int getLevel() const; |
192 | |
193 | /** |
194 | * Sets the level to the given number. |
195 | * @param p_level the new level |
196 | */ |
197 | void setLevel(int p_level); |
198 | |
199 | /** |
200 | * Create the new Bonus |
201 | * @param p_position the Bonus position |
202 | */ |
203 | void createBonus(QPointF p_position); |
204 | |
205 | /** |
206 | * Create the new Kapman |
207 | * @param p_position the Kapman position |
208 | */ |
209 | void createKapman(QPointF p_position); |
210 | |
211 | /** |
212 | * Create the new Ghost |
213 | * @param p_position the Ghost position |
214 | * @param p_imageId the image of the Ghost |
215 | */ |
216 | void createGhost(QPointF p_position, const QString & p_imageId); |
217 | |
218 | /** |
219 | * Initializes a Maze |
220 | * @param p_nbRows the number of rows |
221 | * @param p_nbColumns the number of columns |
222 | */ |
223 | void initMaze(const int p_nbRows, const int p_nbColumns); |
224 | |
225 | /** |
226 | * Initializes a Ghost |
227 | */ |
228 | void initGhost(); |
229 | |
230 | /** |
231 | * Initializes a Kapman |
232 | */ |
233 | void initKapman(); |
234 | |
235 | /** |
236 | * Enables / disables the sounds. |
237 | * @param p_enabled if true the sounds will be enabled, otherwise they will be disabled |
238 | */ |
239 | void setSoundsEnabled(bool p_enabled); |
240 | |
241 | private: |
242 | |
243 | /** |
244 | * Initializes the character coordinates. |
245 | */ |
246 | void initCharactersPosition(); |
247 | |
248 | /** |
249 | * Calculates and update the ghosts speed depending on the ghosts speed |
250 | * The value is in Ghost::s_speed |
251 | */ |
252 | void setTimersDuration(); |
253 | |
254 | public slots: |
255 | |
256 | /** |
257 | * Manages the key press events. |
258 | * @param p_event the key press event |
259 | */ |
260 | void keyPressEvent(QKeyEvent* p_event); |
261 | |
262 | /** |
263 | * Resumes the Game after the Kapman death. |
264 | */ |
265 | void resumeAfterKapmanDeath(); |
266 | |
267 | private slots: |
268 | |
269 | /** |
270 | * Updates the Game data. |
271 | */ |
272 | void update(); |
273 | |
274 | /** |
275 | * Manages the loss of a life. |
276 | */ |
277 | void kapmanDeath(); |
278 | |
279 | /** |
280 | * Manages the death of a Ghost. |
281 | */ |
282 | void ghostDeath(Ghost* p_ghost); |
283 | |
284 | /** |
285 | * Increases the score considering the eaten Element. |
286 | * @param p_element the eaten Element |
287 | */ |
288 | void winPoints(Element* p_element); |
289 | |
290 | /** |
291 | * Starts the next level. |
292 | */ |
293 | void nextLevel(); |
294 | |
295 | /** |
296 | * Hides the Bonus. |
297 | */ |
298 | void hideBonus(); |
299 | |
300 | /** |
301 | * Ends the Ghosts prey state. |
302 | */ |
303 | void endPreyState(); |
304 | |
305 | signals: |
306 | |
307 | /** |
308 | * Emitted when the Game is started. |
309 | */ |
310 | void gameStarted(); |
311 | |
312 | /** |
313 | * Emitted when the Game is over. |
314 | * @param p_unused this parameter must always be true ! |
315 | */ |
316 | void gameOver(const bool p_unused); |
317 | |
318 | /** |
319 | * Emitted when a level begins, if level up or if a life has been lost. |
320 | * @param p_newLevel true if a new level is beginning, false otherwise |
321 | */ |
322 | void levelStarted(const bool p_newLevel); |
323 | |
324 | /** |
325 | * Emitted when the pause state has changed. |
326 | * @param p_pause true if the Game is paused, false otherwise |
327 | * @param p_fromUser true if the Game has been paused due to an action the player has done, false otherwise |
328 | */ |
329 | void pauseChanged(const bool p_pause, const bool p_fromUser); |
330 | |
331 | /** |
332 | * Emitted when an Element has been eaten. |
333 | * @param p_x the Element x-coordinate |
334 | * @param p_y the Element y-coordinate |
335 | */ |
336 | void elementEaten(const qreal p_x, const qreal p_y); |
337 | |
338 | /** |
339 | * Emitted when the Bonus has to be displayed. |
340 | */ |
341 | void bonusOn(); |
342 | |
343 | /** |
344 | * Emitted when the Bonus has to disappear. |
345 | */ |
346 | void bonusOff(); |
347 | |
348 | /** |
349 | * Emitted when the level have changed. |
350 | * @param p_level the new level data |
351 | */ |
352 | void levelChanged( unsigned int p_level ); |
353 | |
354 | /** |
355 | * Emitted when the score have changed. |
356 | * @param p_score the new score data |
357 | */ |
358 | void scoreChanged( unsigned int p_score ); |
359 | |
360 | /** |
361 | * Emitted when the lives have changed. |
362 | * @param p_lives the new lives data |
363 | */ |
364 | void livesChanged( unsigned int p_lives ); |
365 | |
366 | |
367 | /** |
368 | * Emitted when a ghost or a bonus is eaten. It tells to the scene to |
369 | * display the number of won points |
370 | * @param p_wonPoints the value to display |
371 | * @param p_xPos the x position of the label |
372 | * @param p_yPos the y position of the label |
373 | */ |
374 | void pointsToDisplay(long p_wonPoints, qreal p_xPos, qreal p_yPos); |
375 | }; |
376 | |
377 | #endif |
378 | |
379 | |