Changeset View
Changeset View
Standalone View
Standalone View
gamewidget.cpp
Show All 10 Lines | |||||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
12 | * Library General Public License for more details. | 12 | * Library General Public License for more details. | ||
13 | * | 13 | * | ||
14 | * You should have received a copy of the GNU Library General Public | 14 | * You should have received a copy of the GNU Library General Public | ||
15 | * License along with this program; if not, write to the Free | 15 | * License along with this program; if not, write to the Free | ||
16 | * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 16 | * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
17 | */ | 17 | */ | ||
18 | 18 | | |||
19 | #include "gamewidget.h" | | |||
20 | #include "settings.h" | | |||
21 | #include "wall.h" | | |||
22 | #include "debug.h" | | |||
23 | | ||||
24 | #include <QPalette> | 19 | #include <QPalette> | ||
25 | #include <QTimer> | 20 | #include <QTimer> | ||
26 | #include <QStandardPaths> | 21 | #include <QStandardPaths> | ||
27 | 22 | | |||
28 | #include <KgDifficulty> | 23 | #include <KgDifficulty> | ||
29 | #include <KgThemeProvider> | 24 | #include <KgThemeProvider> | ||
30 | #include <KColorScheme> | 25 | #include <KColorScheme> | ||
31 | #include <KLocalizedString> | 26 | #include <KLocalizedString> | ||
32 | 27 | | |||
28 | #include "gamewidget.h" | ||||
29 | #include "settings.h" | ||||
30 | #include "wall.h" | ||||
31 | #include "debug.h" | ||||
32 | | ||||
33 | static const int MIN_MARGIN = 50; | 33 | static const int MIN_MARGIN = 50; | ||
34 | static const int GAME_TIME_DELAY = 1000; | 34 | static const int GAME_TIME_DELAY = 1000; | ||
35 | static const int MIN_FILL_PERCENT = 75; | 35 | static const int MIN_FILL_PERCENT = 75; | ||
36 | static const int POINTS_FOR_LIFE = 15; | 36 | static const int POINTS_FOR_LIFE = 15; | ||
37 | static const int TICKS_PER_SECOND = 1000 / GAME_TIME_DELAY; | 37 | static const int TICKS_PER_SECOND = 1000 / GAME_TIME_DELAY; | ||
38 | 38 | | |||
39 | /** | ||||
40 | * KBounceGameWidget class | ||||
41 | * | ||||
42 | * Constructor to set game widget configurations | ||||
43 | * @param parent Superclass parameter | ||||
44 | * @see gamewidget.h | ||||
45 | */ | ||||
39 | KBounceGameWidget::KBounceGameWidget( QWidget* parent ) | 46 | KBounceGameWidget::KBounceGameWidget( QWidget* parent ) | ||
40 | : QGraphicsView( parent ) | 47 | : QGraphicsView( parent ) | ||
41 | , m_state( BeforeFirstGame ) | 48 | , kBounceGameWidget_state( BeforeFirstGame ) // set initial game state | ||
42 | , m_bonus( 0 ) | 49 | , kBounceGameWidget_bonus( 0 ) // set initial bonus value | ||
43 | , m_level( 0 ) | 50 | , kBounceGameWidget_level( 0 ) // set initial level value | ||
44 | , m_lives( 0 ) | 51 | , kBounceGameWidget_lives( 0 ) // set initial lives value | ||
45 | , m_time( 0 ) | 52 | , kBounceGameWidget_time( 0 ) // set initial time value | ||
46 | , m_vertical( false ) | 53 | , kBounceGameWidget_vertical( false ) // set initial orientation flag | ||
47 | , m_soundTimeout( QStandardPaths::locate( QStandardPaths::AppDataLocation, QStringLiteral("sounds/timeout.wav") ) ) | 54 | , kBounceGameWidget_soundTimeout( QStandardPaths::locate( QStandardPaths::AppDataLocation, QStringLiteral("sounds/timeout.wav") ) ) // set timout sound asset | ||
48 | { | 55 | { | ||
schwarzer: You kept the spaces inside the braces here. On purpose? | |||||
49 | m_board = new KBounceBoard( &m_renderer ); | 56 | | ||
50 | connect(m_board, &KBounceBoard::fillChanged, this, &KBounceGameWidget::onFillChanged); | 57 | // Create game board (Game rules) | ||
51 | connect(m_board, &KBounceBoard::wallDied, this, &KBounceGameWidget::onWallDied); | 58 | kBounceGameWidget_board = new KBounceBoard(&kBounceGameWidget_renderer); | ||
52 | 59 | | |||
53 | m_overlay = new QGraphicsPixmapItem(); | 60 | // Add game rule "fill board" | ||
54 | m_overlay->hide(); | 61 | connect(kBounceGameWidget_board, &KBounceBoard::fillChanged, this, &KBounceGameWidget::onFillChanged); | ||
55 | 62 | | |||
56 | m_clock = new QTimer( this ); | 63 | // Add game rule "die on wall" | ||
57 | m_clock->setInterval( GAME_TIME_DELAY ); | 64 | connect(kBounceGameWidget_board, &KBounceBoard::wallDied, this, &KBounceGameWidget::onWallDied); | ||
58 | connect(m_clock, &QTimer::timeout, this, &KBounceGameWidget::tick); | 65 | | ||
66 | // Create and hide overlay message box | ||||
67 | kBounceGameWidget_overlay = new QGraphicsPixmapItem(); | ||||
68 | kBounceGameWidget_overlay->hide(); | ||||
69 | | ||||
70 | // Create game timer | ||||
71 | kBounceGameWidget_clock = new QTimer(this); | ||||
72 | | ||||
73 | // Set timer interval between ticks | ||||
74 | kBounceGameWidget_clock->setInterval(GAME_TIME_DELAY); | ||||
75 | | ||||
76 | // Add game rule "timeout" | ||||
77 | connect(kBounceGameWidget_clock, &QTimer::timeout, this, &KBounceGameWidget::tick); | ||||
78 | | ||||
79 | // Add game rule about lives | ||||
59 | connect(this, &KBounceGameWidget::livesChanged, this, &KBounceGameWidget::onLivesChanged); | 80 | connect(this, &KBounceGameWidget::livesChanged, this, &KBounceGameWidget::onLivesChanged); | ||
60 | 81 | | |||
82 | // ? | ||||
61 | setMouseTracking( true ); | 83 | setMouseTracking(true); | ||
62 | 84 | | |||
63 | connect(m_renderer.themeProvider(), &KgThemeProvider::currentThemeChanged, | 85 | // Add theme controller on settings | ||
86 | connect(kBounceGameWidget_renderer.themeProvider(), &KgThemeProvider::currentThemeChanged, | ||||
64 | this, &KBounceGameWidget::settingsChanged); | 87 | this, &KBounceGameWidget::settingsChanged); | ||
65 | 88 | | |||
66 | m_scene.addItem( m_board ); | 89 | // Add game board | ||
67 | m_scene.addItem( m_overlay ); | 90 | kBounceGameWidget_scene.addItem(kBounceGameWidget_board); | ||
68 | setScene( &m_scene ); | 91 | | ||
92 | // Add overlay message box | ||||
93 | kBounceGameWidget_scene.addItem(kBounceGameWidget_overlay); | ||||
94 | | ||||
95 | // Set game scene | ||||
96 | setScene(&kBounceGameWidget_scene); | ||||
69 | } | 97 | } | ||
70 | 98 | | |||
99 | /** | ||||
100 | * KBounceGameWidget destructor | ||||
101 | * @see gamewidget.h | ||||
102 | */ | ||||
71 | KBounceGameWidget::~KBounceGameWidget() | 103 | KBounceGameWidget::~KBounceGameWidget() | ||
72 | { | 104 | { | ||
73 | delete m_board; | 105 | delete kBounceGameWidget_board; | ||
74 | delete m_overlay; | 106 | delete kBounceGameWidget_overlay; | ||
75 | } | 107 | } | ||
76 | 108 | | |||
77 | int KBounceGameWidget::level() | 109 | /** | ||
110 | * Get current game level | ||||
111 | * @return current game level | ||||
112 | * @see gamewidget.h | ||||
113 | */ | ||||
114 | int KBounceGameWidget::getLevel() | ||||
78 | { | 115 | { | ||
79 | return m_level; | 116 | return kBounceGameWidget_level; | ||
80 | } | 117 | } | ||
81 | 118 | | |||
82 | int KBounceGameWidget::score() | 119 | /** | ||
120 | * Get current game score | ||||
121 | * @return current game score | ||||
122 | * @see gamewidget.h | ||||
123 | */ | ||||
124 | int KBounceGameWidget::getScore() | ||||
83 | { | 125 | { | ||
84 | qCDebug(KBOUNCE_LOG) << "Score:" << m_score; | 126 | qCDebug(KBOUNCE_LOG) << "Score:" << kBounceGameWidget_score; | ||
85 | return m_score; | 127 | return kBounceGameWidget_score; | ||
86 | } | 128 | } | ||
87 | 129 | | |||
130 | /** | ||||
131 | * ? | ||||
132 | * @see gamewidget.h | ||||
133 | */ | ||||
88 | QSize KBounceGameWidget::minimumSizeHint() const | 134 | QSize KBounceGameWidget::minimumSizeHint() const | ||
89 | { | 135 | { | ||
90 | return QSize( 576, 384 ); | 136 | return QSize(576, 384); | ||
91 | } | 137 | } | ||
92 | 138 | | |||
139 | /** | ||||
140 | * Set variables to close the game | ||||
141 | * @see gamewidget.h | ||||
142 | */ | ||||
93 | void KBounceGameWidget::closeGame() | 143 | void KBounceGameWidget::closeGame() | ||
94 | { | 144 | { | ||
95 | if ( m_state != BeforeFirstGame && m_state != GameOver ) | 145 | if (kBounceGameWidget_state != BeforeFirstGame && kBounceGameWidget_state != GameOver) | ||
96 | { | 146 | { | ||
97 | m_clock->stop(); | 147 | // Stop the timer | ||
98 | m_board->setPaused( true ); | 148 | kBounceGameWidget_clock->stop(); | ||
99 | m_state = GameOver; | 149 | | ||
100 | emit stateChanged( m_state ); | 150 | // Pause balls on board movement | ||
151 | kBounceGameWidget_board->setPaused(true); | ||||
152 | | ||||
153 | // Set game over state | ||||
154 | kBounceGameWidget_state = GameOver; | ||||
155 | | ||||
156 | // Emit signals to apply state | ||||
157 | emit stateChanged(kBounceGameWidget_state); | ||||
101 | emit gameOver(); | 158 | emit gameOver(); | ||
102 | 159 | | |||
160 | // Stop game | ||||
103 | Kg::difficulty()->setGameRunning( false ); | 161 | Kg::difficulty()->setGameRunning(false); | ||
162 | | ||||
163 | // Redraw the game board | ||||
104 | redraw(); | 164 | redraw(); | ||
105 | } | 165 | } | ||
106 | } | 166 | } | ||
107 | 167 | | |||
168 | /** | ||||
169 | * Start a new game | ||||
170 | * @see gamewidget.h | ||||
171 | */ | ||||
108 | void KBounceGameWidget::newGame() | 172 | void KBounceGameWidget::newGame() | ||
109 | { | 173 | { | ||
174 | // Close previous game | ||||
110 | closeGame(); | 175 | closeGame(); | ||
111 | m_level = 1; | | |||
112 | m_score = 0; | | |||
113 | 176 | | |||
114 | emit levelChanged( m_level ); | 177 | // Set initial game variables | ||
115 | emit scoreChanged( m_score ); | 178 | kBounceGameWidget_level = 1; | ||
179 | kBounceGameWidget_score = 0; | ||||
180 | | ||||
181 | // Emit signals to apply level and score | ||||
182 | emit levelChanged(kBounceGameWidget_level); | ||||
183 | emit scoreChanged(kBounceGameWidget_score); | ||||
116 | 184 | | |||
185 | // Start game | ||||
117 | Kg::difficulty()->setGameRunning( true ); | 186 | Kg::difficulty()->setGameRunning(true); | ||
187 | | ||||
188 | // Start a new level | ||||
118 | newLevel(); | 189 | newLevel(); | ||
119 | } | 190 | } | ||
120 | 191 | | |||
121 | void KBounceGameWidget::setPaused( bool val ) | 192 | /** | ||
193 | * Set state to pause the game | ||||
194 | * @param flag pause flag | ||||
195 | * @see gamewidget.h | ||||
196 | */ | ||||
197 | void KBounceGameWidget::setPaused(bool flag) | ||||
122 | { | 198 | { | ||
123 | if ( m_state == Paused && val == false ) | 199 | if ( kBounceGameWidget_state == Paused && !flag) | ||
124 | { | 200 | { | ||
125 | m_clock->start(); | 201 | // Start the timer | ||
126 | m_board->setPaused( false ); | 202 | kBounceGameWidget_clock->start(); | ||
127 | m_state = Running; | 203 | | ||
128 | emit stateChanged( m_state ); | 204 | // Unpause game board | ||
205 | kBounceGameWidget_board->setPaused(false); | ||||
206 | | ||||
207 | // Update state | ||||
208 | kBounceGameWidget_state = Running; | ||||
209 | | ||||
210 | // Emit signal to apply state | ||||
211 | emit stateChanged(kBounceGameWidget_state); | ||||
129 | } | 212 | } | ||
130 | else if ( m_state == Running && val == true ) | 213 | else if (kBounceGameWidget_state == Running && flag) | ||
131 | { | 214 | { | ||
132 | m_clock->stop(); | 215 | // Stop the timer | ||
133 | m_board->setPaused( true ); | 216 | kBounceGameWidget_clock->stop(); | ||
134 | m_state = Paused; | 217 | | ||
135 | emit stateChanged( m_state ); | 218 | // Pause game board | ||
219 | kBounceGameWidget_board->setPaused(true); | ||||
220 | | ||||
221 | // Update state | ||||
222 | kBounceGameWidget_state = Paused; | ||||
223 | | ||||
224 | // Emit signal to apply state | ||||
225 | emit stateChanged(kBounceGameWidget_state); | ||||
136 | } | 226 | } | ||
137 | 227 | | |||
228 | // Redraw the game board | ||||
138 | redraw(); | 229 | redraw(); | ||
139 | } | 230 | } | ||
140 | 231 | | |||
141 | void KBounceGameWidget::setSuspended( bool val ) | 232 | /** | ||
233 | * Set state to suspend the game | ||||
234 | * @param flag suspend flag | ||||
235 | * @see gamewidget.h | ||||
236 | */ | ||||
237 | void KBounceGameWidget::setSuspended(bool flag) | ||||
142 | { | 238 | { | ||
143 | if ( m_state == Suspended && val == false ) | 239 | if (kBounceGameWidget_state == Suspended && !flag) | ||
144 | { | 240 | { | ||
145 | m_clock->start(); | 241 | // Start the timer | ||
146 | m_board->setPaused( false ); | 242 | kBounceGameWidget_clock->start(); | ||
147 | m_state = Running; | 243 | | ||
148 | emit stateChanged( m_state ); | 244 | // Unpause game board | ||
245 | kBounceGameWidget_board->setPaused(false); | ||||
246 | | ||||
247 | // Update state | ||||
248 | kBounceGameWidget_state = Running; | ||||
249 | | ||||
250 | // Emit signal to apply state | ||||
251 | emit stateChanged(kBounceGameWidget_state); | ||||
149 | } | 252 | } | ||
150 | 253 | | |||
151 | if ( m_state == Running && val == true ) | 254 | if (kBounceGameWidget_state == Running && flag) | ||
152 | { | 255 | { | ||
153 | m_clock->stop(); | 256 | // Stop the timer | ||
154 | m_board->setPaused( true ); | 257 | kBounceGameWidget_clock->stop(); | ||
155 | m_state = Suspended; | 258 | | ||
156 | emit stateChanged( m_state ); | 259 | // Pause game board | ||
260 | kBounceGameWidget_board->setPaused(true); | ||||
261 | | ||||
262 | // Update state | ||||
263 | kBounceGameWidget_state = Suspended; | ||||
264 | | ||||
265 | // Emit signal to apply state | ||||
266 | emit stateChanged(kBounceGameWidget_state); | ||||
157 | } | 267 | } | ||
268 | | ||||
269 | // Redraw the game board | ||||
158 | redraw(); | 270 | redraw(); | ||
159 | } | 271 | } | ||
160 | 272 | | |||
273 | /** | ||||
274 | * Event to apply background settings | ||||
275 | * @see gamewidget.h | ||||
276 | */ | ||||
161 | void KBounceGameWidget::settingsChanged() | 277 | void KBounceGameWidget::settingsChanged() | ||
162 | { | 278 | { | ||
163 | qCDebug(KBOUNCE_LOG) << "Settings changed"; | 279 | qCDebug(KBOUNCE_LOG) << "Settings changed"; | ||
164 | 280 | | |||
165 | if (KBounceSettings::useRandomBackgroundPictures()) | 281 | if (KBounceSettings::useRandomBackgroundPictures()) | ||
166 | { | 282 | kBounceGameWidget_renderer.setCustomBackgroundPath(KBounceSettings::backgroundPicturePath()); | ||
167 | m_renderer.setCustomBackgroundPath(KBounceSettings::backgroundPicturePath()); | | |||
168 | } | | |||
169 | else | 283 | else | ||
170 | { | 284 | kBounceGameWidget_renderer.setCustomBackgroundPath(QString()); | ||
171 | m_renderer.setCustomBackgroundPath(QString()); | 285 | | ||
172 | } | 286 | // Redraw the game board | ||
173 | redraw(); | 287 | redraw(); | ||
174 | } | 288 | } | ||
175 | 289 | | |||
290 | /** | ||||
291 | * Update game difficulty and apply their respective rules | ||||
292 | * @param difficulty new difficulty | ||||
293 | * @see gamewidget.h | ||||
294 | */ | ||||
176 | void KBounceGameWidget::setGameDifficulty( const KgDifficultyLevel * difficulty ) | 295 | void KBounceGameWidget::setGameDifficulty(const KgDifficultyLevel * difficulty) | ||
177 | { | 296 | { | ||
178 | switch ( difficulty->hardness() ) { | 297 | switch (difficulty->hardness()) | ||
298 | { | ||||
299 | | ||||
300 | // Apply configuratons for difficulty "Easy" | ||||
179 | case KgDifficultyLevel::Easy: | 301 | case KgDifficultyLevel::Easy: | ||
180 | m_board->setBallVelocity(0.100); | 302 | // Ball velocity | ||
181 | m_board->setWallVelocity(0.250); | 303 | kBounceGameWidget_board->setBallVelocity(0.100); | ||
304 | | ||||
305 | // Wall velocity | ||||
306 | kBounceGameWidget_board->setWallVelocity(0.250); | ||||
182 | break; | 307 | break; | ||
308 | | ||||
309 | // Apply configuratons for difficulty "Medium" | ||||
183 | case KgDifficultyLevel::Medium: | 310 | case KgDifficultyLevel::Medium: | ||
184 | m_board->setWallVelocity(0.125); | 311 | // Ball velocity | ||
185 | m_board->setBallVelocity(0.125); | 312 | kBounceGameWidget_board->setWallVelocity(0.125); | ||
313 | | ||||
314 | // Wall velocity | ||||
315 | kBounceGameWidget_board->setBallVelocity(0.125); | ||||
186 | break; | 316 | break; | ||
317 | | ||||
318 | // Apply configuratons for difficulty "Hard" | ||||
187 | case KgDifficultyLevel::Hard: | 319 | case KgDifficultyLevel::Hard: | ||
188 | m_board->setWallVelocity(0.100); | 320 | // Ball velocity | ||
189 | m_board->setBallVelocity(0.250); | 321 | kBounceGameWidget_board->setBallVelocity(0.250); | ||
322 | | ||||
323 | // Wall velocity | ||||
324 | kBounceGameWidget_board->setWallVelocity(0.100); | ||||
190 | break; | 325 | break; | ||
191 | } | 326 | } | ||
192 | } | 327 | } | ||
193 | 328 | | |||
329 | /** | ||||
330 | * Event to apply level changes | ||||
331 | * @see gamewidget.h | ||||
332 | */ | ||||
194 | void KBounceGameWidget::levelChanged() | 333 | void KBounceGameWidget::levelChanged() | ||
195 | { | 334 | { | ||
335 | // Set game difficulty | ||||
196 | setGameDifficulty( Kg::difficulty()->currentLevel() ); | 336 | setGameDifficulty(Kg::difficulty()->currentLevel()); | ||
197 | 337 | | |||
198 | if ( m_state == Running || m_state == Paused ) | 338 | // Start new game board | ||
339 | if (kBounceGameWidget_state == Running || kBounceGameWidget_state == Paused) | ||||
199 | newGame(); | 340 | newGame(); | ||
200 | } | 341 | } | ||
201 | 342 | | |||
343 | /** | ||||
344 | * Event to apply onFill changes | ||||
345 | * @param fill current game filled percentage | ||||
346 | * @see gamewidget.h | ||||
347 | */ | ||||
202 | void KBounceGameWidget::onFillChanged( int fill ) | 348 | void KBounceGameWidget::onFillChanged(int fill) | ||
203 | { | 349 | { | ||
350 | // Emit signal to apply filled percentage | ||||
204 | emit filledChanged( fill ); | 351 | emit filledChanged(fill); | ||
205 | if ( fill >= MIN_FILL_PERCENT ) | 352 | if (fill >= MIN_FILL_PERCENT) | ||
206 | { | 353 | { | ||
354 | // Close previous level | ||||
207 | closeLevel(); | 355 | closeLevel(); | ||
208 | m_level++; | | |||
209 | emit levelChanged( m_level ); | | |||
210 | 356 | | |||
211 | m_state = BetweenLevels; | 357 | // Update game level | ||
212 | emit stateChanged( m_state ); | 358 | kBounceGameWidget_level++; | ||
359 | | ||||
360 | // Emit signal to apply game level | ||||
361 | emit levelChanged(kBounceGameWidget_level); | ||||
213 | 362 | | |||
363 | // Update game state | ||||
364 | kBounceGameWidget_state = BetweenLevels; | ||||
365 | | ||||
366 | // Emit signal to apply state | ||||
367 | emit stateChanged(kBounceGameWidget_state); | ||||
368 | | ||||
369 | // Redraw the game board | ||||
214 | redraw(); | 370 | redraw(); | ||
215 | } | 371 | } | ||
216 | } | 372 | } | ||
217 | 373 | | |||
374 | /** | ||||
375 | * Event to apply "die on wall" rule | ||||
376 | * @see gamewidget.h | ||||
377 | */ | ||||
218 | void KBounceGameWidget::onWallDied() | 378 | void KBounceGameWidget::onWallDied() | ||
219 | { | 379 | { | ||
220 | if ( m_lives <= 1 ) | 380 | if (kBounceGameWidget_lives <= 1) | ||
221 | { | 381 | closeGame(); // Close curent game | ||
222 | closeGame(); | | |||
223 | } | | |||
224 | else | 382 | else | ||
225 | { | 383 | { | ||
226 | m_lives--; | 384 | // Update lives | ||
227 | emit livesChanged( m_lives ); | 385 | kBounceGameWidget_lives--; | ||
386 | | ||||
387 | // Emit signal to apply lives | ||||
388 | emit livesChanged(kBounceGameWidget_lives); | ||||
228 | } | 389 | } | ||
229 | } | 390 | } | ||
230 | 391 | | |||
392 | /** | ||||
393 | * Event to apply live changes | ||||
394 | * @param lives current game lives | ||||
395 | * @see gamewidget.h | ||||
396 | */ | ||||
231 | void KBounceGameWidget::onLivesChanged(int lives) | 397 | void KBounceGameWidget::onLivesChanged(int lives) | ||
232 | { | 398 | { | ||
233 | if ( lives < ( m_level + 1 ) | 399 | // Play timeout sound after lives changes | ||
234 | && KBounceSettings::playSounds() ) | 400 | if (lives < (kBounceGameWidget_level + 1) && KBounceSettings::playSounds()) | ||
235 | { | 401 | kBounceGameWidget_soundTimeout.start(); | ||
236 | m_soundTimeout.start(); | | |||
237 | } | 402 | } | ||
238 | } | | |||
239 | | ||||
240 | 403 | | |||
404 | /** | ||||
405 | * Event to apply tick changes | ||||
406 | * @see gamewidget.h | ||||
407 | */ | ||||
241 | void KBounceGameWidget::tick() | 408 | void KBounceGameWidget::tick() | ||
242 | { | 409 | { | ||
410 | // Set initial ticks value | ||||
243 | static int ticks = TICKS_PER_SECOND; | 411 | static int ticks = TICKS_PER_SECOND; | ||
412 | | ||||
413 | // Update ticks | ||||
244 | ticks--; | 414 | ticks--; | ||
415 | | ||||
245 | if ( ticks <= 0 ) | 416 | if (ticks <= 0) | ||
246 | { | 417 | { | ||
247 | emit timeChanged( --m_time ); | 418 | // Emit signal to apply time changes | ||
248 | if ( m_time == 0 ) | 419 | emit timeChanged(--kBounceGameWidget_time); | ||
249 | { | 420 | | ||
250 | closeGame(); | 421 | if (kBounceGameWidget_time == 0) | ||
251 | } | 422 | closeGame(); // Close curent game | ||
423 | | ||||
424 | // Restart ticks value | ||||
252 | ticks = TICKS_PER_SECOND; | 425 | ticks = TICKS_PER_SECOND; | ||
253 | } | 426 | } | ||
254 | } | 427 | } | ||
255 | 428 | | |||
429 | /** | ||||
430 | * XmlGui "resize" event | ||||
431 | * @param *ev Event context | ||||
432 | * @see gamewidget.h | ||||
433 | */ | ||||
256 | void KBounceGameWidget::resizeEvent( QResizeEvent* ev ) | 434 | void KBounceGameWidget::resizeEvent(QResizeEvent* ev) | ||
257 | { | 435 | { | ||
258 | qCDebug(KBOUNCE_LOG) << "Size" << ev->size(); | 436 | qCDebug(KBOUNCE_LOG) << "Size" << ev->size(); | ||
259 | 437 | | |||
260 | m_renderer.setBackgroundSize( ev->size() ); | 438 | // Update background size | ||
439 | kBounceGameWidget_renderer.setBackgroundSize(ev->size()); | ||||
261 | 440 | | |||
441 | // Update central wiget size | ||||
262 | QRectF rect( 0, 0, ev->size().width(), ev->size().height() ); | 442 | QRectF rect(0, 0, ev->size().width(), ev->size().height()); | ||
263 | m_scene.setSceneRect( rect ); | 443 | kBounceGameWidget_scene.setSceneRect(rect); | ||
444 | | ||||
445 | // Update game board size | ||||
446 | QSize boardSize(sceneRect().width() - MIN_MARGIN, sceneRect().height() - MIN_MARGIN); | ||||
447 | kBounceGameWidget_board->resize(boardSize); | ||||
264 | 448 | | |||
265 | QSize boardSize( sceneRect().width() - MIN_MARGIN, | 449 | qreal x = (sceneRect().width() - kBounceGameWidget_board->boundingRect().width()) / 2; | ||
266 | sceneRect().height() - MIN_MARGIN ); | 450 | qreal y = (sceneRect().height() - kBounceGameWidget_board->boundingRect().height()) / 2; | ||
267 | m_board->resize( boardSize ); | 451 | kBounceGameWidget_board->setPos(x, y); | ||
268 | | ||||
269 | qreal x = ( sceneRect().width() - m_board->boundingRect().width() ) / 2; | | |||
270 | qreal y = ( sceneRect().height() - m_board->boundingRect().height() ) / 2; | | |||
271 | m_board->setPos( x, y ); | | |||
272 | 452 | | |||
453 | // Redraw the game board | ||||
273 | redraw(); | 454 | redraw(); | ||
274 | } | 455 | } | ||
275 | 456 | | |||
457 | /** | ||||
458 | * XmlGui "mouse release" event | ||||
459 | * @param *ev Event context | ||||
460 | * @see gamewidget.h | ||||
461 | */ | ||||
276 | void KBounceGameWidget::mouseReleaseEvent( QMouseEvent* event ) | 462 | void KBounceGameWidget::mouseReleaseEvent(QMouseEvent* event) | ||
277 | { | 463 | { | ||
464 | // Release right button | ||||
278 | if ( event->button() & Qt::RightButton ) | 465 | if (event->button() & Qt::RightButton) | ||
279 | { | 466 | { | ||
280 | m_vertical = !m_vertical; | 467 | kBounceGameWidget_vertical = !kBounceGameWidget_vertical; | ||
468 | // Update cursor image | ||||
281 | updateCursor(); | 469 | updateCursor(); | ||
282 | } | 470 | } | ||
283 | 471 | | |||
472 | // Release left button | ||||
284 | if ( event->button() & Qt::LeftButton ) | 473 | if (event->button() & Qt::LeftButton) | ||
285 | { | 474 | { | ||
286 | if ( m_state == Running ) | 475 | switch (kBounceGameWidget_state) | ||
287 | { | | |||
288 | m_board->buildWall( mapToScene( event->pos() ), m_vertical ); | | |||
289 | } | | |||
290 | else if ( m_state == Paused ) | | |||
291 | { | 476 | { | ||
477 | // Build wall if running | ||||
478 | case Running: | ||||
479 | kBounceGameWidget_board->buildWall(mapToScene( event->pos() ), kBounceGameWidget_vertical); | ||||
480 | break; | ||||
481 | | ||||
482 | // Unpause game if paused | ||||
483 | case Paused: | ||||
292 | setPaused( false ); | 484 | setPaused(false); | ||
293 | } | 485 | break; | ||
294 | else if ( m_state == BetweenLevels ) | 486 | | ||
295 | { | 487 | // Create a new level if is between levels | ||
488 | case BetweenLevels: | ||||
296 | newLevel(); | 489 | newLevel(); | ||
297 | } | 490 | break; | ||
298 | else if ( m_state == BeforeFirstGame || m_state == GameOver ) | 491 | | ||
299 | { | 492 | // Create a new game if is before the first game or in a game over | ||
493 | case BeforeFirstGame: | ||||
494 | case GameOver: | ||||
300 | newGame(); | 495 | newGame(); | ||
496 | break; | ||||
301 | } | 497 | } | ||
302 | } | 498 | } | ||
303 | } | 499 | } | ||
304 | 500 | | |||
305 | 501 | /** | |||
502 | * Set variables to close the level | ||||
503 | * @see gamewidget.h | ||||
504 | */ | ||||
306 | void KBounceGameWidget::closeLevel() | 505 | void KBounceGameWidget::closeLevel() | ||
307 | { | 506 | { | ||
308 | m_bonus = 0; | 507 | // Apply bonus score rule | ||
309 | if ( m_board->filled() >= MIN_FILL_PERCENT ) | 508 | kBounceGameWidget_bonus = 0; | ||
310 | { | 509 | if (kBounceGameWidget_board->filled() >= MIN_FILL_PERCENT) | ||
311 | m_bonus = ( m_board->filled() - MIN_FILL_PERCENT ) * 2 * ( m_level + 5 ); | 510 | kBounceGameWidget_bonus = (kBounceGameWidget_board->filled() - MIN_FILL_PERCENT) * 2 * (kBounceGameWidget_level + 5); | ||
312 | } | 511 | | ||
313 | m_score += m_bonus; | 512 | // Add bonus score | ||
314 | m_score += POINTS_FOR_LIFE * m_lives; | 513 | kBounceGameWidget_score += kBounceGameWidget_bonus; | ||
315 | emit scoreChanged( m_score ); | 514 | | ||
515 | // Add life score | ||||
516 | kBounceGameWidget_score += POINTS_FOR_LIFE * kBounceGameWidget_lives; | ||||
316 | 517 | | |||
317 | m_clock->stop(); | 518 | // Emit signal to apply score | ||
318 | m_board->setPaused( true ); | 519 | emit scoreChanged(kBounceGameWidget_score); | ||
520 | | ||||
521 | // Stop timer | ||||
522 | kBounceGameWidget_clock->stop(); | ||||
523 | | ||||
524 | // Pause the game | ||||
525 | kBounceGameWidget_board->setPaused(true); | ||||
319 | } | 526 | } | ||
320 | 527 | | |||
528 | /** | ||||
529 | * Start a new level | ||||
530 | * @see gamewidget.h | ||||
531 | */ | ||||
321 | void KBounceGameWidget::newLevel() | 532 | void KBounceGameWidget::newLevel() | ||
322 | { | 533 | { | ||
323 | m_state = Running; | 534 | // Update game state | ||
324 | emit stateChanged( m_state ); | 535 | kBounceGameWidget_state = Running; | ||
536 | | ||||
537 | // Emit signal to apply state | ||||
538 | emit stateChanged(kBounceGameWidget_state); | ||||
539 | | ||||
540 | // Start the timer | ||||
541 | kBounceGameWidget_clock->start(); | ||||
325 | 542 | | |||
326 | m_clock->start(); | 543 | // Set initial level | ||
327 | m_board->newLevel( m_level ); | 544 | kBounceGameWidget_board->newLevel(kBounceGameWidget_level); | ||
328 | m_board->setPaused( false ); | | |||
329 | | ||||
330 | m_bonus = 0; | | |||
331 | m_lives = m_level + 1; | | |||
332 | m_time = 30 * ( m_level + 2 ); | | |||
333 | emit livesChanged( m_lives ); | | |||
334 | emit timeChanged( m_time ); | | |||
335 | 545 | | |||
546 | // Unpause the game | ||||
547 | kBounceGameWidget_board->setPaused(false); | ||||
548 | | ||||
549 | // Update game variables (bonus, lives and time) | ||||
550 | kBounceGameWidget_bonus = 0; | ||||
551 | kBounceGameWidget_lives = kBounceGameWidget_level + 1; | ||||
552 | kBounceGameWidget_time = 30 * (kBounceGameWidget_level + 2); | ||||
553 | | ||||
554 | // Emit signals to apply game variables (lives and time) | ||||
555 | emit livesChanged(kBounceGameWidget_lives); | ||||
556 | emit timeChanged(kBounceGameWidget_time); | ||||
557 | | ||||
558 | // Load a random background | ||||
336 | if (KBounceSettings::useRandomBackgroundPictures()) | 559 | if (KBounceSettings::useRandomBackgroundPictures()) | ||
337 | m_renderer.loadNewBackgroundPixmap(); | 560 | kBounceGameWidget_renderer.loadNewBackgroundPixmap(); | ||
338 | 561 | | |||
562 | // Redraw the game board | ||||
339 | redraw(); | 563 | redraw(); | ||
340 | } | 564 | } | ||
341 | 565 | | |||
342 | 566 | /** | |||
567 | * Set variables to redraw the game board | ||||
568 | * @see gamewidget.h | ||||
569 | */ | ||||
343 | void KBounceGameWidget::redraw() | 570 | void KBounceGameWidget::redraw() | ||
344 | { | 571 | { | ||
345 | if ( size().isEmpty() ) | 572 | if (size().isEmpty()) | ||
346 | return; | 573 | return; | ||
347 | 574 | | |||
348 | switch ( m_state ) | 575 | switch (kBounceGameWidget_state) | ||
349 | { | 576 | { | ||
577 | // Actions to redraw before first game | ||||
350 | case BeforeFirstGame: | 578 | case BeforeFirstGame: | ||
351 | m_board->hide(); | 579 | // Hide game board | ||
580 | kBounceGameWidget_board->hide(); | ||||
581 | | ||||
582 | // Generate and show message overlay | ||||
352 | generateOverlay(); | 583 | generateOverlay(); | ||
353 | m_overlay->show(); | 584 | kBounceGameWidget_overlay->show(); | ||
354 | break; | 585 | break; | ||
586 | | ||||
587 | // Actions to redraw while running | ||||
355 | case Running: | 588 | case Running: | ||
356 | m_board->show(); | 589 | // Show game board | ||
357 | m_overlay->hide(); | 590 | kBounceGameWidget_board->show(); | ||
591 | | ||||
592 | // Hide message overlay | ||||
593 | kBounceGameWidget_overlay->hide(); | ||||
358 | break; | 594 | break; | ||
595 | | ||||
596 | // Default redraw actions | ||||
359 | default: | 597 | default: | ||
360 | m_board->show(); | 598 | // Show game board | ||
599 | kBounceGameWidget_board->show(); | ||||
600 | | ||||
601 | // Generate and show message overlay | ||||
361 | generateOverlay(); | 602 | generateOverlay(); | ||
362 | m_overlay->show(); | 603 | kBounceGameWidget_overlay->show(); | ||
363 | break; | 604 | break; | ||
364 | } | 605 | } | ||
365 | 606 | | |||
607 | // Update cursor image | ||||
366 | updateCursor(); | 608 | updateCursor(); | ||
609 | | ||||
610 | // Load wall sprites | ||||
367 | KBounceWall::loadSprites(); | 611 | KBounceWall::loadSprites(); | ||
368 | m_scene.setBackgroundBrush( m_board->applyWallsOn(m_renderer.renderBackground()) ); | 612 | | ||
613 | // Set initial background | ||||
614 | kBounceGameWidget_scene.setBackgroundBrush( kBounceGameWidget_board->applyWallsOn(kBounceGameWidget_renderer.renderBackground()) ); | ||||
615 | | ||||
369 | update(); | 616 | update(); | ||
370 | } | 617 | } | ||
371 | 618 | | |||
619 | /** | ||||
620 | * Generate overlay message box | ||||
621 | * @see gamewidget.h | ||||
622 | */ | ||||
372 | void KBounceGameWidget::generateOverlay() | 623 | void KBounceGameWidget::generateOverlay() | ||
373 | { | 624 | { | ||
374 | if ( size().isEmpty() ) | 625 | if (size().isEmpty()) | ||
375 | return; | 626 | return; | ||
376 | 627 | | |||
628 | // Set width and height | ||||
377 | int itemWidth = qRound( 0.8 * size().width() ); | 629 | int itemWidth = qRound(0.8 * size().width()); | ||
378 | int itemHeight = qRound( 0.6 * size().height() ); | 630 | int itemHeight = qRound(0.6 * size().height()); | ||
379 | 631 | | |||
632 | // Create background canvas | ||||
380 | QSize backgroundSize( itemWidth,itemHeight ); | 633 | QSize backgroundSize(itemWidth, itemHeight); | ||
381 | 634 | | |||
635 | // Create bitmap from background canvas | ||||
382 | QPixmap px( backgroundSize ); | 636 | QPixmap px(backgroundSize); | ||
383 | px.fill( Qt::transparent ); | 637 | px.fill(Qt::transparent); | ||
384 | 638 | | |||
639 | // Set properties to overlay | ||||
385 | QPainter p( &px ); | 640 | QPainter p(&px); | ||
386 | | ||||
387 | p.setPen( Qt::transparent ); | 641 | p.setPen(Qt::transparent); | ||
388 | p.setRenderHint(QPainter::Antialiasing ); | 642 | p.setRenderHint(QPainter::Antialiasing); | ||
389 | 643 | | |||
390 | if ( m_renderer.spriteExists(QStringLiteral("overlayBackground")) ) | 644 | // Render background canvas image | ||
645 | if ( kBounceGameWidget_renderer.spriteExists(QStringLiteral("overlayBackground")) ) | ||||
391 | { | 646 | { | ||
392 | QPixmap themeBackgound = m_renderer.spritePixmap(QStringLiteral("overlayBackground"),backgroundSize); | 647 | // Render by file | ||
648 | QPixmap themeBackgound = kBounceGameWidget_renderer.spritePixmap(QStringLiteral("overlayBackground"),backgroundSize); | ||||
393 | p.setCompositionMode( QPainter::CompositionMode_Source ); | 649 | p.setCompositionMode(QPainter::CompositionMode_Source); | ||
394 | p.drawPixmap( p.viewport(), themeBackgound ); | 650 | p.drawPixmap(p.viewport(), themeBackgound); | ||
395 | p.setCompositionMode( QPainter::CompositionMode_DestinationIn ); | 651 | p.setCompositionMode(QPainter::CompositionMode_DestinationIn); | ||
396 | p.fillRect(px.rect(), QColor( 0, 0, 0, 160 )); | 652 | p.fillRect(px.rect(), QColor( 0, 0, 0, 160 )); | ||
397 | p.setCompositionMode( QPainter::CompositionMode_SourceOver ); | 653 | p.setCompositionMode(QPainter::CompositionMode_SourceOver); | ||
398 | } | 654 | } | ||
399 | else | 655 | else | ||
400 | { | 656 | { | ||
657 | // Render by pure color | ||||
401 | p.setBrush( QBrush( QColor( 188, 202, 222, 155 ) ) ); | 658 | p.setBrush(QBrush( QColor(188, 202, 222, 155) )); | ||
659 | | ||||
660 | // PS.: WARNING deprecated method (use drawRoundedRect) | ||||
402 | p.drawRoundRect( 0, 0, itemWidth, itemHeight, 25 ); | 661 | p.drawRoundRect(0, 0, itemWidth, itemHeight, 25); | ||
403 | } | 662 | } | ||
404 | 663 | | |||
664 | // Initialize overlay text | ||||
405 | QString text; | 665 | QString text; | ||
406 | switch( m_state ) | 666 | | ||
667 | switch(kBounceGameWidget_state) | ||||
407 | { | 668 | { | ||
669 | // Set text on "before first game" state | ||||
408 | case BeforeFirstGame: | 670 | case BeforeFirstGame: | ||
409 | text = i18n( "Welcome to KBounce.\n Click to start a game" ); | 671 | text = i18n( "Welcome to KBounce.\n Click to start a game" ); | ||
410 | break; | 672 | break; | ||
673 | | ||||
674 | // Set text on "paused" state | ||||
411 | case Paused: | 675 | case Paused: | ||
412 | text = i18n( "Paused\n Click to resume" ); | 676 | text = i18n( "Paused\n Click to resume" ); | ||
413 | break; | 677 | break; | ||
678 | | ||||
679 | // Set text on "between levels" state | ||||
414 | case BetweenLevels: | 680 | case BetweenLevels: | ||
415 | text = i18n( "You have successfully cleared more than %1% of the board\n", MIN_FILL_PERCENT ) + | 681 | text = i18n( "You have successfully cleared more than %1% of the board\n", MIN_FILL_PERCENT ) + | ||
416 | i18n( "%1 points: %2 points per remaining life\n", m_lives * POINTS_FOR_LIFE, POINTS_FOR_LIFE ) + | 682 | i18n( "%1 points: %2 points per remaining life\n", kBounceGameWidget_lives * POINTS_FOR_LIFE, POINTS_FOR_LIFE ) + | ||
417 | i18n( "%1 points: Bonus\n", m_bonus ) + | 683 | i18n( "%1 points: Bonus\n", kBounceGameWidget_bonus ) + | ||
418 | i18n( "%1 points: Total score for this level\n", m_bonus + m_lives * POINTS_FOR_LIFE ) + | 684 | i18n( "%1 points: Total score for this level\n", kBounceGameWidget_bonus + kBounceGameWidget_lives * POINTS_FOR_LIFE ) + | ||
419 | i18n( "On to level %1. Remember you get %2 lives this time!", m_level, m_level + 1 ); | 685 | i18n( "On to level %1. Remember you get %2 lives this time!", kBounceGameWidget_level, kBounceGameWidget_level + 1 ); | ||
420 | break; | 686 | break; | ||
687 | | ||||
688 | // Set text on "game over" state | ||||
421 | case GameOver: | 689 | case GameOver: | ||
422 | text = i18n( "Game over.\n Click to start a game" ); | 690 | text = i18n( "Game over.\n Click to start a game" ); | ||
423 | break; | 691 | break; | ||
692 | | ||||
693 | // Set text on another state | ||||
424 | default: | 694 | default: | ||
425 | text = QString(); | 695 | text = QString(); | ||
426 | } | 696 | } | ||
427 | 697 | | |||
698 | // Set text font properties | ||||
428 | QFont font; | 699 | QFont font; | ||
429 | font.setPointSize( 28 ); | 700 | font.setPointSize(28); | ||
430 | p.setFont( font ); | 701 | p.setFont(font); | ||
431 | int textWidth = p.boundingRect( p.viewport(), Qt::AlignCenter | Qt::AlignVCenter, text ).width(); | 702 | int textWidth = p.boundingRect(p.viewport(), Qt::AlignCenter | Qt::AlignVCenter, text).width(); | ||
432 | int fontSize = 28; | 703 | int fontSize = 28; | ||
704 | | ||||
705 | // Adjust font size based on message size | ||||
433 | while ( ( textWidth > itemWidth * 0.95 ) && fontSize > 1 ) | 706 | while ( (textWidth > itemWidth * 0.95) && fontSize > 1) | ||
434 | { | 707 | { | ||
435 | fontSize--; | 708 | fontSize--; | ||
436 | font.setPointSize( fontSize ); | 709 | font.setPointSize(fontSize); | ||
437 | p.setFont( font ); | 710 | p.setFont(font); | ||
438 | textWidth = p.boundingRect( p.viewport(), Qt::AlignCenter | Qt::AlignVCenter, text ).width(); | 711 | textWidth = p.boundingRect(p.viewport(), Qt::AlignCenter | Qt::AlignVCenter, text).width(); | ||
439 | } | 712 | } | ||
713 | | ||||
714 | // Set text color scheme | ||||
440 | KColorScheme kcs = KColorScheme( QPalette::Normal, KColorScheme::Window ); | 715 | KColorScheme kcs = KColorScheme(QPalette::Normal, KColorScheme::Window); | ||
441 | p.setPen( kcs.foreground(KColorScheme::NormalText).color()); | 716 | p.setPen(kcs.foreground(KColorScheme::NormalText).color()); | ||
442 | p.drawText( p.viewport(), Qt::AlignCenter | Qt::AlignVCenter, text ); | 717 | p.drawText(p.viewport(), Qt::AlignCenter | Qt::AlignVCenter, text); | ||
443 | p.end(); | 718 | p.end(); | ||
444 | 719 | | |||
445 | m_overlay->setPixmap( px ); | 720 | // Apply overlay properties | ||
446 | 721 | kBounceGameWidget_overlay->setPixmap(px); | |||
447 | QPointF pos( ( sceneRect().width() - itemWidth) / 2, | | |||
448 | ( sceneRect().height() - itemHeight) / 2 ); | | |||
449 | m_overlay->setPos( pos ); | | |||
450 | } | | |||
451 | 722 | | |||
723 | // Get overlay position | ||||
724 | QPointF pos( | ||||
725 | (sceneRect().width() - itemWidth) / 2, | ||||
726 | (sceneRect().height() - itemHeight) / 2 | ||||
727 | ); | ||||
728 | | ||||
729 | // Apply overlay position | ||||
730 | kBounceGameWidget_overlay->setPos(pos); | ||||
731 | } | ||||
732 | | ||||
733 | /** | ||||
734 | * XmlGui "focus out" event | ||||
735 | * @param *ev Event context | ||||
736 | * @see gamewidget.h | ||||
737 | */ | ||||
452 | void KBounceGameWidget::focusOutEvent(QFocusEvent *event) | 738 | void KBounceGameWidget::focusOutEvent(QFocusEvent *event) | ||
453 | { | 739 | { | ||
740 | // Pause game if not on focus | ||||
454 | if (event->reason() == Qt::ActiveWindowFocusReason) | 741 | if (event->reason() == Qt::ActiveWindowFocusReason) | ||
455 | { | | |||
456 | setPaused( true ); | 742 | setPaused(true); | ||
457 | } | 743 | } | ||
458 | } | | |||
459 | 744 | | |||
745 | /** | ||||
746 | * Update cursor image | ||||
747 | * @see gamewidget.h | ||||
748 | */ | ||||
460 | void KBounceGameWidget::updateCursor() | 749 | void KBounceGameWidget::updateCursor() | ||
461 | { | 750 | { | ||
462 | if ( m_state == Running ) | 751 | if (kBounceGameWidget_state == Running) | ||
463 | setCursor( m_vertical ? Qt::SizeVerCursor : Qt::SizeHorCursor ); | 752 | setCursor(kBounceGameWidget_vertical ? Qt::SizeVerCursor : Qt::SizeHorCursor); | ||
464 | else | 753 | else | ||
465 | unsetCursor(); | 754 | unsetCursor(); | ||
466 | } | 755 | } | ||
467 | | ||||
468 | | ||||
469 | | ||||
756 | No newline at end of file |
You kept the spaces inside the braces here. On purpose?