1 | /******************************************************************* |
2 | * |
3 | * Copyright 2006-2007 Dmitry Suzdalev <dimsuz@gmail.com> |
4 | * Copyright 2010 Brian Croom <brian.s.croom@gmail.com> |
5 | * |
6 | * This file is part of the KDE project "KAtomic" |
7 | * |
8 | * KAtomic is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by |
10 | * the Free Software Foundation; either version 2, or (at your option) |
11 | * any later version. |
12 | * |
13 | * KAtomic is distributed in the hope that it will be useful, |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | * GNU General Public License for more details. |
17 | * |
18 | * You should have received a copy of the GNU General Public License |
19 | * along with KAtomic; see the file COPYING. If not, write to |
20 | * the Free Software Foundation, 51 Franklin Street, Fifth Floor, |
21 | * Boston, MA 02110-1301, USA. |
22 | * |
23 | ********************************************************************/ |
24 | #ifndef PLAYFIELD_H |
25 | #define PLAYFIELD_H |
26 | #include <QGraphicsScene> |
27 | #include <KGameRenderer> |
28 | #include <QList> |
29 | #include <QStack> |
30 | |
31 | #include "commondefs.h" |
32 | |
33 | #define MIN_ELEM_SIZE 30 |
34 | |
35 | class KConfigGroup; |
36 | class AtomFieldItem; |
37 | class ArrowFieldItem; |
38 | class MoleculePreviewItem; |
39 | class QTimeLine; |
40 | class ; |
41 | class LevelData; |
42 | |
43 | /** |
44 | * KAtomic level playfield |
45 | */ |
46 | class PlayField : public QGraphicsScene |
47 | { |
48 | Q_OBJECT |
49 | public: |
50 | enum Direction { Up=0, Down, Left, Right }; |
51 | /** |
52 | * Constructor |
53 | */ |
54 | explicit PlayField( QObject *parent ); |
55 | /** |
56 | * Destructor |
57 | */ |
58 | virtual ~PlayField(); |
59 | /** |
60 | * Resizes playfield to width,height |
61 | */ |
62 | void resize( int width, int height ); |
63 | /** |
64 | * Loads level |
65 | */ |
66 | void setLevelData(const LevelData* level); |
67 | /** |
68 | * Sets animation speed (0-slow, 1-normal, 2-fast) |
69 | */ |
70 | void setAnimationSpeed(int speed); |
71 | /** |
72 | * Animates currently selected atom movement in direction dir |
73 | * @param numCells used on undos/redos |
74 | */ |
75 | void moveSelectedAtom( Direction dir, int numCells=0 ); |
76 | /** |
77 | * Saves the current game to config object |
78 | */ |
79 | void saveGame(KConfigGroup& config) const; |
80 | /** |
81 | * Loads game from config object |
82 | */ |
83 | void loadGame(const KConfigGroup& config); |
84 | /** |
85 | * Returns whether level is finished already |
86 | */ |
87 | bool isLevelFinished() const { return m_levelFinished; } |
88 | /** |
89 | * Displays a passive popup message at the bottom of the scene |
90 | */ |
91 | void showMessage( const QString& message ); |
92 | /** |
93 | * Name of the current molecule |
94 | */ |
95 | QString moleculeName() const; |
96 | /** |
97 | * The caching SVG pixmap renderer |
98 | */ |
99 | KGameRenderer* renderer() { return &m_renderer; } |
100 | |
101 | public slots: |
102 | /** |
103 | * Selects next atom |
104 | */ |
105 | void nextAtom(); |
106 | /** |
107 | * Selects previous atom |
108 | */ |
109 | void previousAtom(); |
110 | /** |
111 | * Undoes one movement |
112 | */ |
113 | void undo(); |
114 | /** |
115 | * Redoes one movement |
116 | */ |
117 | void redo(); |
118 | /** |
119 | * Undoes all movements |
120 | */ |
121 | void undoAll(); |
122 | /** |
123 | * Redoes all movements |
124 | */ |
125 | void redoAll(); |
126 | signals: |
127 | void gameOver(int numMoves); |
128 | void updateMoves(int); |
129 | void enableUndo(bool); |
130 | void enableRedo(bool); |
131 | private slots: |
132 | void atomAnimFrameChanged(int frame); |
133 | private: |
134 | virtual void drawForeground( QPainter*, const QRectF& ); |
135 | virtual void mousePressEvent( QGraphicsSceneMouseEvent* ev ); |
136 | |
137 | /** |
138 | * Checks if molecule is finished |
139 | */ |
140 | bool checkDone() const; |
141 | /** |
142 | * Re-renders atoms&arrows Pixmaps, updates their positions |
143 | */ |
144 | void updateFieldItems(); |
145 | /** |
146 | * Updates arrows around selected atom |
147 | */ |
148 | void updateArrows(bool justHide=false); |
149 | /** |
150 | * Set the background brush to a properly sized pixmap |
151 | */ |
152 | void updateBackground(); |
153 | /** |
154 | * Returns true if Field cell (x,y) is empty, i.e. it isn't a wall and has no atom |
155 | */ |
156 | bool cellIsEmpty(int x, int y) const; |
157 | /** |
158 | * Returns true if atom animation is running |
159 | */ |
160 | bool isAnimating() const; |
161 | |
162 | inline int toPixX( int fieldX ) const { return fieldX*m_elemSize; } |
163 | inline int toPixY( int fieldY ) const { return fieldY*m_elemSize; } |
164 | inline int toFieldX( int pixX ) const { return pixX/m_elemSize; } |
165 | inline int toFieldY( int pixY ) const { return pixY/m_elemSize; } |
166 | inline int fieldCenterX() const { return toPixX(0) + m_elemSize*FIELD_SIZE/2; } |
167 | inline int fieldCenterY() const { return toPixY(0) + m_elemSize*FIELD_SIZE/2; } |
168 | |
169 | /** |
170 | * Renderer object |
171 | */ |
172 | KGameRenderer m_renderer; |
173 | /** |
174 | * Number of moves made for current level |
175 | */ |
176 | int m_numMoves; |
177 | /** |
178 | * Level Data |
179 | */ |
180 | const LevelData* m_levelData; |
181 | /** |
182 | * Element (i.e. atom, wall, arrow) size |
183 | */ |
184 | int m_elemSize; |
185 | /** |
186 | * List of atom QGraphicsItems |
187 | */ |
188 | QList<AtomFieldItem*> m_atoms; |
189 | /** |
190 | * Arrow items |
191 | */ |
192 | ArrowFieldItem *m_upArrow, *m_leftArrow, *m_downArrow, *m_rightArrow; |
193 | /** |
194 | * Item used to show messages to user |
195 | */ |
196 | KGamePopupItem *m_messageItem; |
197 | /** |
198 | * Index of currently selected atom |
199 | */ |
200 | int m_selIdx; |
201 | /** |
202 | * Direction in which current atom animation moves |
203 | */ |
204 | Direction m_dir; |
205 | /** |
206 | * Animation speed. Atom will move at 1cell in m_animSpeed msec speed |
207 | */ |
208 | int m_animSpeed; |
209 | /** |
210 | * Timeline object to control atom movement animation |
211 | */ |
212 | QTimeLine *m_atomTimeLine; |
213 | /** |
214 | * True if current level is finished and thus all player input should be disabled |
215 | */ |
216 | bool m_levelFinished; |
217 | |
218 | struct AtomMove |
219 | { |
220 | int atomIdx; // atom index in m_atoms |
221 | Direction dir; |
222 | int numCells; |
223 | AtomMove( int idx=-1, Direction d=Up, int nc=0 ) |
224 | : atomIdx(idx), dir(d), numCells(nc) { } |
225 | }; |
226 | QStack<AtomMove> m_undoStack; |
227 | QStack<AtomMove> m_redoStack; |
228 | |
229 | MoleculePreviewItem *m_previewItem; |
230 | }; |
231 | |
232 | #endif |
233 | |