File indexing completed on 2024-12-08 06:45:41

0001 /*
0002     SPDX-FileCopyrightText: 2007-2008 Thomas Gallinari <tg8187@yahoo.fr>
0003     SPDX-FileCopyrightText: 2007-2008 Alexandre Galinier <alex.galinier@hotmail.com>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #ifndef GAME_H
0009 #define GAME_H
0010 
0011 #include "bonus.h"
0012 #include "ghost.h"
0013 #include "kapman.h"
0014 #include "maze.h"
0015 
0016 #include <KGameSound>
0017 #include <QKeyEvent>
0018 #include <QPointF>
0019 #include <QTimer>
0020 
0021 /**
0022  * @brief This class manages the game main loop : it regularly checks the key press events, computes the character moves and updates their coordinates.
0023  */
0024 class Game : public QObject
0025 {
0026     Q_OBJECT
0027 
0028 public:
0029     /** Ratio which modify the timers function of the difficulty */
0030     static qreal s_durationRatio;
0031 
0032     /** Timer duration for prey state in medium difficulty */
0033     static int s_preyStateDuration;
0034 
0035     /** Timer duration for bonus apparition in medium difficulty */
0036     static int s_bonusDuration;
0037 
0038 private:
0039     /** Number of FPS */
0040     static const int FPS;
0041 
0042     /** The game different states : RUNNING, PAUSED_LOCKED, PAUSED_UNLOCKED */
0043     enum State {
0044         RUNNING, // Game running
0045         PAUSED_LOCKED, // Game paused and user is not allowed to unpause
0046         PAUSED_UNLOCKED // Game paused and user is allowed to unpause
0047     };
0048     /** A flag for the State enum */
0049     Q_DECLARE_FLAGS(GameStates, State)
0050 
0051     /** The game state */
0052     State m_state;
0053 
0054     /** The Game main timer */
0055     QTimer *m_timer;
0056 
0057     /** The Bonus timer to make it disappear if it is not eaten after a given time */
0058     QTimer *m_bonusTimer;
0059 
0060     /** Timer to manage the prey state of the ghosts */
0061     QTimer *m_preyTimer;
0062 
0063     /** The Maze */
0064     Maze *m_maze;
0065 
0066     /** The main Character */
0067     Kapman *m_kapman;
0068 
0069     /** The Ghosts */
0070     QList<Ghost *> m_ghosts;
0071 
0072     /** The Bonus instance */
0073     Bonus *m_bonus;
0074 
0075     /** A flag to know if the player has cheated during the game */
0076     bool m_isCheater;
0077 
0078     /** The remaining number of lives */
0079     int m_lives;
0080 
0081     /** The won points */
0082     long m_points;
0083 
0084     /** The current game level */
0085     int m_level;
0086 
0087     /** The number of eaten ghosts since the beginning of the current level */
0088     int m_nbEatenGhosts;
0089 
0090     /** Flag if sound is enabled */
0091     bool m_soundEnabled;
0092 
0093     KGameSound m_soundGameOver;
0094     KGameSound m_soundGhost;
0095     KGameSound m_soundGainLife;
0096     KGameSound m_soundEnergizer;
0097     KGameSound m_soundBonus;
0098     KGameSound m_soundPill;
0099     KGameSound m_soundLevelUp;
0100 
0101 public:
0102     /**
0103      * Creates a new Game instance.
0104      */
0105     Game();
0106 
0107     /**
0108      * Deletes the Game instance.
0109      */
0110     ~Game() override;
0111 
0112     /**
0113      * Starts the Game.
0114      */
0115     void start();
0116 
0117     /**
0118      * Pauses the Game.
0119      * @param p_locked if true the player will be unable to unset the pause.
0120      */
0121     void pause(bool p_locked = false);
0122 
0123     /**
0124      * Pauses / unpauses the game.
0125      * @param p_locked if true the player will be unable to unset the pause.
0126      */
0127     void switchPause(bool p_locked = false);
0128 
0129     /**
0130      * @return the Maze instance
0131      */
0132     Maze *getMaze() const;
0133 
0134     /**
0135      * @return the Kapman model
0136      */
0137     Kapman *getKapman() const;
0138 
0139     /**
0140      * @return the Ghost models
0141      */
0142     QList<Ghost *> getGhosts() const;
0143 
0144     /**
0145      * @return the Bonus instance
0146      */
0147     Bonus *getBonus() const;
0148 
0149     /**
0150      * @return the main timer
0151      */
0152     QTimer *getTimer() const;
0153 
0154     /**
0155      * @return true if the Game is paused, false otherwise
0156      */
0157     bool isPaused() const;
0158 
0159     /**
0160      * @return true if the player has cheated during the game, false otherwise
0161      */
0162     bool isCheater() const;
0163 
0164     /**
0165      * @return the score
0166      */
0167     int getScore() const;
0168 
0169     /**
0170      * @return the number of remaining lives
0171      */
0172     int getLives() const;
0173 
0174     /**
0175      * @return the current level
0176      */
0177     int getLevel() const;
0178 
0179     /**
0180      * Sets the level to the given number.
0181      * @param p_level the new level
0182      */
0183     void setLevel(int p_level);
0184 
0185     /**
0186      * Create the new Bonus
0187      * @param p_position the Bonus position
0188      */
0189     void createBonus(QPointF p_position);
0190 
0191     /**
0192      * Create the new Kapman
0193      * @param p_position the Kapman position
0194      */
0195     void createKapman(QPointF p_position);
0196 
0197     /**
0198      * Create the new Ghost
0199      * @param p_position the Ghost position
0200      * @param p_imageId the image of the Ghost
0201      */
0202     void createGhost(QPointF p_position, const QString &p_imageId);
0203 
0204     /**
0205      * Initializes a Maze
0206      * @param p_nbRows the number of rows
0207      * @param p_nbColumns the number of columns
0208      */
0209     void initMaze(const int p_nbRows, const int p_nbColumns);
0210 
0211     /**
0212      * Enables / disables the sounds.
0213      * @param p_enabled if true the sounds will be enabled, otherwise they will be disabled
0214      */
0215     void setSoundsEnabled(bool p_enabled);
0216 
0217 private:
0218     /**
0219      * Initializes the character coordinates.
0220      */
0221     void initCharactersPosition();
0222 
0223     /**
0224      * Calculates and update the ghosts speed depending on the ghosts speed
0225      * The value is in Ghost::s_speed
0226      */
0227     void setTimersDuration();
0228     void setPreyTimerDuration();
0229     void setBonusTimerDuration();
0230 
0231 public Q_SLOTS:
0232 
0233     /**
0234      * Manages the key press events.
0235      * @param p_event the key press event
0236      */
0237     void keyPressEvent(QKeyEvent *p_event);
0238 
0239     /**
0240      * Resumes the Game after the Kapman death.
0241      */
0242     void resumeAfterKapmanDeath();
0243 
0244 private Q_SLOTS:
0245 
0246     /**
0247      * Updates the Game data.
0248      */
0249     void update();
0250 
0251     /**
0252      * Manages the loss of a life.
0253      */
0254     void kapmanDeath();
0255 
0256     /**
0257      * Manages the death of a Ghost.
0258      */
0259     void ghostDeath(Ghost *p_ghost);
0260 
0261     /**
0262      * Increases the score considering the eaten Element.
0263      * @param p_element the eaten Element
0264      */
0265     void winPoints(Element *p_element);
0266 
0267     /**
0268      * Starts the next level.
0269      */
0270     void nextLevel();
0271 
0272     /**
0273      * Hides the Bonus.
0274      */
0275     void hideBonus();
0276 
0277     /**
0278      * Ends the Ghosts prey state.
0279      */
0280     void endPreyState();
0281 
0282 Q_SIGNALS:
0283 
0284     /**
0285      * Emitted when the Game is started.
0286      */
0287     void gameStarted();
0288 
0289     /**
0290      * Emitted when the Game is over.
0291      */
0292     void gameOver();
0293 
0294     /**
0295      * Emitted when a level begins, if level up or if a life has been lost.
0296      * @param p_newLevel true if a new level is beginning, false otherwise
0297      */
0298     void levelStarted(const bool p_newLevel);
0299 
0300     /**
0301      * Emitted when the pause state has changed.
0302      * @param p_pause true if the Game is paused, false otherwise
0303      * @param p_fromUser true if the Game has been paused due to an action the player has done, false otherwise
0304      */
0305     void pauseChanged(const bool p_pause, const bool p_fromUser);
0306 
0307     /**
0308      * Emitted when an Element has been eaten.
0309      * @param p_x the Element x-coordinate
0310      * @param p_y the Element y-coordinate
0311      */
0312     void elementEaten(const qreal p_x, const qreal p_y);
0313 
0314     /**
0315      * Emitted when the Bonus has to be displayed.
0316      */
0317     void bonusOn();
0318 
0319     /**
0320      * Emitted when the Bonus has to disappear.
0321      */
0322     void bonusOff();
0323 
0324     /**
0325      * Emitted when the level have changed.
0326      * @param p_level the new level data
0327      */
0328     void levelChanged(unsigned int p_level);
0329 
0330     /**
0331      * Emitted when the score have changed.
0332      * @param p_score the new score data
0333      */
0334     void scoreChanged(unsigned int p_score);
0335 
0336     /**
0337      * Emitted when the lives have changed.
0338      * @param p_lives the new lives data
0339      */
0340     void livesChanged(unsigned int p_lives);
0341 
0342     /**
0343      * Emitted when a ghost or a bonus is eaten. It tells to the scene to
0344      * display the number of won points
0345      * @param p_wonPoints the value to display
0346      * @param p_xPos the x position of the label
0347      * @param p_yPos the y position of the label
0348      */
0349     void pointsToDisplay(long p_wonPoints, qreal p_xPos, qreal p_yPos);
0350 };
0351 
0352 #endif