~ubuntu-branches/ubuntu/vivid/kapman/vivid-proposed

« back to all changes in this revision

Viewing changes to gamescene.cpp

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2012-12-07 17:37:19 UTC
  • Revision ID: package-import@ubuntu.com-20121207173719-5973b949kqub4zup
Tags: upstream-4.9.90
ImportĀ upstreamĀ versionĀ 4.9.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright 2007-2008 Thomas Gallinari <tg8187@yahoo.fr>
 
3
 * Copyright 2007-2008 Alexandre Galinier <alex.galinier@hotmail.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 "gamescene.h"
 
20
#include "cell.h"
 
21
#include "bonus.h"
 
22
#include "settings.h"
 
23
 
 
24
#include <KLocale>
 
25
 
 
26
GameScene::GameScene(Game* p_game) : m_game(p_game), m_kapmanItem(0), m_mazeItem(0) {
 
27
        connect(p_game, SIGNAL(levelStarted(bool)), SLOT(intro(bool)));
 
28
        connect(p_game, SIGNAL(gameStarted()), this, SLOT(start()));
 
29
        connect(p_game, SIGNAL(pauseChanged(bool,bool)), this, SLOT(setPaused(bool,bool)));
 
30
        connect(p_game, SIGNAL(elementEaten(qreal,qreal)), this, SLOT(hideElement(qreal,qreal)));
 
31
        connect(p_game, SIGNAL(bonusOn()), this, SLOT(displayBonus())); 
 
32
        connect(p_game, SIGNAL(bonusOff()), this, SLOT(hideBonus()));
 
33
 
 
34
        // Connection between Game and GameScene for the display of won points when a bonus or a ghost is eaten
 
35
        connect(p_game, SIGNAL(pointsToDisplay(long,qreal,qreal)), this, SLOT(displayPoints(long,qreal,qreal)));
 
36
 
 
37
        // Create the theme instance
 
38
        m_theme = new KGameTheme();
 
39
 
 
40
        // Load the SVG file
 
41
        m_renderer = new QSvgRenderer();
 
42
        loadTheme();
 
43
 
 
44
        // Create the MazeItem
 
45
        m_mazeItem = new MazeItem();
 
46
        // Give the maze the shared renderer to avoid loading the whole SVG file again
 
47
        m_mazeItem->setSharedRenderer(m_renderer);
 
48
        // Set the element Id to the right value
 
49
        m_mazeItem->setElementId("maze");
 
50
        m_mazeItem->setZValue(-2);
 
51
 
 
52
        // Create the KapmanItem
 
53
        m_kapmanItem = new KapmanItem(p_game->getKapman());
 
54
        m_kapmanItem->setSharedRenderer(m_renderer);
 
55
        m_kapmanItem->setElementId("kapman_0");
 
56
        // Corrects the position of the KapmanItem
 
57
        m_kapmanItem->update(p_game->getKapman()->getX(), p_game->getKapman()->getY());
 
58
        m_kapmanItem->setZValue(2);
 
59
        // Stops the Kapman animation
 
60
        m_kapmanItem->stopAnim();
 
61
 
 
62
        // Create the GhostItems
 
63
        for (int i = 0; i < p_game->getGhosts().size(); ++i) {
 
64
                GhostItem* ghost = new GhostItem(p_game->getGhosts()[i]);
 
65
                ghost->setSharedRenderer(m_renderer);
 
66
                ghost->setElementId(p_game->getGhosts()[i]->getImageId());
 
67
                ghost->update(p_game->getGhosts()[i]->getX(), p_game->getGhosts()[i]->getY());
 
68
                // At the beginning, the ghosts are above the kapman because they eat him
 
69
                ghost->setZValue(3);
 
70
                m_ghostItems.append(ghost);
 
71
        }
 
72
        // Create the Pill and Energizer items
 
73
        m_elementItems = new ElementItem**[m_game->getMaze()->getNbRows()];
 
74
        for (int i = 0; i < m_game->getMaze()->getNbRows(); ++i) {
 
75
                m_elementItems[i] = new ElementItem*[m_game->getMaze()->getNbColumns()];
 
76
                for (int j = 0; j < m_game->getMaze()->getNbColumns(); ++j) {
 
77
                        if (m_game->getMaze()->getCell(i, j).getElement() != NULL) {
 
78
                                // Create the element and set the image
 
79
                                ElementItem* element = new ElementItem(m_game->getMaze()->getCell(i, j).getElement());
 
80
                                element->setSharedRenderer(m_renderer);
 
81
                                element->setElementId(m_game->getMaze()->getCell(i,j).getElement()->getImageId());
 
82
                                element->update(m_game->getMaze()->getCell(i, j).getElement()->getX(), m_game->getMaze()->getCell(i, j).getElement()->getY());
 
83
                                m_elementItems[i][j] = element;
 
84
                        } else {
 
85
                                m_elementItems[i][j] = NULL;
 
86
                        }
 
87
                }
 
88
        }
 
89
        // Create the Bonus item
 
90
        m_bonusItem = new ElementItem(m_game->getBonus());
 
91
        m_bonusItem->setSharedRenderer(m_renderer);
 
92
        m_bonusItem->setElementId("bonus1");
 
93
 
 
94
        // All elements are created, update theme properties
 
95
        updateSvgIds();
 
96
        updateThemeProperties();
 
97
 
 
98
        // Create the introduction labels
 
99
        m_introLabel = new QGraphicsTextItem(i18n("GET READY!!!"));
 
100
        m_introLabel->setFont(QFont("Helvetica", 25, QFont::Bold, false));
 
101
        m_introLabel->setDefaultTextColor(QColor("#FFFF00"));
 
102
        m_introLabel->setZValue(4);
 
103
        m_introLabel2 = new QGraphicsTextItem(i18n("Press any arrow key to start"));
 
104
        m_introLabel2->setFont(QFont("Helvetica", 15, QFont::Bold, false));
 
105
        m_introLabel2->setDefaultTextColor(QColor("#FFFF00"));
 
106
        m_introLabel2->setZValue(4);
 
107
        // Create the new level label
 
108
        m_newLevelLabel = new QGraphicsTextItem();
 
109
        m_newLevelLabel->setFont(QFont("Helvetica", 35, QFont::Bold, false));
 
110
        m_newLevelLabel->setDefaultTextColor(QColor("#FFFF00"));
 
111
        m_newLevelLabel->setZValue(4);
 
112
        // Create the pause label
 
113
        m_pauseLabel = new QGraphicsTextItem(i18n("PAUSED"));
 
114
        m_pauseLabel->setFont(QFont("Helvetica", 35, QFont::Bold, false));
 
115
        m_pauseLabel->setDefaultTextColor(QColor("#FFFF00"));
 
116
        m_pauseLabel->setZValue(4);
 
117
 
 
118
        // Display the MazeItem
 
119
        addItem(m_mazeItem);
 
120
        // Display the KapmanItem
 
121
        addItem(m_kapmanItem);
 
122
        // Display each GhostItem
 
123
        for (int i = 0; i < m_ghostItems.size(); ++i) {
 
124
                addItem(m_ghostItems[i]);
 
125
        }
 
126
        // Display each Pill and Energizer item and introduction labels
 
127
        intro(true);
 
128
}
 
129
 
 
130
GameScene::~GameScene() {
 
131
        delete m_mazeItem;
 
132
        delete m_kapmanItem;
 
133
        for (int i = 0; i < m_ghostItems.size(); ++i) {
 
134
                delete m_ghostItems[i];
 
135
        }
 
136
        for (int i = 0; i < m_game->getMaze()->getNbRows();++i) {
 
137
                for (int j = 0; j < m_game->getMaze()->getNbColumns(); ++j) {
 
138
                        if (m_elementItems[i][j] != NULL) {
 
139
                                delete m_elementItems[i][j];
 
140
                        }
 
141
                }
 
142
                delete[] m_elementItems[i];
 
143
        }
 
144
        delete[] m_elementItems;
 
145
        delete m_bonusItem;
 
146
        delete m_introLabel;
 
147
        delete m_introLabel2;
 
148
        delete m_newLevelLabel;
 
149
        delete m_pauseLabel;
 
150
        delete m_renderer;
 
151
        delete m_theme;
 
152
}
 
153
 
 
154
Game* GameScene::getGame() const {
 
155
        return m_game;
 
156
}
 
157
 
 
158
void GameScene::loadTheme() {
 
159
        if (!m_theme->load(Settings::self()->theme())) {
 
160
                return;
 
161
        }
 
162
        if (!m_renderer->load(m_theme->graphics())) {
 
163
                return;
 
164
        }
 
165
 
 
166
        //Update elementIDs, theme properties
 
167
        updateSvgIds();
 
168
        updateThemeProperties();
 
169
 
 
170
        update(0, 0, width(), height());
 
171
 
 
172
        // Update the theme config: if the default theme is selected, no theme entry is written -> the theme selector does not select the theme
 
173
        Settings::self()->config()->group("General").writeEntry("Theme", Settings::self()->theme());
 
174
}
 
175
 
 
176
void GameScene::updateSvgIds() {
 
177
        //Needed so new boundingRects() are read for all SVG elements after a theme change
 
178
        // Sanity check, see if game elements already exist
 
179
        if (!m_kapmanItem) return;
 
180
 
 
181
        // Set the element Id to the right value
 
182
        m_mazeItem->setElementId("maze");
 
183
 
 
184
        // Create the KapmanItem
 
185
        m_kapmanItem->setElementId("kapman_0");
 
186
        // Corrects the position of the KapmanItem
 
187
        m_kapmanItem->update(m_game->getKapman()->getX(), m_game->getKapman()->getY());
 
188
 
 
189
        for (int i = 0; i < m_ghostItems.size(); ++i) {
 
190
                GhostItem* ghost = m_ghostItems[i];
 
191
                ghost->setElementId(m_game->getGhosts()[i]->getImageId());
 
192
                ghost->update(m_game->getGhosts()[i]->getX(), m_game->getGhosts()[i]->getY());
 
193
        }
 
194
        for (int i = 0; i < m_game->getMaze()->getNbRows();++i) {
 
195
                for (int j = 0; j < m_game->getMaze()->getNbColumns(); ++j) {
 
196
                        if (m_elementItems[i][j] != NULL) {
 
197
                                ElementItem* element = m_elementItems[i][j];
 
198
                                element->setElementId(m_game->getMaze()->getCell(i,j).getElement()->getImageId());
 
199
                                element->update(m_game->getMaze()->getCell(i, j).getElement()->getX(), m_game->getMaze()->getCell(i, j).getElement()->getY());
 
200
                        }
 
201
                }
 
202
        }
 
203
}
 
204
 
 
205
void GameScene::updateThemeProperties() {
 
206
        // Sanity check, see if game elements already exist
 
207
        if (!m_kapmanItem) return;
 
208
 
 
209
        // Set the Rotation flag for KapmanItem
 
210
        if (m_theme->themeProperty("RotateKapman")=="0") {
 
211
                m_kapmanItem->setRotationFlag(false);
 
212
        } else {
 
213
                m_kapmanItem->setRotationFlag(true);
 
214
        }
 
215
}
 
216
 
 
217
void GameScene::intro(const bool p_newLevel) {
 
218
        // If a new level has begun
 
219
        if (p_newLevel) {
 
220
                // Set each Pill and Energizer item to its original coordinates
 
221
                for (int i = 0; i < m_game->getMaze()->getNbRows(); ++i) {
 
222
                        for (int j = 0; j < m_game->getMaze()->getNbColumns(); ++j) {
 
223
                                if (m_elementItems[i][j] != NULL) {
 
224
                                        if (!items().contains(m_elementItems[i][j])) {
 
225
                                                addItem(m_elementItems[i][j]);
 
226
                                        }
 
227
                                }
 
228
                        }
 
229
                }
 
230
                // Display the new level label
 
231
                m_newLevelLabel->setPlainText(i18nc("The number of the game level", "Level %1", m_game->getLevel()));
 
232
                if (!items().contains(m_newLevelLabel)) {
 
233
                        addItem(m_newLevelLabel);
 
234
                        m_newLevelLabel->setPos((width() - m_newLevelLabel->boundingRect().width()) / 2, (height() - m_newLevelLabel->boundingRect().height()) / 2);
 
235
                }
 
236
                // Display the introduction label
 
237
                if (!items().contains(m_introLabel2)) {
 
238
                        addItem(m_introLabel2);
 
239
                        m_introLabel2->setPos((width() - m_introLabel2->boundingRect().width()) / 2,
 
240
                                (height() - m_introLabel2->boundingRect().height() + m_newLevelLabel->boundingRect().height()) / 2);
 
241
                }
 
242
        } else {
 
243
                // Display the introduction labels
 
244
                if (!items().contains(m_introLabel)) {
 
245
                        addItem(m_introLabel);
 
246
                        m_introLabel->setPos((width() - m_introLabel->boundingRect().width()) / 2, (height() - m_introLabel->boundingRect().height()) / 2);
 
247
                }
 
248
                if (!items().contains(m_introLabel2)) {
 
249
                        addItem(m_introLabel2);
 
250
                        m_introLabel2->setPos((width() - m_introLabel2->boundingRect().width()) / 2,
 
251
                                (height() - m_introLabel2->boundingRect().height() + m_introLabel->boundingRect().height()) / 2);
 
252
                }
 
253
        }
 
254
}
 
255
 
 
256
void GameScene::start() {
 
257
        // If the introduction and new level labels were displayed then remove them
 
258
        if (items().contains(m_introLabel)) {
 
259
                removeItem(m_introLabel);
 
260
        }
 
261
        if (items().contains(m_introLabel2)) {
 
262
                removeItem(m_introLabel2);
 
263
        }
 
264
        if (items().contains(m_newLevelLabel)) {
 
265
                removeItem(m_newLevelLabel);
 
266
        }
 
267
}
 
268
 
 
269
void GameScene::setPaused(const bool p_pause, const bool p_fromUser) {
 
270
        // If the game has paused
 
271
        if (p_pause) {
 
272
                // If the pause is due to an action from the user
 
273
                if (p_fromUser) {
 
274
                        // If the label was not displayed yet
 
275
                        if (!items().contains(m_pauseLabel)) {
 
276
                                // FIXME: Hack to remove labels when pausing game while init labels are shown (icwiener)
 
277
                                //        This should be done cleaner
 
278
                                // FIXME #2: start() is a misleading method name ...
 
279
                                start();
 
280
                                // Display the pause label
 
281
                                addItem(m_pauseLabel);
 
282
                                m_pauseLabel->setPos((width() - m_pauseLabel->boundingRect().width()) / 2, (height() - m_pauseLabel->boundingRect().height()) / 2);
 
283
                        }
 
284
                }
 
285
                // Stop kapman animation
 
286
                m_kapmanItem->pauseAnim();
 
287
        } else {        // If the game has resumed
 
288
                // If the pause was due to an action from the user
 
289
                if (p_fromUser) {
 
290
                        // If the label was displayed
 
291
                        if (items().contains(m_pauseLabel)) {
 
292
                                removeItem(m_pauseLabel);
 
293
                        }
 
294
                }
 
295
                // Resume kapman animation
 
296
                m_kapmanItem->resumeAnim();
 
297
        }
 
298
}
 
299
 
 
300
void GameScene::hideElement(const qreal p_x, const qreal p_y) {
 
301
        if (items().contains(m_elementItems[(int)((p_y - (Cell::SIZE * 0.5)) / Cell::SIZE)][(int)((p_x - (Cell::SIZE * 0.5)) / Cell::SIZE)])) {
 
302
                removeItem(m_elementItems[(int)((p_y - (Cell::SIZE * 0.5)) / Cell::SIZE)][(int)((p_x - (Cell::SIZE * 0.5)) / Cell::SIZE)]);
 
303
        }
 
304
}
 
305
 
 
306
void GameScene::displayBonus() {
 
307
        if (!items().contains(m_bonusItem)) {
 
308
                switch (m_game->getLevel()) {
 
309
                        case 1:
 
310
                                m_bonusItem->setElementId("bonus1");
 
311
                                break;
 
312
                        case 2:
 
313
                                m_bonusItem->setElementId("bonus2");
 
314
                                break;
 
315
                        case 3:
 
316
                                m_bonusItem->setElementId("bonus3");
 
317
                                break;
 
318
                        case 4:
 
319
                                m_bonusItem->setElementId("bonus4");
 
320
                                break;
 
321
                        case 5:
 
322
                                m_bonusItem->setElementId("bonus5");
 
323
                                break;
 
324
                        case 6:
 
325
                                m_bonusItem->setElementId("bonus6");
 
326
                                break;
 
327
                        default:
 
328
                                m_bonusItem->setElementId("bonus7");
 
329
                                break;  
 
330
                }
 
331
                m_bonusItem->update(m_game->getBonus()->getX(), m_game->getBonus()->getY());
 
332
                addItem(m_bonusItem);
 
333
        }
 
334
}
 
335
 
 
336
void GameScene::hideBonus() {
 
337
        if (items().contains(m_bonusItem)) {
 
338
                removeItem(m_bonusItem);
 
339
        }
 
340
}
 
341
 
 
342
 
 
343
void GameScene::displayPoints(long p_wonPoints, qreal p_xPos, qreal p_yPos) {
 
344
        // Launch a singleShot timer
 
345
        QTimer::singleShot(1000, this, SLOT(hidePoints()));
 
346
 
 
347
        // Add a label in the list of won points Labels
 
348
        m_wonPointsLabels.prepend(new QGraphicsTextItem(QString::number(p_wonPoints)));
 
349
        addItem(m_wonPointsLabels.first());
 
350
 
 
351
        // Temporary reference to the first item in the list
 
352
        QGraphicsTextItem* tempRef = m_wonPointsLabels.first();
 
353
 
 
354
        // Positioning and customization of the point label
 
355
        tempRef->setDefaultTextColor(QColor("#FFFF00"));
 
356
        tempRef->setFont(QFont("Helvetica", 15, QFont::Normal, false));
 
357
        tempRef->setPos(p_xPos-(tempRef->boundingRect().width() / 2), p_yPos-(tempRef->boundingRect().height() / 2));
 
358
        tempRef->setZValue(-1);
 
359
}
 
360
 
 
361
void GameScene::hidePoints() {
 
362
        // Remove the oldest item of the list from the scene
 
363
        removeItem(m_wonPointsLabels.last());
 
364
        // Remove the oldest item from the list
 
365
        delete m_wonPointsLabels.takeLast();
 
366
}