~ubuntu-branches/ubuntu/saucy/kblocks/saucy-proposed

« back to all changes in this revision

Viewing changes to KBlocksScene.cpp

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2012-12-07 17:39:13 UTC
  • Revision ID: package-import@ubuntu.com-20121207173913-5wqlq9suj93x4ap2
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
*   KBlocks, a falling blocks game for KDE                                *
 
3
*   Copyright (C) 2010 Mauricio Piacentini <mauricio@tabuleiro.com>       *
 
4
*                      Zhongjie Cai <squall.leonhart.cai@gmail.com>       *
 
5
*                                                                         *
 
6
*   This program is free software; you can redistribute it and/or modify  *
 
7
*   it under the terms of the GNU General Public License as published by  *
 
8
*   the Free Software Foundation; either version 2 of the License, or     *
 
9
*   (at your option) any later version.                                   *
 
10
***************************************************************************/
 
11
#include "KBlocksScene.h"
 
12
 
 
13
#include "settings.h"
 
14
 
 
15
#include <QVarLengthArray>
 
16
 
 
17
KBlocksScene::KBlocksScene(GameLogicInterface * p, int capacity)
 
18
{
 
19
    mpGameLogic = p;
 
20
    mGameStarted = false;
 
21
    
 
22
    mSnapshotMode = false;
 
23
    mTopGameLevel = 0;
 
24
    mGroupCount = 0;
 
25
    mMaxCapacity = capacity;
 
26
    mSceneGamesPerLine = 4;
 
27
    mGameAnimEnabled = true;
 
28
    mWaitForAllUpdate = false;
 
29
    
 
30
    maGroupList = new KBlocksItemGroup*[capacity]();
 
31
    maGameScoreList = new KBlocksScore*[capacity]();
 
32
    maGameReadySignal = new bool[capacity]();
 
33
    
 
34
    QString themeFile(Settings::theme());
 
35
    mpGrafx = new KBlocksGraphics(themeFile);
 
36
    mpSnd = new KBlocksSound(themeFile);
 
37
    
 
38
    int width = (capacity >= mSceneGamesPerLine) ? mSceneGamesPerLine : (capacity % mSceneGamesPerLine);
 
39
    int height = (int)(capacity / (mSceneGamesPerLine + 1)) + 1;
 
40
    setSceneRect(0, 0, mpGrafx->m_View_Size_Width * width,
 
41
                       mpGrafx->m_View_Size_Height * height);
 
42
    
 
43
    setItemIndexMethod(NoIndex);
 
44
    
 
45
    mUpdateInterval = 50;
 
46
    mUpdateTimer.setInterval(mUpdateInterval);
 
47
    connect(&mUpdateTimer, SIGNAL(timeout()), SLOT(updateGame()));
 
48
    mUpdateTimer.stop();
 
49
}
 
50
 
 
51
KBlocksScene::~KBlocksScene()
 
52
{
 
53
    delete [] maGameReadySignal;
 
54
    delete [] maGameScoreList;
 
55
    delete [] maGroupList;
 
56
    
 
57
    delete mpGrafx;
 
58
    delete mpSnd;
 
59
}
 
60
 
 
61
KBlocksItemGroup* KBlocksScene::getItemGroup(int index)
 
62
{
 
63
    return maGroupList[index];
 
64
}
 
65
 
 
66
KBlocksScore* KBlocksScene::getScoreHandler(int index)
 
67
{
 
68
    return maGameScoreList[index];
 
69
}
 
70
 
 
71
void KBlocksScene::createGameItemGroups(int groupCount, bool snapshotMode)
 
72
{
 
73
    if (groupCount > mMaxCapacity)
 
74
    {
 
75
        mGroupCount = mMaxCapacity;
 
76
    }
 
77
    mGroupCount = groupCount;
 
78
    mSnapshotMode = snapshotMode;
 
79
    mTopGameLevel = 0;
 
80
    
 
81
    for(int i = 0; i < mGroupCount; i++)
 
82
    {
 
83
        maGroupList[i] = new KBlocksItemGroup(i, mpGameLogic->getSingleGame(i), mpGrafx, mpSnd, snapshotMode);
 
84
        maGroupList[i]->setUpdateInterval(mUpdateInterval);
 
85
        maGroupList[i]->setGameAnimEnabled(mGameAnimEnabled);
 
86
        maGroupList[i]->setWaitForAllUpdate(mWaitForAllUpdate);
 
87
        addItem(maGroupList[i]);
 
88
        
 
89
        maGameScoreList[i] = new KBlocksScore();
 
90
        maGameScoreList[i]->setLevelUpFactor(KBlocksScore_Level_x_Level_x_Factor, 1000);
 
91
        maGameScoreList[i]->setScoreUpFactor(10);
 
92
        
 
93
        maGameReadySignal[i] = false;
 
94
        connect(maGroupList[i], SIGNAL(readyForAction(int)), this, SLOT(readyForAction(int)));
 
95
    }
 
96
    
 
97
    updateDimensions();
 
98
        
 
99
    //Our Message Item, hidden by default
 
100
    mMessageBox = new KGamePopupItem();
 
101
    mMessageBox->setMessageOpacity(0.9);
 
102
    addItem(mMessageBox);
 
103
}
 
104
 
 
105
void KBlocksScene::deleteGameItemGroups()
 
106
{
 
107
    removeItem(mMessageBox);
 
108
    delete mMessageBox;
 
109
 
 
110
    for(int i = 0; i < mGroupCount; i++)
 
111
    {
 
112
        disconnect(maGroupList[i], SIGNAL(readyForAction(int)), this, SLOT(readyForAction(int)));
 
113
        
 
114
        delete maGameScoreList[i];
 
115
        maGameScoreList[i] = 0;
 
116
        
 
117
        removeItem(maGroupList[i]);
 
118
        delete maGroupList[i];
 
119
        maGroupList[i] = 0;
 
120
    }
 
121
    mGroupCount = 0;
 
122
}
 
123
 
 
124
void KBlocksScene::setGamesPerLine(int count)
 
125
{
 
126
    mSceneGamesPerLine = count;
 
127
}
 
128
 
 
129
void KBlocksScene::setGameAnimEnabled(bool flag)
 
130
{
 
131
    mGameAnimEnabled = flag;
 
132
    for(int i = 0; i < mGroupCount; i++)
 
133
    {
 
134
        maGroupList[i]->setGameAnimEnabled(flag);
 
135
    }
 
136
}
 
137
 
 
138
void KBlocksScene::setWaitForAllUpdate(bool flag)
 
139
{
 
140
    mWaitForAllUpdate = flag;
 
141
    for(int i = 0; i < mGroupCount; i++)
 
142
    {
 
143
        maGroupList[i]->setWaitForAllUpdate(flag);
 
144
    }
 
145
}
 
146
 
 
147
void KBlocksScene::setUpdateInterval(int interval)
 
148
{
 
149
    mUpdateInterval = interval;
 
150
    mUpdateTimer.setInterval(mUpdateInterval);
 
151
    for(int i = 0; i < mGroupCount; i++)
 
152
    {
 
153
        maGroupList[i]->setUpdateInterval(mUpdateInterval);
 
154
    }
 
155
}
 
156
 
 
157
void KBlocksScene::setSoundsEnabled(bool enabled)
 
158
{
 
159
    mpSnd->setSoundsEnabled(enabled);
 
160
}
 
161
 
 
162
void KBlocksScene::readSettings(const QSize & viewSize)
 
163
{
 
164
    if (mpGrafx->theme()->fileName()!=Settings::theme())
 
165
    {
 
166
        mpGrafx->loadTheme(Settings::theme());
 
167
        mpSnd->loadTheme(Settings::theme());
 
168
        mpGrafx->adjustForSize(viewSize);
 
169
        updateDimensions();
 
170
    }
 
171
}
 
172
 
 
173
void KBlocksScene::viewScaled(const QSize& /*newsize*/)
 
174
{
 
175
    /*
 
176
    //Temporarily halt game timer while resizing elements
 
177
    if (gameState==Game_Active) stepTimer.stop();
 
178
    grafx->adjustForSize(newsize);
 
179
    updateDimensions();
 
180
    //Do not restart if game was paused
 
181
    if (gameState==Game_Active) stepTimer.start();
 
182
    */
 
183
}
 
184
 
 
185
void KBlocksScene::startGame()
 
186
{
 
187
    if (mGameStarted)
 
188
    {
 
189
        return;
 
190
    }
 
191
    mGameStarted = true;
 
192
    
 
193
    mTopGameLevel = 0;
 
194
    for(int i = 0; i < mGroupCount; i++)
 
195
    {
 
196
        maGroupList[i]->startGame();
 
197
    }
 
198
    
 
199
    if (!mSnapshotMode)
 
200
    {
 
201
        mUpdateTimer.start();
 
202
        QTimer::singleShot(500, this, SLOT(greetPlayer()));
 
203
    }
 
204
}
 
205
 
 
206
void KBlocksScene::stopGame()
 
207
{
 
208
    if (!mGameStarted)
 
209
    {
 
210
        return;
 
211
    }
 
212
    mGameStarted = false;
 
213
    
 
214
    for(int i = 0; i < mGroupCount; i++)
 
215
    {
 
216
        maGroupList[i]->stopGame();
 
217
    }
 
218
    
 
219
    mUpdateTimer.stop();
 
220
}
 
221
 
 
222
void KBlocksScene::pauseGame(bool flag, bool fromUI)
 
223
{
 
224
    if (!mGameStarted)
 
225
    {
 
226
        return;
 
227
    }
 
228
    
 
229
    QString resuming(i18n("Game Resumed!"));
 
230
    QString pausing(i18n("Game Paused!"));
 
231
    
 
232
    for(int i = 0; i < mGroupCount; i++)
 
233
    {
 
234
        maGroupList[i]->pauseGame(flag);
 
235
    }
 
236
    
 
237
    if (!mSnapshotMode)
 
238
    {
 
239
        if (flag)
 
240
        {
 
241
            mUpdateTimer.stop();
 
242
            if (!fromUI)
 
243
            {
 
244
                showMessage(pausing, 2000);
 
245
            }
 
246
        }
 
247
        else
 
248
        {
 
249
            mUpdateTimer.start();
 
250
            if (!fromUI)
 
251
            {
 
252
                showMessage(resuming, 2000);
 
253
            }
 
254
        }
 
255
    }
 
256
}
 
257
 
 
258
void KBlocksScene::addScore(int gameIndex, int lineCount)
 
259
{
 
260
    if (!mSnapshotMode)
 
261
    {
 
262
        return;
 
263
    }
 
264
    maGameScoreList[gameIndex]->addScore(lineCount);
 
265
    emit scoreChanged(gameIndex, maGameScoreList[gameIndex]->getScorePoint(),
 
266
                                 maGameScoreList[gameIndex]->getLineCount(), 
 
267
                                 maGameScoreList[gameIndex]->getGameLevel());
 
268
}
 
269
 
 
270
void KBlocksScene::updateDimensions()
 
271
{
 
272
    // TODO : Reset item position and scale
 
273
    int width = (mGroupCount >= mSceneGamesPerLine) ? mSceneGamesPerLine : (mGroupCount % mSceneGamesPerLine);
 
274
    int height = (int)(mGroupCount / (mSceneGamesPerLine + 1)) + 1;
 
275
    
 
276
    setSceneRect(0, 0, mpGrafx->m_View_Size_Width * width,
 
277
                       mpGrafx->m_View_Size_Height * height);
 
278
    
 
279
    for(int i = 0; i < mGroupCount; i++)
 
280
    {
 
281
        int left = mpGrafx->m_View_Size_Width * (i % mSceneGamesPerLine);
 
282
        int top = mpGrafx->m_View_Size_Height * ((int)(i / mSceneGamesPerLine));
 
283
        
 
284
        maGroupList[i]->setPos(left, top);
 
285
        maGroupList[i]->refreshPosition();
 
286
    }
 
287
}
 
288
 
 
289
void KBlocksScene::greetPlayer()
 
290
{
 
291
    QString greets(i18n("Game Start!")); 
 
292
    showMessage( greets, 2000 );
 
293
}
 
294
 
 
295
void KBlocksScene::gameOverPlayer()
 
296
{
 
297
    QString greets(i18n("Game Over!")); 
 
298
    showMessage( greets, 2000 );
 
299
}
 
300
 
 
301
void KBlocksScene::gameOverMultiWin()
 
302
{
 
303
    QString gameOver(i18n("You Win!")); 
 
304
    showMessage( gameOver, 2000 );
 
305
}
 
306
 
 
307
void KBlocksScene::gameOverMultiLose()
 
308
{
 
309
    QString gameOver(i18n("You Lose!")); 
 
310
    showMessage( gameOver, 2000 );
 
311
}
 
312
 
 
313
void KBlocksScene::showMessage(const QString& message, int ms)
 
314
{
 
315
    mMessageBox->setMessageTimeout( ms );
 
316
    mMessageBox->showMessage( message, KGamePopupItem::TopLeft );
 
317
}
 
318
 
 
319
void KBlocksScene::updateGame()
 
320
{
 
321
    if (mSnapshotMode)
 
322
    {
 
323
        return;
 
324
    }
 
325
    
 
326
    QVarLengthArray<int, 16> removedLines(mGroupCount);
 
327
    int gameCount = mpGameLogic->updateGame(removedLines.data());
 
328
    
 
329
    for(int i = 0; i < mGroupCount; i++)
 
330
    {
 
331
        if (removedLines[i] > 0)
 
332
        {
 
333
            if (maGameScoreList[i]->addScore(removedLines[i]))
 
334
            {
 
335
                int tmpLevel = maGameScoreList[i]->getGameLevel();
 
336
                if (mTopGameLevel < tmpLevel)
 
337
                {
 
338
                    mpGameLogic->levelUpGame(tmpLevel - mTopGameLevel);
 
339
                    mTopGameLevel = tmpLevel;
 
340
                }
 
341
            }
 
342
            emit scoreChanged(i, maGameScoreList[i]->getScorePoint(),
 
343
                                 maGameScoreList[i]->getLineCount(), 
 
344
                                 maGameScoreList[i]->getGameLevel());
 
345
        }
 
346
        else if (removedLines[i] == -1)
 
347
        {
 
348
            maGroupList[i]->stopGame();
 
349
            if (mGroupCount == 1)
 
350
            {
 
351
                QTimer::singleShot(500, this, SLOT(gameOverPlayer()));
 
352
                emit isHighscore(0, maGameScoreList[0]->getScorePoint(),
 
353
                                    maGameScoreList[0]->getGameLevel());
 
354
            }
 
355
            else
 
356
            {
 
357
                if (i == 0)
 
358
                {
 
359
                    for (int j = 0; j < mGroupCount; j++)
 
360
                    {
 
361
                        maGroupList[j]->stopGame();
 
362
                    }
 
363
                    QTimer::singleShot(500, this, SLOT(gameOverMultiLose()));
 
364
                    emit isHighscore(0, maGameScoreList[0]->getScorePoint(),
 
365
                                        maGameScoreList[0]->getGameLevel());
 
366
                }
 
367
                else if (gameCount <= 1)
 
368
                {
 
369
                    maGroupList[0]->stopGame();
 
370
                    QTimer::singleShot(500, this, SLOT(gameOverMultiWin()));
 
371
                    emit isHighscore(0, maGameScoreList[0]->getScorePoint(),
 
372
                                        maGameScoreList[0]->getGameLevel());
 
373
                }
 
374
            }
 
375
        }
 
376
    }
 
377
}
 
378
 
 
379
void KBlocksScene::readyForAction(int groupID)
 
380
{
 
381
    maGameReadySignal[groupID] = true;
 
382
    bool allReady = true;
 
383
    for(int i = 0; i < mGroupCount; i++)
 
384
    {
 
385
        if (!maGameReadySignal[i])
 
386
        {
 
387
            allReady = false;
 
388
        }
 
389
    }
 
390
    if (allReady)
 
391
    {
 
392
        for(int i = 0; i < mGroupCount; i++)
 
393
        {
 
394
            if (mpGameLogic->getSingleGame(i)->isGameRunning())
 
395
            {
 
396
                maGameReadySignal[i] = false;
 
397
            }
 
398
        }
 
399
        mpGameLogic->continueGame();
 
400
    }
 
401
}
 
402
 
 
403
void KBlocksScene::drawBackground( QPainter * painter, const QRectF & rect )
 
404
{
 
405
    if (mpGrafx->renderer()->isValid())
 
406
    {
 
407
        mpGrafx->renderer()->render(painter, QString("BACKGROUND"), rect);
 
408
    }
 
409
}
 
410
 
 
411