File indexing completed on 2024-03-24 04:05:15
0001 /* 0002 This file is part of the KDE project "KLines" 0003 0004 SPDX-FileCopyrightText: 2006 Dmitry Suzdalev <dimsuz@gmail.com> 0005 0006 SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #ifndef KL_SCENE_H 0010 #define KL_SCENE_H 0011 0012 #include <QGraphicsScene> 0013 #include <QRandomGenerator> 0014 0015 #include "commondefs.h" 0016 0017 static const int FIELD_SIZE=9; 0018 0019 class KLinesAnimator; 0020 class BallItem; 0021 class PreviewItem; 0022 class QGraphicsRectItem; 0023 class KGamePopupItem; 0024 0025 /** 0026 * Displays and drives the game 0027 */ 0028 class KLinesScene : public QGraphicsScene 0029 { 0030 Q_OBJECT 0031 public: 0032 explicit KLinesScene( QObject *parent ); 0033 ~KLinesScene() override; 0034 /** 0035 * Resizes scene 0036 */ 0037 void resizeScene( int width, int height ); 0038 /** 0039 * Brings in next three balls to scene 0040 */ 0041 void nextThreeBalls(); 0042 /** 0043 * Show/Hide the preview zone 0044 */ 0045 void setPreviewZoneVisible( bool visible ); 0046 /** 0047 * This score points will be added as an additional bonus to 0048 * every score resulted from ball erasing event. 0049 * For example 1 score point is added if the game is played with 0050 * hidden preview widget. 0051 * By default no bonus is added. 0052 */ 0053 void setBonusScorePoints( int points ) { m_bonusScore = points; } 0054 /** 0055 * Returns colors of the 3 balls in the next turn 0056 */ 0057 QList<BallColor> nextColors() const { return m_nextColors; } 0058 /** 0059 * Returns ballitem in field position pos or 0 if there 0060 * is no item there 0061 */ 0062 BallItem* ballAt( FieldPos pos ) { return m_field[pos.x][pos.y]; } 0063 /** 0064 * Overloaded above function 0065 */ 0066 BallItem* ballAt( int x, int y ) { return m_field[x][y]; } 0067 /** 0068 * Field coords to pixel coords 0069 */ 0070 inline QPointF fieldToPix(FieldPos fpos) const 0071 { 0072 return QPointF( m_playFieldRect.x() + m_playFieldBorderSize + fpos.x*m_cellSize, 0073 m_playFieldRect.y() + m_playFieldBorderSize + fpos.y*m_cellSize ); 0074 } 0075 /** 0076 * Pixel coords to field coords 0077 */ 0078 inline FieldPos pixToField( QPointF p ) const 0079 { 0080 return FieldPos(static_cast<int>(( p.x()-m_playFieldRect.x()-m_playFieldBorderSize )/m_cellSize), 0081 static_cast<int>(( p.y()-m_playFieldRect.y()-m_playFieldBorderSize )/m_cellSize)); 0082 } 0083 public Q_SLOTS: 0084 /** 0085 * Starts new game 0086 */ 0087 void startNewGame(); 0088 /** 0089 * Ends game 0090 */ 0091 void endGame(); 0092 /** 0093 * Ends current and starts next turn explicitly 0094 */ 0095 void endTurn(); 0096 /** 0097 * Undoes one move 0098 */ 0099 void undo(); 0100 /** 0101 * Moves keyboard-playing focus rect to the left 0102 */ 0103 void moveFocusLeft(); 0104 /** 0105 * Moves keyboard-playing focus rect to the right 0106 */ 0107 void moveFocusRight(); 0108 /** 0109 * Moves keyboard-playing focus rect to the up 0110 */ 0111 void moveFocusUp(); 0112 /** 0113 * Moves keyboard-playing focus rect to the down 0114 */ 0115 void moveFocusDown(); 0116 /** 0117 * Takes corresponding action on cell under focus rect 0118 */ 0119 void cellSelected(); 0120 Q_SIGNALS: 0121 void scoreChanged(int); 0122 void stateChanged(const QString &); 0123 void gameOver(int); 0124 private Q_SLOTS: 0125 void moveAnimFinished(); 0126 void removeAnimFinished(); 0127 void bornAnimFinished(); 0128 private: 0129 /** 0130 * Creates a ball and places it in random free cell 0131 * @param c color of the ball 0132 * @return ball placed 0133 */ 0134 BallItem* randomlyPlaceBall(BallColor c); 0135 /** 0136 * Searches for 5 or more balls in a row and deletes them from field 0137 */ 0138 void searchAndErase(); 0139 /** 0140 * This function takes one of two actions: 0141 * If there's a ball at fpos, it will be selected. 0142 * Otherwise if the cell at fpos is empty and there's 0143 * a selected ball in some other cell it will be moved to fpos 0144 * (if the move is possible, of course) 0145 */ 0146 void selectOrMove(FieldPos fpos ); 0147 /** 0148 * Saves game state information to be used during undo 0149 */ 0150 void saveUndoInfo(); 0151 /** Does some actions upon game over. Called from various places where 0152 * it is clear that game is now over. emits gameOver(int) signal 0153 */ 0154 void gameOverHandler(); 0155 0156 void drawBackground( QPainter*, const QRectF& ) override; 0157 void mousePressEvent( QGraphicsSceneMouseEvent* ) override; 0158 0159 /** 0160 * This array represents the play field. 0161 * Each cell holds the pointer to BallItem 0162 * or 0 if there's no ball in that cell 0163 */ 0164 BallItem* m_field[FIELD_SIZE][FIELD_SIZE]; 0165 /** 0166 * Used to start game animations 0167 * This object knows how to do some ball animations 0168 */ 0169 KLinesAnimator* m_animator; 0170 /** 0171 * We need random numbers in this game 0172 */ 0173 QRandomGenerator m_randomSeq; 0174 /** 0175 * Area of playfield (with border included - if any exists in theme) 0176 */ 0177 QRect m_playFieldRect; 0178 /** 0179 * Size of a playfield border. 0180 * Equals 0 if there's no border element in current theme 0181 */ 0182 int m_playFieldBorderSize; 0183 0184 /** 0185 * Position of selected ball (-1,-1) if none 0186 */ 0187 FieldPos m_selPos; 0188 /** 0189 * Number of free cells in the field 0190 */ 0191 int m_numFreeCells; 0192 /** 0193 * Current game score 0194 */ 0195 int m_score; 0196 /** 0197 * Bonus points added to score upon ball erasing 0198 * @see setBonusScorePoints() 0199 */ 0200 int m_bonusScore; 0201 /** 0202 * Cell size in pixels 0203 */ 0204 int m_cellSize; 0205 /** 0206 * Is true if preview zone is visible 0207 */ 0208 bool m_previewZoneVisible; 0209 /** 0210 * Varable which is needed for little trick (tm). 0211 * Read more about it in removeAnimFinished() slot 0212 */ 0213 bool m_placeBalls; 0214 /** 0215 * Items pending for removal after remove-anim finishes 0216 */ 0217 QList<BallItem*> m_itemsToDelete; 0218 /** 0219 * Colors of the next turn's balls 0220 */ 0221 QList<BallColor> m_nextColors; 0222 /** 0223 * Keyboard-playing focus indication 0224 */ 0225 QGraphicsRectItem *m_focusItem; 0226 /** 0227 * Item which displays next balls preview 0228 */ 0229 PreviewItem *m_previewItem; 0230 /** 0231 * Item to show popup messages to user 0232 */ 0233 KGamePopupItem *m_popupItem; 0234 /** 0235 * Struct for holding game state - used on undos 0236 */ 0237 struct UndoInfo 0238 { 0239 int numFreeCells; 0240 int score; 0241 QList<BallColor> nextColors; 0242 BallColor fcolors[FIELD_SIZE][FIELD_SIZE]; 0243 }; 0244 /** 0245 * Holds game state for undo. 0246 * It is saved before every new turn 0247 */ 0248 UndoInfo m_undoInfo; 0249 bool m_gameOver; 0250 }; 0251 0252 #endif