1 | /******************************************************************* |
2 | * |
3 | * Copyright 2006 Dmitry Suzdalev <dimsuz@gmail.com> |
4 | * |
5 | * This file is part of the KDE project "KLines" |
6 | * |
7 | * KLines is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by |
9 | * the Free Software Foundation; either version 2, or (at your option) |
10 | * any later version. |
11 | * |
12 | * KLines is distributed in the hope that it will be useful, |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | * GNU General Public License for more details. |
16 | * |
17 | * You should have received a copy of the GNU General Public License |
18 | * along with KLines; see the file COPYING. If not, write to |
19 | * the Free Software Foundation, 51 Franklin Street, Fifth Floor, |
20 | * Boston, MA 02110-1301, USA. |
21 | * |
22 | ********************************************************************/ |
23 | #ifndef KL_SCENE_H |
24 | #define KL_SCENE_H |
25 | |
26 | #include <QGraphicsScene> |
27 | #include <KRandomSequence> |
28 | |
29 | #include "commondefs.h" |
30 | |
31 | static const int FIELD_SIZE=9; |
32 | |
33 | class KLinesAnimator; |
34 | class BallItem; |
35 | class PreviewItem; |
36 | class QGraphicsRectItem; |
37 | class ; |
38 | |
39 | /** |
40 | * Displays and drives the game |
41 | */ |
42 | class KLinesScene : public QGraphicsScene |
43 | { |
44 | Q_OBJECT |
45 | public: |
46 | explicit KLinesScene( QObject *parent ); |
47 | ~KLinesScene(); |
48 | /** |
49 | * Resizes scene |
50 | */ |
51 | void resizeScene( int width, int height ); |
52 | /** |
53 | * Brings in next three balls to scene |
54 | */ |
55 | void nextThreeBalls(); |
56 | /** |
57 | * Show/Hide the preview zone |
58 | */ |
59 | void setPreviewZoneVisible( bool visible ); |
60 | /** |
61 | * This score points will be added as an additional bonus to |
62 | * every score resulted from ball erasing event. |
63 | * For example 1 score point is added if the game is played with |
64 | * hidden preview widget. |
65 | * By default no bonus is added. |
66 | */ |
67 | void setBonusScorePoints( int points ) { m_bonusScore = points; } |
68 | /** |
69 | * Returns colors of the 3 balls in the next turn |
70 | */ |
71 | QList<BallColor> nextColors() const { return m_nextColors; } |
72 | /** |
73 | * Returns ballitem in field position pos or 0 if there |
74 | * is no item there |
75 | */ |
76 | BallItem* ballAt( const FieldPos& pos ) { return m_field[pos.x][pos.y]; } |
77 | /** |
78 | * Overloaded above function |
79 | */ |
80 | BallItem* ballAt( int x, int y ) { return m_field[x][y]; } |
81 | /** |
82 | * Field coords to pixel coords |
83 | */ |
84 | inline QPointF fieldToPix(const FieldPos& fpos) const |
85 | { |
86 | return QPointF( m_playFieldRect.x() + m_playFieldBorderSize + fpos.x*m_cellSize, |
87 | m_playFieldRect.y() + m_playFieldBorderSize + fpos.y*m_cellSize ); |
88 | } |
89 | /** |
90 | * Pixel coords to field coords |
91 | */ |
92 | inline FieldPos pixToField( const QPointF& p ) const |
93 | { |
94 | return FieldPos(static_cast<int>(( p.x()-m_playFieldRect.x()-m_playFieldBorderSize )/m_cellSize), |
95 | static_cast<int>(( p.y()-m_playFieldRect.y()-m_playFieldBorderSize )/m_cellSize)); |
96 | } |
97 | public slots: |
98 | /** |
99 | * Starts new game |
100 | */ |
101 | void startNewGame(); |
102 | /** |
103 | * Ends current and starts next turn explicitly |
104 | */ |
105 | void endTurn(); |
106 | /** |
107 | * Undoes one move |
108 | */ |
109 | void undo(); |
110 | /** |
111 | * Moves keyboard-playing focus rect to the left |
112 | */ |
113 | void moveFocusLeft(); |
114 | /** |
115 | * Moves keyboard-playing focus rect to the right |
116 | */ |
117 | void moveFocusRight(); |
118 | /** |
119 | * Moves keyboard-playing focus rect to the up |
120 | */ |
121 | void moveFocusUp(); |
122 | /** |
123 | * Moves keyboard-playing focus rect to the down |
124 | */ |
125 | void moveFocusDown(); |
126 | /** |
127 | * Takes corresponding action on cell under focus rect |
128 | */ |
129 | void cellSelected(); |
130 | signals: |
131 | void scoreChanged(int); |
132 | void stateChanged(const QString &); |
133 | void gameOver(int); |
134 | private slots: |
135 | void moveAnimFinished(); |
136 | void removeAnimFinished(); |
137 | void bornAnimFinished(); |
138 | private: |
139 | /** |
140 | * Creates a ball and places it in random free cell |
141 | * @param c color of the ball |
142 | * @return ball placed |
143 | */ |
144 | BallItem* randomlyPlaceBall(BallColor c); |
145 | /** |
146 | * Searches for 5 or more balls in a row and deletes them from field |
147 | */ |
148 | void searchAndErase(); |
149 | /** |
150 | * This function takes one of two actions: |
151 | * If there's a ball at fpos, it will be selected. |
152 | * Otherwise if the cell at fpos is empty and there's |
153 | * a selected ball in some other cell it will be moved to fpos |
154 | * (if the move is possible, of course) |
155 | */ |
156 | void selectOrMove( const FieldPos& fpos ); |
157 | /** |
158 | * Saves game state information to be used during undo |
159 | */ |
160 | void saveUndoInfo(); |
161 | /** Does some actions upon game over. Called from various places where |
162 | * it is clear that game is now over. emits gameOver(int) signal |
163 | */ |
164 | void gameOverHandler(); |
165 | |
166 | virtual void drawBackground( QPainter*, const QRectF& ); |
167 | virtual void mousePressEvent( QGraphicsSceneMouseEvent* ); |
168 | |
169 | /** |
170 | * This array represents the play field. |
171 | * Each cell holds the pointer to BallItem |
172 | * or 0 if there's no ball in that cell |
173 | */ |
174 | BallItem* m_field[FIELD_SIZE][FIELD_SIZE]; |
175 | /** |
176 | * Used to start game animations |
177 | * This object knows how to do some ball animations |
178 | */ |
179 | KLinesAnimator* m_animator; |
180 | /** |
181 | * We need random numbers in this game |
182 | */ |
183 | KRandomSequence m_randomSeq; |
184 | /** |
185 | * Area of playfield (with border included - if any exists in theme) |
186 | */ |
187 | QRect m_playFieldRect; |
188 | /** |
189 | * Size of a playfield border. |
190 | * Equals 0 if there's no border element in current theme |
191 | */ |
192 | int m_playFieldBorderSize; |
193 | |
194 | /** |
195 | * Position of selected ball (-1,-1) if none |
196 | */ |
197 | FieldPos m_selPos; |
198 | /** |
199 | * Number of free cells in the field |
200 | */ |
201 | int m_numFreeCells; |
202 | /** |
203 | * Current game score |
204 | */ |
205 | int m_score; |
206 | /** |
207 | * Bonus points added to score upon ball erasing |
208 | * @see setBonusScorePoints() |
209 | */ |
210 | int m_bonusScore; |
211 | /** |
212 | * Cell size in pixels |
213 | */ |
214 | int m_cellSize; |
215 | /** |
216 | * Is true if preview zone is visible |
217 | */ |
218 | bool m_previewZoneVisible; |
219 | /** |
220 | * Varable which is needed for little trick (tm). |
221 | * Read more about it in removeAnimFinished() slot |
222 | */ |
223 | bool m_placeBalls; |
224 | /** |
225 | * Items pending for removal after remove-anim finishes |
226 | */ |
227 | QList<BallItem*> m_itemsToDelete; |
228 | /** |
229 | * Colors of the next turn's balls |
230 | */ |
231 | QList<BallColor> m_nextColors; |
232 | /** |
233 | * Keyboard-playing focus indication |
234 | */ |
235 | QGraphicsRectItem *m_focusItem; |
236 | /** |
237 | * Item which displays next balls preview |
238 | */ |
239 | PreviewItem *m_previewItem; |
240 | /** |
241 | * Item to show popup messages to user |
242 | */ |
243 | KGamePopupItem *; |
244 | /** |
245 | * Struct for holding game state - used on undos |
246 | */ |
247 | struct UndoInfo |
248 | { |
249 | int numFreeCells; |
250 | int score; |
251 | QList<BallColor> nextColors; |
252 | BallColor fcolors[FIELD_SIZE][FIELD_SIZE]; |
253 | }; |
254 | /** |
255 | * Holds game state for undo. |
256 | * It is saved before every new turn |
257 | */ |
258 | UndoInfo m_undoInfo; |
259 | bool m_gameOver; |
260 | }; |
261 | |
262 | #endif |
263 | |