File indexing completed on 2024-11-03 03:46:54

0001 /*
0002     SPDX-FileCopyrightText: 2010 Ni Hui <shuizhuyuanluo@126.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #ifndef GAMESCENE_H
0008 #define GAMESCENE_H
0009 
0010 #include <QGraphicsScene>
0011 #include <QList>
0012 #include <QUndoStack>
0013 
0014 #include <KGameGraphicsViewRenderer>
0015 #include <KGameSound>
0016 
0017 class QSequentialAnimationGroup;
0018 class KConfigGroup;
0019 class KGamePopupItem;
0020 class Piece;
0021 /**
0022  * This class represents the game field scene.
0023  * It handles the most important game logic and rendering.
0024  */
0025 class GameScene : public QGraphicsScene
0026 {
0027     Q_OBJECT
0028     public:
0029         explicit GameScene( QObject* parent = nullptr );
0030         ~GameScene() override;
0031         /** Start a new game with custom size, color count and game id */
0032         void startNewGame( int pwc, int phc, int colorCount, int gameId );
0033         /** Load a game from config */
0034         void loadGame( const KConfigGroup& config );
0035         /** Save the current game to config */
0036         void saveGame( KConfigGroup& config ) const;
0037         /** Restart the current game, all the undo/redo history will be lost */
0038         void restartGame();
0039         /** Pause/Unpause the current game */
0040         void setPaused( bool isPaused );
0041         /** @return whether the current game has been finished */
0042         bool isGameFinished() const;
0043         /** Change the background type */
0044         void setBackgroundType( int type );
0045         /** Determine whether to show the bound lines between different colors */
0046         void setShowBoundLines( bool isShowing );
0047         /** Determine whether to enable the animation when removing pieces */
0048         void setEnableAnimation( bool isEnabled );
0049         /** Determine whether the pieces should be highlighted when hovered */
0050         void setEnableHighlight( bool isEnabled );
0051         /** The MainWindow needs a ref. to this for KGameThemeSelector */
0052         KGameThemeProvider* themeProvider() const;
0053     Q_SIGNALS:
0054         /** Emitted when undo action enable or disable */
0055         void canUndoChanged( bool canUndo );
0056         /** Emitted when redo action enable or disable */
0057         void canRedoChanged( bool canRedo );
0058         /** Emitted when the marked piece count changes */
0059         void markedCountChanged( int markedCount );
0060         /** Emitted when the remaining piece count changes */
0061         void remainCountChanged( int remainCount );
0062         /** Emitted when the game has been finished */
0063         void gameFinished( int remainCount );
0064     public Q_SLOTS:
0065         /** Undo the last move */
0066         void undoMove();
0067         /** Redo the last undo */
0068         void redoMove();
0069         /** Undo all */
0070         void undoAllMove();
0071         /** Redo all */
0072         void redoAllMove();
0073     protected:
0074         /** Reimplemented for drawing the background depending on the settings */
0075         void drawBackground( QPainter* painter, const QRectF& rect ) override;
0076     private Q_SLOTS:
0077         /** Check whether the player has no way to remove any pieces, emit signals if finished */
0078         void checkGameFinished();
0079         /** Try to highlight the pieces of the same color at ( x y ) */
0080         void highlightPieces( int x, int y );
0081         /** Try to unhighlight the pieces of the same color at ( x y ) */
0082         void unhighlightPieces( int x, int y );
0083         /** Try to remove the pieces of the same color at ( x y ) */
0084         void removePieces( int x, int y );
0085         /** Resize the game scene, layout all the pieces and bound lines */
0086         void resize( const QRectF& size );
0087         /** Update all the pieces and bound lines */
0088         void updateScene();
0089         /** Update all the bound lines */
0090         void updateBoundLines();
0091     private:
0092         /** Internal function used to help perform piece function recursively */
0093         void traverseNeighbors( int x, int y, int color, bool (GameScene::*func)(Piece*) );
0094         /** Internal function used to help highlight pieces recursively */
0095         bool highlightPiece( Piece* p );
0096         /** Internal function used to help unhighlight pieces recursively */
0097         bool unhighlightPiece( Piece* p );
0098         /** Internal function used to help remove pieces recursively */
0099         bool removePiece( Piece* p );
0100         /** Internal function used to check whether the piece can be removed */
0101         bool canRemovePiece( int x, int y );
0102         /** Internal function used to caluculate the marked piece count */
0103         int currentMarkedCount() const;
0104         /** Internal function used to caluculate the remaining piece count */
0105         int currentRemainCount() const;
0106         /** The game graphics item renderer */
0107         KGameGraphicsViewRenderer m_renderer;
0108         /** The popup messenger used when game paused or finished */
0109         KGamePopupItem* m_messenger;
0110         /** The container of all the pieces */
0111         QList<Piece*> m_pieces;
0112         /** The undo stack recording moves */
0113         QUndoStack m_undoStack;
0114         /** True if the bound lines should be showed */
0115         bool m_showBoundLines;
0116         /** True if the animation of removing pieces should be used */
0117         bool m_enableAnimation;
0118         /** True if the pieces should be highlighted when hovered */
0119         bool m_enableHighlight;
0120         /** The background type */
0121         int m_backgroundType;
0122         /** The x-position of the currently hovered piece */
0123         int m_currentlyHoveredPieceX;
0124         /** The y-position of the currently hovered piece */
0125         int m_currentlyHoveredPieceY;
0126         /** The count of pieces in a row */
0127         int PWC;
0128         /** The count of pieces in a column */
0129         int PHC;
0130         /** The count of colors used */
0131         int m_colorCount;
0132         /** The game id */
0133         int m_gameId;
0134         /** True if the game has been paused */
0135         bool m_isPaused;
0136         /** True if the game has been finished */
0137         bool m_isFinished;
0138         /** The animation group holding the animations of removing pieces */
0139         QSequentialAnimationGroup* const m_animation;
0140 
0141         KGameSound m_soundRemove;
0142         KGameSound m_soundGameFinished;
0143 };
0144 
0145 #endif // GAMESCENE_H