1 | /* |
2 | * Copyright 2007-2008 Thomas Gallinari <tg8187@yahoo.fr> |
3 | * Copyright 2007-2008 Pierre-Benoit Bessse <besse@gmail.com> |
4 | * |
5 | * This program is free software; you can redistribute it and/or |
6 | * modify it under the terms of the GNU General Public License as |
7 | * published by the Free Software Foundation; either version 2 of |
8 | * the License, or (at your option) any later version. |
9 | * |
10 | * This program is distributed in the hope that it will be useful, |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | * GNU General Public License for more details. |
14 | * |
15 | * You should have received a copy of the GNU General Public License |
16 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
17 | */ |
18 | |
19 | #include "kapmanmainwindow.h" |
20 | #include "gamescene.h" |
21 | #include "settings.h" |
22 | |
23 | #include <QPointer> |
24 | #include <KActionCollection> |
25 | #include <KStandardGameAction> |
26 | #include <KToggleAction> |
27 | #include <KMessageBox> |
28 | #include <KConfigDialog> |
29 | #include <KInputDialog> |
30 | #include <KLocale> |
31 | #include <KStatusBar> |
32 | #include <KgDifficulty> |
33 | #include <KScoreDialog> |
34 | |
35 | #define USE_UNSTABLE_LIBKDEGAMESPRIVATE_API |
36 | #include <libkdegamesprivate/kgamethemeselector.h> |
37 | |
38 | KapmanMainWindow::KapmanMainWindow() { |
39 | // Initialize the game |
40 | m_game = NULL; |
41 | m_view = NULL; |
42 | // Set the window menus |
43 | KStandardGameAction::gameNew(this, SLOT(newGame(bool)), actionCollection()); |
44 | KStandardGameAction::highscores(this, SLOT(showHighscores()), actionCollection()); |
45 | KStandardAction::preferences(this, SLOT(showSettings()), actionCollection()); |
46 | KStandardGameAction::quit(this, SLOT(close()), actionCollection()); |
47 | KAction* soundAction = new KToggleAction(i18n("&Play sounds" ), this); |
48 | soundAction->setChecked(Settings::sounds()); |
49 | actionCollection()->addAction( QLatin1String( "sounds" ), soundAction); |
50 | connect(soundAction, SIGNAL(triggered(bool)), this, SLOT(setSoundsEnabled(bool))); |
51 | KAction* levelAction = new KAction(i18n("&Change level" ), this); |
52 | actionCollection()->addAction( QLatin1String( "level" ), levelAction); |
53 | connect(levelAction, SIGNAL(triggered(bool)), this, SLOT(changeLevel())); |
54 | // Add a statusbar to show level,score,lives information |
55 | m_statusBar = statusBar(); |
56 | m_statusBar->insertItem(i18nc("Used to display the current level of play to the user" , "Level: %1" , 1), 1, 1); |
57 | m_statusBar->insertItem(i18nc("Used to inform the user of their current score" , "Score: %1" , 0), 2, 1); |
58 | m_statusBar->insertItem(i18nc("Used to tell the user how many lives they have left" , "Lives: %1" , initLives), 4, 1); |
59 | |
60 | |
61 | // Initialize the KgDifficulty singleton |
62 | Kg::difficulty()->addStandardLevelRange( |
63 | KgDifficultyLevel::Easy, KgDifficultyLevel::Hard, //range |
64 | KgDifficultyLevel::Medium //default |
65 | ); |
66 | KgDifficultyGUI::init(this); |
67 | connect(Kg::difficulty(), SIGNAL(currentLevelChanged(const KgDifficultyLevel*)), SLOT(initGame())); |
68 | // Setup the window |
69 | setupGUI(); |
70 | |
71 | initGame(); |
72 | } |
73 | |
74 | KapmanMainWindow::~KapmanMainWindow() { |
75 | delete m_statusBar; |
76 | delete m_game; |
77 | delete m_view; |
78 | } |
79 | |
80 | void KapmanMainWindow::initGame() { |
81 | // Create a new Game instance |
82 | delete m_game; |
83 | m_game = new Game(); |
84 | connect(m_game, SIGNAL(gameOver(bool)), this, SLOT(newGame(bool))); // TODO Remove the useless bool parameter from gameOver() |
85 | connect(m_game, SIGNAL(levelChanged(uint)), this, SLOT(displayLevel(uint))); |
86 | connect(m_game, SIGNAL(scoreChanged(uint)), this, SLOT(displayScore(uint))); |
87 | connect(m_game, SIGNAL(livesChanged(uint)), this, SLOT(displayLives(uint))); |
88 | |
89 | |
90 | // Create a new GameView instance |
91 | delete m_view; |
92 | m_view = new GameView(m_game); |
93 | m_view->setBackgroundBrush(Qt::black); |
94 | setCentralWidget(m_view); |
95 | m_view->setFocus(); |
96 | // For some reason, calling setFocus() immediately won't work after the |
97 | // score dialog has been shown, so do it again after an eventloop run. |
98 | QTimer::singleShot(0, m_view, SLOT(setFocus())); |
99 | resetStatusBar(); |
100 | } |
101 | |
102 | |
103 | void KapmanMainWindow::newGame(const bool gameOver) { |
104 | bool gameRunning; // True if the game is running (game timer is active), false otherwise |
105 | |
106 | gameRunning = m_game->getTimer()->isActive(); |
107 | // If the game is running |
108 | if (gameRunning) { |
109 | // Pause the game |
110 | m_game->pause(); |
111 | } |
112 | // If the game was not over |
113 | if (!gameOver){ |
114 | // Confirm before starting a new game |
115 | if (KMessageBox::warningYesNo(this, i18n("Are you sure you want to quit the current game?" ), i18n("New game" )) == KMessageBox::Yes) { |
116 | // Start a new game |
117 | initGame(); |
118 | } |
119 | else { |
120 | // If the game was running |
121 | if (gameRunning) { |
122 | // Resume the game |
123 | m_game->start(); |
124 | } |
125 | } |
126 | } |
127 | else { |
128 | // Display the score information |
129 | KMessageBox::information(this, i18np("Your score is %1 point." , "Your score is %1 points." , m_game->getScore()), i18n("Game Over" )); |
130 | // manage Highscores only if player did not cheat |
131 | if (m_game->isCheater()) { |
132 | KMessageBox::information(this, i18n("You cheated, no Highscore for you ;)" ), i18n("Cheater!" )); |
133 | } |
134 | else { |
135 | // Add the score to the highscores table |
136 | QPointer<KScoreDialog> dialog = new KScoreDialog(KScoreDialog::Name | KScoreDialog::Score | KScoreDialog::Level, this); |
137 | dialog->initFromDifficulty(Kg::difficulty()); |
138 | KScoreDialog::FieldInfo scoreInfo; |
139 | scoreInfo[KScoreDialog::Level].setNum(m_game->getLevel()); |
140 | scoreInfo[KScoreDialog::Score].setNum(m_game->getScore()); |
141 | // If the new score is a highscore then display the highscore dialog |
142 | if (dialog->addScore(scoreInfo)) { |
143 | dialog->exec(); |
144 | } |
145 | delete dialog; |
146 | } |
147 | // Start a new game |
148 | initGame(); |
149 | } |
150 | } |
151 | |
152 | void KapmanMainWindow::changeLevel() { |
153 | int newLevel = KInputDialog::getInteger(i18n("Change level" ), i18nc("The number of the game level" , "Level" ), m_game->getLevel(), 1, 1000000, 1, 10, 0, this); |
154 | if (newLevel > 0) { |
155 | m_game->setLevel(newLevel); |
156 | } |
157 | } |
158 | |
159 | void KapmanMainWindow::showHighscores() { |
160 | QPointer<KScoreDialog> dialog = new KScoreDialog(KScoreDialog::Name | KScoreDialog::Score | KScoreDialog::Level, this); |
161 | dialog->initFromDifficulty(Kg::difficulty()); |
162 | dialog->exec(); |
163 | delete dialog; |
164 | } |
165 | |
166 | void KapmanMainWindow::setSoundsEnabled(bool p_enabled) { |
167 | m_game->setSoundsEnabled(p_enabled); |
168 | } |
169 | |
170 | void KapmanMainWindow::showSettings() { |
171 | if (KConfigDialog::showDialog("settings" )) { |
172 | return; |
173 | } |
174 | KConfigDialog* settingsDialog = new KConfigDialog(this, "settings" , Settings::self()); |
175 | settingsDialog->addPage(new KGameThemeSelector(settingsDialog, Settings::self(), KGameThemeSelector::NewStuffDisableDownload), i18n("Theme" ), "kapman" ); |
176 | settingsDialog->setFaceType(KConfigDialog::Plain); //only one page -> no page selection necessary |
177 | connect(settingsDialog, SIGNAL(settingsChanged(QString)), this, SLOT(loadSettings())); |
178 | settingsDialog->show(); |
179 | } |
180 | |
181 | void KapmanMainWindow::loadSettings() { |
182 | ((GameScene*)m_view->scene())->loadTheme(); |
183 | } |
184 | |
185 | void KapmanMainWindow::close() { |
186 | bool gameRunning; // True if the game is running (game timer is active), false otherwise |
187 | |
188 | gameRunning = m_game->getTimer()->isActive(); |
189 | // If the game is running |
190 | if (gameRunning) { |
191 | // Pause the game |
192 | m_game->pause(); |
193 | } |
194 | // Confirm before closing |
195 | if(KMessageBox::warningYesNo(this, i18n("Are you sure you want to quit Kapman?" ), i18nc("To quit Kapman" , "Quit" )) == KMessageBox::Yes) { |
196 | KXmlGuiWindow::close(); |
197 | } |
198 | else { |
199 | // If the game was running |
200 | if (gameRunning) { |
201 | // Resume the game |
202 | m_game->start(); |
203 | } |
204 | } |
205 | } |
206 | |
207 | void KapmanMainWindow::displayLevel(unsigned int p_level) |
208 | { |
209 | m_statusBar->changeItem(i18nc( |
210 | "Used to display the current level of play to the user" , |
211 | "Level: %1" , p_level), 1); |
212 | } |
213 | |
214 | void KapmanMainWindow::displayScore(unsigned int p_score) |
215 | { |
216 | m_statusBar->changeItem(i18nc( |
217 | "Used to inform the user of their current score" , "Score: %1" , |
218 | p_score), 2); |
219 | } |
220 | |
221 | void KapmanMainWindow::displayLives(unsigned int p_lives) |
222 | { |
223 | m_statusBar->changeItem(i18nc( |
224 | "Used to tell the user how many lives they have left" , "Lives: %1" , |
225 | p_lives), 4); |
226 | } |
227 | |
228 | void KapmanMainWindow::resetStatusBar() |
229 | { |
230 | displayLevel(1); |
231 | displayScore(0); |
232 | displayLives(initLives); |
233 | } |
234 | |