File indexing completed on 2024-12-08 06:46:03

0001 /*
0002     SPDX-FileCopyrightText: 2012 Roney Gomes <roney477@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 /**
0008  * @class KGrScene  kgrscene.h
0009  * @short The QGraphicsScene that represents KGoldrunner on the screen.
0010  *
0011  * In the KGoldrunner scene, the KGoldrunner level-layouts use tile-coordinates
0012  * that run from (1, 1) to (28, 20). To simplify programming, these are exactly
0013  * the same as the cell co-ordinates used in the game-engine (or model).
0014  *
0015  * The central grid has internal coordinates running from (-1, -1) to (30, 22),
0016  * making 32x24 spaces. The empty space around the level-layout (2 cells wide
0017  * all around) is designed to absorb over-enthusiastic mouse actions, which
0018  * could otherwise cause accidents on other windows or the surrounding desktop.
0019  *
0020  * Rows -1, 0, 29 and 30 usually contain titles and scores, which could have
0021  * fractional co-ordinates. Row 0, row 21, column 0 and column 29 can also
0022  * contain border-tiles (as in the Egyptian theme).
0023  *
0024  * The hero and enemies (sprites) will have fractional co-ordinates as they move
0025  * from one cell to another. Other graphics items (tiles) always have whole
0026  * number co-ordinates (e.g. bricks, ladders and concrete). Empty spaces have
0027  * no graphic item and the background shows through them.
0028  *
0029  * The width and height of the view will rarely be an exact number of tiles, so
0030  * there will be unused strips outside the 32x24 tile spaces. The sceneRect() is
0031  * set larger than 24 tiles by 32 tiles to allow for this and its top left
0032  * corner has negative fractional co-ordinates that are calculated but never
0033  * actually used. Their purpose is to ensure that (1, 1) is always the top left
0034  * corner of the KGoldrunner level layout, whatever the size/shape of the view.
0035  */
0036 #ifndef KGRSCENE_H
0037 #define KGRSCENE_H
0038 
0039 #include <QGraphicsScene>
0040 
0041 #include "kgrglobals.h"
0042 
0043 class KGrView;
0044 class KGrSprite;
0045 class KGrRenderer;
0046 class KGameRenderedItem;
0047 class QTimeLine;
0048 
0049 enum StartFrame     {RIGHTWALK1 = 1,  RIGHTWALK2,  RIGHTWALK3,  RIGHTWALK4,
0050                      RIGHTWALK5,  RIGHTWALK6,  RIGHTWALK7,  RIGHTWALK8,
0051                      LEFTWALK1,   LEFTWALK2,   LEFTWALK3,   LEFTWALK4,
0052                      LEFTWALK5,   LEFTWALK6,   LEFTWALK7,   LEFTWALK8,
0053                      RIGHTCLIMB1, RIGHTCLIMB2, RIGHTCLIMB3, RIGHTCLIMB4,
0054                      RIGHTCLIMB5, RIGHTCLIMB6, RIGHTCLIMB7, RIGHTCLIMB8,
0055                      LEFTCLIMB1,  LEFTCLIMB2,  LEFTCLIMB3,  LEFTCLIMB4,
0056                      LEFTCLIMB5,  LEFTCLIMB6,  LEFTCLIMB7,  LEFTCLIMB8,
0057                      CLIMB1,      CLIMB2,
0058                      FALL1,       FALL2,
0059                      DIGBRICK1 = 1, DIGBRICK2, DIGBRICK3, DIGBRICK4,
0060                      DIGBRICK5,
0061                      DIGBRICK6, DIGBRICK7, DIGBRICK8, DIGBRICK9};
0062 
0063 class KGrScene : public QGraphicsScene
0064 {
0065     Q_OBJECT
0066 public:
0067     explicit KGrScene       (KGrView * view);
0068     ~KGrScene               () override;
0069 
0070     /**
0071      * Redraw the scene whenever the current theme has changed.
0072      */
0073     void changeTheme        ();
0074 
0075     /**
0076      * Redraw the scene whenever the view widget is resized.
0077      */
0078     void changeSize         ();
0079 
0080     /**
0081      * Set the current level number.  It is used to select a background.
0082      *
0083      * @param level         The current level number.
0084      */
0085     void setLevel (unsigned int level);
0086 
0087     /**
0088      * Set the text for the title of the current level.
0089      *
0090      * @param newTitle      The title of the current level.
0091      */
0092     void setTitle (const QString & newTitle);
0093 
0094     void setReplayMessage (const QString & msg);
0095 
0096     void showReplayMessage (bool onOff);
0097 
0098     void setHasHintText (const QString & msg);
0099 
0100     void setPauseResumeText (const QString & msg);
0101 
0102     void goToBlack();
0103     void fadeIn (bool inOut);
0104 
0105     /**
0106      * Get the current size of the squared region occupied by a single visual
0107      * element (characters, ladders, bricks etc.).
0108      */
0109     QSize tileSize          () const { return QSize (m_tileSize, m_tileSize); }
0110 
0111     /**
0112      * Get a pointer to the scene's renderer.
0113      */
0114     KGrRenderer * renderer  () const { return m_renderer; }
0115 
0116     inline void setGoldEnemiesRule (bool showIt) { enemiesShowGold = showIt; }
0117 
0118 public Q_SLOTS:
0119     void showLives          (long lives);
0120 
0121     void showScore          (long score);
0122 
0123     int  makeSprite         (const char type, int i, int j);
0124 
0125     void animate            (bool missed);
0126     void gotGold            (const int spriteId, const int i, const int j,
0127                              const bool spriteHasGold, const bool lost = false);
0128     void showHiddenLadders  (const QList<int> & ladders, const int width);
0129     void deleteSprite       (const int id);
0130     void deleteAllSprites   ();
0131 
0132     /**
0133      * Requests the view to display a particular type of tile at a particular
0134      * cell, or make it empty and show the background (tileType = FREE). Used
0135      * when loading level-layouts and also to make gold disappear/appear, hidden
0136      * ladders appear or cells to be painted by the game editor.  If there was
0137      * something in the cell already, tileType = FREE acts as an erase function.
0138      *
0139      * @param i            The column-number of the cell to paint.
0140      * @param j            The row-number of the cell to paint.
0141      * @param type         The type of tile to paint (gold, brick, ladder, etc).
0142      */
0143     void paintCell          (const int i, const int j, const char type);
0144 
0145     /**
0146      * Requests the view to display an animation of a runner or dug brick at a
0147      * particular cell, cancelling and superseding any current animation.
0148      *
0149      * @param id           The ID of the sprite (dug brick).
0150      * @param repeating    If true, repeat the animation (false for dug brick).
0151      * @param i            The column-number of the cell.
0152      * @param j            The row-number of the cell.
0153      * @param time         The time in which to traverse one cell.
0154      * @param dirn         The direction of motion (always STAND for dug brick).
0155      * @param type         The type of animation (run, climb, open/close brick).
0156      */
0157     void startAnimation    (const int id, const bool repeating,
0158                             const int i, const int j, const int time,
0159                             const Direction dirn, const AnimationType type);
0160 
0161     /**
0162      * Just as the game starts, ensure that all frames of the "hero" and "enemy"
0163      * sprites have been rendered. This is to avoid hiccups in animation in the
0164      * first few seconds of play or demo.
0165      */
0166     void preRenderSprites();
0167 
0168     void setMousePos (const int i, const int j);
0169     void getMousePos (int & i, int & j);
0170 
0171 Q_SIGNALS:
0172     void fadeFinished();
0173     void redrawEditToolbar();
0174 
0175 private:
0176     /*
0177      * Actions performed whenever the viewport is resized or a different theme
0178      * is loaded.
0179      */
0180     void redrawScene    ();
0181 
0182     /*
0183      * Load and set the size and position of the KGameRenderedItem's which make
0184      * up the border layout.
0185      */
0186     void drawBorder     ();
0187 
0188     /*
0189      * Draw a frame around the playing area when there are no border tiles.
0190      */
0191     void drawFrame       ();
0192 
0193     /*
0194      * Load and set the size and position of the background image for the
0195      * current level.
0196      *
0197      * @param level The current level.
0198      */
0199     void loadBackground (const int level);
0200 
0201     /*
0202      * Add a new element, with coordinates x and y, to the border-layout.
0203      *
0204      * @param spriteKey The sprite key of the requested item.
0205      * @param x         The item's x coordinate.
0206      * @param y         The item's y coordinate.
0207      */
0208     void setBorderTile  (const QString &spriteKey, const int x, const int y);
0209 
0210     /*
0211      * Resize a game's visual element.
0212      *
0213      * @param tile      The element to be resized.
0214      * @param tileSize  The new size.
0215      */
0216     void setTile        (KGameRenderedItem * tile, const int tileSize,
0217                          const int i, const int j);
0218 
0219     KGrView             *   m_view;
0220     KGrRenderer         *   m_renderer;
0221     KGameRenderedItem   *   m_background;
0222     unsigned int            m_level;
0223 
0224     QGraphicsRectItem   *   m_frame;
0225 
0226     // Text items. 
0227     QGraphicsSimpleTextItem * m_title;
0228     QGraphicsSimpleTextItem * m_replayMessage;
0229     QGraphicsSimpleTextItem * m_livesText;
0230     QGraphicsSimpleTextItem * m_scoreText;
0231     QGraphicsSimpleTextItem * m_hasHintText;
0232     QGraphicsSimpleTextItem * m_pauseResumeText;
0233 
0234     int                     m_heroId;
0235     int                     m_tilesWide;
0236     int                     m_tilesHigh;
0237     int                     m_tileSize;
0238     int                     m_toolbarTileSize;
0239 
0240     bool                    m_sizeChanged;
0241     bool                    m_themeChanged;
0242 
0243     // The animated sprites for dug bricks, hero and enemies.
0244     QList <KGrSprite *> m_sprites;
0245 
0246     // The visible elements of the scenario (tiles and borders), excluding the
0247     // background picture and the animated sprites.
0248     QList <KGameRenderedItem *> m_tiles;
0249 
0250     // The type of each tile stored in m_tiles.
0251     QByteArray m_tileTypes;
0252 
0253     bool enemiesShowGold;       // Show or conceal if enemies have gold.
0254 
0255     int m_topLeftX;
0256     int m_topLeftY;
0257 
0258     QCursor * m_mouse;
0259 
0260     void setTextFont (QGraphicsSimpleTextItem * t, double fontFraction);
0261     void placeTextItems();
0262 
0263     QGraphicsRectItem * m_spotlight;        // Fade-out/fade-in item.
0264     QTimeLine *         m_fadingTimeLine;   // Timing for fade-out/fade-in.
0265     QRadialGradient     m_gradient;     // Black with circular hole.
0266     qreal               m_maxRadius;
0267 
0268 private Q_SLOTS:
0269     void drawSpotlight (qreal ratio);       // Animate m_spotlight.
0270 };
0271 
0272 #endif // KGRSCENE_H