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 */
35class 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