|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
4 ** All rights reserved. |
|
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
|
6 ** |
|
7 ** This file is part of the QtCore module of the Qt Toolkit. |
|
8 ** |
|
9 ** $QT_BEGIN_LICENSE:LGPL$ |
|
10 ** No Commercial Usage |
|
11 ** This file contains pre-release code and may not be distributed. |
|
12 ** You may use this file in accordance with the terms and conditions |
|
13 ** contained in the Technology Preview License Agreement accompanying |
|
14 ** this package. |
|
15 ** |
|
16 ** GNU Lesser General Public License Usage |
|
17 ** Alternatively, this file may be used under the terms of the GNU Lesser |
|
18 ** General Public License version 2.1 as published by the Free Software |
|
19 ** Foundation and appearing in the file LICENSE.LGPL included in the |
|
20 ** packaging of this file. Please review the following information to |
|
21 ** ensure the GNU Lesser General Public License version 2.1 requirements |
|
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
23 ** |
|
24 ** In addition, as a special exception, Nokia gives you certain additional |
|
25 ** rights. These rights are described in the Nokia Qt LGPL Exception |
|
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
27 ** |
|
28 ** If you have questions regarding the use of this file, please contact |
|
29 ** Nokia at qt-info@nokia.com. |
|
30 ** |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
38 ** $QT_END_LICENSE$ |
|
39 ** |
|
40 ****************************************************************************/ |
|
41 |
|
42 //Own |
|
43 #include "states.h" |
|
44 #include "graphicsscene.h" |
|
45 #include "boat.h" |
|
46 #include "submarine.h" |
|
47 #include "torpedo.h" |
|
48 #include "animationmanager.h" |
|
49 #include "progressitem.h" |
|
50 #include "textinformationitem.h" |
|
51 |
|
52 //Qt |
|
53 #include <QtGui/QMessageBox> |
|
54 #include <QtGui/QGraphicsView> |
|
55 #include <QtCore/QStateMachine> |
|
56 #include <QtGui/QKeyEventTransition> |
|
57 #include <QtCore/QFinalState> |
|
58 |
|
59 PlayState::PlayState(GraphicsScene *scene, QState *parent) |
|
60 : QState(parent), |
|
61 scene(scene), |
|
62 machine(0), |
|
63 currentLevel(0), |
|
64 score(0) |
|
65 { |
|
66 } |
|
67 |
|
68 PlayState::~PlayState() |
|
69 { |
|
70 delete machine; |
|
71 } |
|
72 |
|
73 void PlayState::onEntry(QEvent *) |
|
74 { |
|
75 //We are now playing? |
|
76 if (machine) { |
|
77 machine->stop(); |
|
78 //we hide the information |
|
79 scene->textInformationItem->hide(); |
|
80 scene->clearScene(); |
|
81 currentLevel = 0; |
|
82 score = 0; |
|
83 delete machine; |
|
84 } |
|
85 |
|
86 machine = new QStateMachine; |
|
87 |
|
88 //This state is when player is playing |
|
89 LevelState *levelState = new LevelState(scene, this, machine); |
|
90 |
|
91 //This state is when the player is actually playing but the game is not paused |
|
92 QState *playingState = new QState(levelState); |
|
93 levelState->setInitialState(playingState); |
|
94 |
|
95 //This state is when the game is paused |
|
96 PauseState *pauseState = new PauseState(scene, levelState); |
|
97 |
|
98 //We have one view, it receive the key press event |
|
99 QKeyEventTransition *pressPplay = new QKeyEventTransition(scene->views().at(0), QEvent::KeyPress, Qt::Key_P); |
|
100 pressPplay->setTargetState(pauseState); |
|
101 QKeyEventTransition *pressPpause = new QKeyEventTransition(scene->views().at(0), QEvent::KeyPress, Qt::Key_P); |
|
102 pressPpause->setTargetState(playingState); |
|
103 |
|
104 //Pause "P" is triggered, the player pause the game |
|
105 playingState->addTransition(pressPplay); |
|
106 |
|
107 //To get back playing when the game has been paused |
|
108 pauseState->addTransition(pressPpause); |
|
109 |
|
110 //This state is when player have lost |
|
111 LostState *lostState = new LostState(scene, this, machine); |
|
112 |
|
113 //This state is when player have won |
|
114 WinState *winState = new WinState(scene, this, machine); |
|
115 |
|
116 //The boat has been destroyed then the game is finished |
|
117 levelState->addTransition(scene->boat, SIGNAL(boatExecutionFinished()),lostState); |
|
118 |
|
119 //This transition check if we won or not |
|
120 WinTransition *winTransition = new WinTransition(scene, this, winState); |
|
121 |
|
122 //The boat has been destroyed then the game is finished |
|
123 levelState->addTransition(winTransition); |
|
124 |
|
125 //This state is an animation when the score changed |
|
126 UpdateScoreState *scoreState = new UpdateScoreState(this, levelState); |
|
127 |
|
128 //This transition update the score when a submarine die |
|
129 UpdateScoreTransition *scoreTransition = new UpdateScoreTransition(scene, this, levelState); |
|
130 scoreTransition->setTargetState(scoreState); |
|
131 |
|
132 //The boat has been destroyed then the game is finished |
|
133 playingState->addTransition(scoreTransition); |
|
134 |
|
135 //We go back to play state |
|
136 scoreState->addTransition(playingState); |
|
137 |
|
138 //We start playing!!! |
|
139 machine->setInitialState(levelState); |
|
140 |
|
141 //Final state |
|
142 QFinalState *final = new QFinalState(machine); |
|
143 |
|
144 //This transition is triggered when the player press space after completing a level |
|
145 CustomSpaceTransition *spaceTransition = new CustomSpaceTransition(scene->views().at(0), this, QEvent::KeyPress, Qt::Key_Space); |
|
146 spaceTransition->setTargetState(levelState); |
|
147 winState->addTransition(spaceTransition); |
|
148 |
|
149 //We lost we should reach the final state |
|
150 lostState->addTransition(lostState, SIGNAL(finished()), final); |
|
151 |
|
152 machine->start(); |
|
153 } |
|
154 |
|
155 LevelState::LevelState(GraphicsScene *scene, PlayState *game, QState *parent) : QState(parent), scene(scene), game(game) |
|
156 { |
|
157 } |
|
158 void LevelState::onEntry(QEvent *) |
|
159 { |
|
160 initializeLevel(); |
|
161 } |
|
162 |
|
163 void LevelState::initializeLevel() |
|
164 { |
|
165 //we re-init the boat |
|
166 scene->boat->setPos(scene->width()/2, scene->sealLevel() - scene->boat->size().height()); |
|
167 scene->boat->setCurrentSpeed(0); |
|
168 scene->boat->setCurrentDirection(Boat::None); |
|
169 scene->boat->setBombsLaunched(0); |
|
170 scene->boat->show(); |
|
171 scene->setFocusItem(scene->boat, Qt::OtherFocusReason); |
|
172 scene->boat->run(); |
|
173 |
|
174 scene->progressItem->setScore(game->score); |
|
175 scene->progressItem->setLevel(game->currentLevel + 1); |
|
176 |
|
177 GraphicsScene::LevelDescription currentLevelDescription = scene->levelsData.value(game->currentLevel); |
|
178 |
|
179 for (int i = 0; i < currentLevelDescription.submarines.size(); ++i ) { |
|
180 |
|
181 QPair<int,int> subContent = currentLevelDescription.submarines.at(i); |
|
182 GraphicsScene::SubmarineDescription submarineDesc = scene->submarinesData.at(subContent.first); |
|
183 |
|
184 for (int j = 0; j < subContent.second; ++j ) { |
|
185 SubMarine *sub = new SubMarine(submarineDesc.type, submarineDesc.name, submarineDesc.points); |
|
186 scene->addItem(sub); |
|
187 int random = (qrand() % 15 + 1); |
|
188 qreal x = random == 13 || random == 5 ? 0 : scene->width() - sub->size().width(); |
|
189 qreal y = scene->height() -(qrand() % 150 + 1) - sub->size().height(); |
|
190 sub->setPos(x,y); |
|
191 sub->setCurrentDirection(x == 0 ? SubMarine::Right : SubMarine::Left); |
|
192 sub->setCurrentSpeed(qrand() % 3 + 1); |
|
193 } |
|
194 } |
|
195 } |
|
196 |
|
197 /** Pause State */ |
|
198 PauseState::PauseState(GraphicsScene *scene, QState *parent) : QState(parent),scene(scene) |
|
199 { |
|
200 } |
|
201 void PauseState::onEntry(QEvent *) |
|
202 { |
|
203 AnimationManager::self()->pauseAll(); |
|
204 scene->boat->setEnabled(false); |
|
205 } |
|
206 void PauseState::onExit(QEvent *) |
|
207 { |
|
208 AnimationManager::self()->resumeAll(); |
|
209 scene->boat->setEnabled(true); |
|
210 scene->boat->setFocus(); |
|
211 } |
|
212 |
|
213 /** Lost State */ |
|
214 LostState::LostState(GraphicsScene *scene, PlayState *game, QState *parent) : QState(parent), scene(scene), game(game) |
|
215 { |
|
216 } |
|
217 |
|
218 void LostState::onEntry(QEvent *) |
|
219 { |
|
220 //The message to display |
|
221 QString message = QString("You lose on level %1. Your score is %2.").arg(game->currentLevel+1).arg(game->score); |
|
222 |
|
223 //We set the level back to 0 |
|
224 game->currentLevel = 0; |
|
225 |
|
226 //We set the score back to 0 |
|
227 game->score = 0; |
|
228 |
|
229 //We clear the scene |
|
230 scene->clearScene(); |
|
231 |
|
232 //We inform the player |
|
233 scene->textInformationItem->setMessage(message); |
|
234 scene->textInformationItem->show(); |
|
235 } |
|
236 |
|
237 void LostState::onExit(QEvent *) |
|
238 { |
|
239 //we hide the information |
|
240 scene->textInformationItem->hide(); |
|
241 } |
|
242 |
|
243 /** Win State */ |
|
244 WinState::WinState(GraphicsScene *scene, PlayState *game, QState *parent) : QState(parent), scene(scene), game(game) |
|
245 { |
|
246 } |
|
247 |
|
248 void WinState::onEntry(QEvent *) |
|
249 { |
|
250 //We clear the scene |
|
251 scene->clearScene(); |
|
252 |
|
253 QString message; |
|
254 if (scene->levelsData.size() - 1 != game->currentLevel) { |
|
255 message = QString("You win the level %1. Your score is %2.\nPress Space to continue.").arg(game->currentLevel+1).arg(game->score); |
|
256 //We increment the level number |
|
257 game->currentLevel++; |
|
258 } else { |
|
259 message = QString("You finish the game on level %1. Your score is %2.").arg(game->currentLevel+1).arg(game->score); |
|
260 //We set the level back to 0 |
|
261 game->currentLevel = 0; |
|
262 //We set the score back to 0 |
|
263 game->score = 0; |
|
264 } |
|
265 |
|
266 //We inform the player |
|
267 scene->textInformationItem->setMessage(message); |
|
268 scene->textInformationItem->show(); |
|
269 } |
|
270 |
|
271 void WinState::onExit(QEvent *) |
|
272 { |
|
273 //we hide the information |
|
274 scene->textInformationItem->hide(); |
|
275 } |
|
276 |
|
277 /** UpdateScore State */ |
|
278 UpdateScoreState::UpdateScoreState(PlayState *g, QState *parent) : QState(parent), game(g) |
|
279 { |
|
280 } |
|
281 |
|
282 /** Win transition */ |
|
283 UpdateScoreTransition::UpdateScoreTransition(GraphicsScene *scene, PlayState *game, QAbstractState *target) |
|
284 : QSignalTransition(scene,SIGNAL(subMarineDestroyed(int))), |
|
285 game(game), scene(scene) |
|
286 { |
|
287 setTargetState(target); |
|
288 } |
|
289 |
|
290 bool UpdateScoreTransition::eventTest(QEvent *event) |
|
291 { |
|
292 if (!QSignalTransition::eventTest(event)) |
|
293 return false; |
|
294 QStateMachine::SignalEvent *se = static_cast<QStateMachine::SignalEvent*>(event); |
|
295 game->score += se->arguments().at(0).toInt(); |
|
296 scene->progressItem->setScore(game->score); |
|
297 return true; |
|
298 } |
|
299 |
|
300 /** Win transition */ |
|
301 WinTransition::WinTransition(GraphicsScene *scene, PlayState *game, QAbstractState *target) |
|
302 : QSignalTransition(scene,SIGNAL(allSubMarineDestroyed(int))), |
|
303 game(game), scene(scene) |
|
304 { |
|
305 setTargetState(target); |
|
306 } |
|
307 |
|
308 bool WinTransition::eventTest(QEvent *event) |
|
309 { |
|
310 if (!QSignalTransition::eventTest(event)) |
|
311 return false; |
|
312 QStateMachine::SignalEvent *se = static_cast<QStateMachine::SignalEvent*>(event); |
|
313 game->score += se->arguments().at(0).toInt(); |
|
314 scene->progressItem->setScore(game->score); |
|
315 return true; |
|
316 } |
|
317 |
|
318 /** Space transition */ |
|
319 CustomSpaceTransition::CustomSpaceTransition(QWidget *widget, PlayState *game, QEvent::Type type, int key) |
|
320 : QKeyEventTransition(widget, type, key), |
|
321 game(game) |
|
322 { |
|
323 } |
|
324 |
|
325 bool CustomSpaceTransition::eventTest(QEvent *event) |
|
326 { |
|
327 if (!QKeyEventTransition::eventTest(event)) |
|
328 return false; |
|
329 return (game->currentLevel != 0); |
|
330 } |