The score counting now stops during pauses
[ghostsoverboard] / seascene.cpp
1 /**************************************************************************
2         Ghosts Overboard - a game for Maemo 5
3
4         Copyright (C) 2011  Heli Hyvättinen
5
6         This file is part of Ghosts Overboard
7
8         Ghosts Overboard is free software: you can redistribute it and/or modify
9         it under the terms of the GNU General Public License as published by
10         the Free Software Foundation, either version 2 of the License, or
11         (at your option) any later version.
12
13         This program is distributed in the hope that it will be useful,
14         but WITHOUT ANY WARRANTY; without even the implied warranty of
15         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16         GNU General Public License for more details.
17
18         You should have received a copy of the GNU General Public License
19         along with this program.  If not, see <http://www.gnu.org/licenses/>.
20
21 **************************************************************************/
22
23 #include "seascene.h"
24 #include "octopus.h"
25 #include "ship.h"
26 #include <QGraphicsPixmapItem>
27 #include <QDebug>
28 #include <QMessageBox>
29 #include <QTime>
30 #include <QApplication>
31 #include <QAction>
32 #include <QPushButton>
33 #include <QLabel>
34 #include <QVBoxLayout>
35 #include <QSettings>
36 #include <QPixmap>
37
38 const QString ghostImageFilename_ = ":/pix/aave.png";
39 const QString rockImageFilename_ =":/pix/kari.png";
40 const QString octopusImageFilename_= ":/pix/tursas.png";
41
42
43 SeaScene::SeaScene(QObject *parent) :
44     QGraphicsScene(parent)
45 {
46
47     setItemPointersNull();
48
49     paused_ = false;
50     screenLitKeeper_.keepScreenLit(true);
51
52     //set background
53
54     QPixmap waves (":/pix/meri.png");
55     waves.scaled(20,20);
56     setBackgroundBrush(QBrush(waves));
57
58     //set random seed
59
60     qsrand(QTime::currentTime().msec()+2);  //+2 to avoid setting it to 1
61
62 //Setup the level list
63
64     QList<Level> levelList;
65     Level level1(5,10);
66     levelList.append(level1);
67     Level level2(5,10,2,50);
68     levelList.append(level2);
69     Level level3(5,15,2,50);
70     levelList.append(level3);
71     Level level4(5,15,4,50);
72     levelList.append(level4);
73     Level level5(5,15,5,100);
74     levelList.append(level5);
75
76     Levelset set ("Original",levelList);
77     levelset_ = set;
78
79     currentLevel_ = 0;
80
81     totalScore_ = 0;
82
83
84     connect(this,SIGNAL(allGhostsPicked()),this,SLOT(nextLevel()));
85
86
87     pVibrateAction_ = new QAction(tr("Vibration effects"),this);
88     pVibrateAction_->setCheckable(true);
89     connect(pVibrateAction_,SIGNAL(toggled(bool)),this,SLOT(vibrationActivate(bool)));
90     QSettings settings;
91     pVibrateAction_->setChecked(settings.value("vibration",false).toBool());
92
93
94     pPauseAction_ = new QAction(tr("Pause"),this);
95     pPauseAction_->setCheckable(true);
96     connect(pPauseAction_,SIGNAL(toggled(bool)),this,SLOT(pause(bool)));
97
98
99     deviceLockPollTimer_.setInterval(20*60);
100     connect(&deviceLockPollTimer_,SIGNAL(timeout()),this,SLOT(pollDeviceLocked()));
101     deviceLockPollTimer_.start();
102
103
104     autopauseTimer.setSingleShot(true);
105     autopauseTimer.setInterval(15*60*1000);
106     connect(&autopauseTimer,SIGNAL(timeout()),this,SLOT(turnPauseOn()));
107
108
109 }
110
111 void SeaScene::setupMap(int ghosts, int rocks, int octopuses, int octopusSpeed)
112 {
113     //empty the map
114
115     clear();
116
117     setItemPointersNull();
118
119     createMenuItems();
120
121     createAboutBoxItems();
122
123     createVictoryItems();
124
125     createLevelCompletedItem();
126
127
128     //empty the list of moving items
129
130     movingItems_.clear();
131
132     //empty the list of free slots
133     freeTiles_.clear();
134
135     //fill the list of free slots
136
137     int numberOfXTiles  = width() / 40;
138     int numberOfYTiles = height() /40;
139
140 //    qDebug() << numberOfXTiles << " slots in x direction";
141 //    qDebug() << numberOfYTiles << " slots in y rirection";
142
143     for (int i = 0; i < numberOfXTiles; i++ )
144     {
145         for (int j = 0; j < numberOfYTiles; j++)
146         {
147             freeTiles_.append(QPointF(i*40,j*40));
148         }
149     }
150
151
152     //spread the rocks
153
154     for (int i = 0; i < rocks; i++)
155     {
156         QPointF * pPosition = findRandomFreeSlot();
157
158         //If there was no room no point to continue
159         if (pPosition == NULL)
160             break;
161
162         QPixmap rockPixmap (":/pix/kari.png");
163         QGraphicsPixmapItem * pRock = addPixmap(rockPixmap);
164         pRock->setData(0,"rock");
165         pRock->setPos(*pPosition);
166         delete pPosition;
167
168     }
169
170     //spread the ghosts
171
172     ghostsLeft_ = ghosts;
173     spreadGhosts(ghosts);
174
175
176
177     //spread the octopuses
178
179     QList <Octopus*> octopusList;
180
181     for (int i=0; i < octopuses; i++)
182     {
183         QPointF * pPosition = findRandomFreeSlot();
184
185         //If there was no room no point to continue
186         if (pPosition == NULL)
187             break;
188
189     QPixmap octopusPixmap (":/pix/tursas.png");
190     Octopus * pOctopus = new Octopus(octopusPixmap,octopusSpeed);
191     pOctopus->setData(0,"octopus");
192     pOctopus->setPos(*pPosition);
193     addItem(pOctopus);
194     pOctopus->startMoving();
195     movingItems_.append(pOctopus);
196     connect(this,SIGNAL(pauseOn()),pOctopus,SLOT(stopMoving()));
197     connect(this,SIGNAL(pauseOff()),pOctopus,SLOT(startMoving()));
198     octopusList.append(pOctopus);
199     delete pPosition;
200
201     }
202
203
204     //place the ship
205
206     QPointF * pPosition = findRandomFreeSlot();
207     if (pPosition == NULL)
208     {
209         // Game cannot begin without a free position for ship, so give an error message and return
210
211         QMessageBox::critical(NULL,"Error! Too many objects on screen","No free space to place the ship. The game cannot start. Please choose another level.");
212         return;
213     }
214
215     QList<QPixmap> shipImages;
216     shipImages.append(QPixmap(":/pix/laiva.png"));
217     shipImages.append(QPixmap(":/pix/laiva_1aave.png"));
218     shipImages.append(QPixmap(":/pix/laiva_2aave.png"));
219     shipImages.append(QPixmap(":/pix/laiva_3aave.png"));
220     shipImages.append(QPixmap(":/pix/laiva_4aave.png"));
221     shipImages.append(QPixmap(":/pix/laiva_5aave.png"));
222     shipImages.append(QPixmap(":/pix/laiva_6aave.png"));
223     shipImages.append(QPixmap(":/pix/laiva_7aave.png"));
224     shipImages.append(QPixmap(":/pix/laiva_8aave.png"));
225     shipImages.append(QPixmap(":/pix/laiva_9aave.png"));
226     shipImages.append(QPixmap(":/pix/laiva_10aave.png"));
227
228     Ship * pShip = new Ship (shipImages);
229     pShip->setData(0,"ship");
230     pShip->setPos(*pPosition);
231     addItem(pShip);
232     connect(pShip,SIGNAL(pickingGhost(QGraphicsItem*)),this, SLOT(removeGhost(QGraphicsItem*)) );
233     connect(pShip,SIGNAL(droppingGhosts(int)),this,SLOT(ghostsDropped(int)));
234     connect(this,SIGNAL(vibrationActivated(bool)),pShip,SLOT(setVibrationActivate(bool)));
235     pShip->startMoving();
236     movingItems_.append(pShip);
237     connect(this,SIGNAL(pauseOn()),pShip,SLOT(stopMoving()));
238     connect(this,SIGNAL(pauseOff()),pShip,SLOT(startMoving()));
239     foreach (Octopus* pOctopus, octopusList)
240     {
241         connect(pOctopus,SIGNAL(droppingGhosts()),pShip,SLOT(dropAllGhosts()));
242     }
243     delete pPosition;
244 }
245
246 void SeaScene::setupMap(Level level)
247 {
248     setupMap(level.getNumberOfGhosts(),level.getNumberOfRocks(),level.getNumberOfOctopuses(),level.getOctopusSpeed());
249 }
250
251 void SeaScene::spreadGhosts(int ghosts)
252 {
253
254
255     //the octopuses and the ship may have moved from their original positions,
256     //so the list of free slots must be adjusted to exclude their current positions
257
258     QList<QPointF> temporarilyReservedSlots;
259
260     foreach (QGraphicsItem* pItem, movingItems_)
261     {
262         if (pItem == NULL)
263         {
264  //           qDebug() << "NULL item in movingItems_";
265             continue;
266         }
267
268         //round x and y down to fit the slot size
269         int x = pItem->x();
270         x = x/40;
271         x = x*40;
272
273         int y = pItem->y();
274         y = y/40;
275         y=y*40;
276
277
278         QPointF position (x,y);
279
280         //remove the tiles (potentially) occupied by the item from free slots and place in temp list if was in the list before
281
282         if (freeTiles_.removeOne(position))
283             temporarilyReservedSlots.append(position);
284
285
286         position.setX(x+40);
287
288         if (freeTiles_.removeOne(position))
289             temporarilyReservedSlots.append(position);
290
291         position.setY(y+40);
292
293         if (freeTiles_.removeOne(position))
294             temporarilyReservedSlots.append(position);
295
296         position.setX(x);
297
298         if (freeTiles_.removeOne(position))
299             temporarilyReservedSlots.append(position);
300
301     }
302
303
304     //spread ghosts in random free slots
305
306     for (int i=0; i < ghosts; i++)
307     {
308         QPointF * pPosition = findRandomFreeSlot();
309
310         //If there was no room no point to continue
311         if (pPosition == NULL)
312             return;
313
314         QPixmap ghostPixmap(":/pix/aave.png");
315         QGraphicsPixmapItem * pGhost = addPixmap(ghostPixmap);
316         pGhost->setData(0,"ghost");
317         pGhost->setPos(*pPosition);
318         delete pPosition;
319     }
320
321     //return the slots occupied by moving items to free slots
322     freeTiles_.append(temporarilyReservedSlots);
323
324     //clear temp for the next round
325     temporarilyReservedSlots.clear();
326 }
327
328 QPointF* SeaScene::findRandomFreeSlot()
329 {
330     if (freeTiles_.isEmpty())
331         return NULL;
332
333     int index = qrand()%freeTiles_.size();
334
335 //    qDebug()  << index << " index";
336     return new QPointF (freeTiles_.takeAt(index));
337
338 }
339
340 void SeaScene::removeGhost(QGraphicsItem *pGhost)
341 {
342     removeItem(pGhost);  //remove the item from scene
343     freeTiles_.append(pGhost->scenePos()); //add the item's position to free slots
344     delete pGhost;
345     ghostsLeft_--;
346     if (ghostsLeft_ == 0)
347     {
348         emit allGhostsPicked();
349  //       qDebug() << "All ghosts picked!";
350     }
351 }
352
353 void SeaScene::ghostsDropped(int ghosts)
354 {
355     ghostsLeft_ += ghosts;
356
357     spreadGhosts(ghosts);
358 }
359
360 void SeaScene::pause(bool paused)
361 {
362     //    qDebug() << "pause pressed " << paused;
363         if (paused_ == paused)
364                 return;
365
366         paused_ = paused;
367
368         if (paused == false)
369         {
370      //       qDebug() << "starting to move again";
371             emit fullscreenRequested();
372             emit pauseOff();
373             screenLitKeeper_.keepScreenLit(true);
374             if (pPausetextItem_)
375                 pPausetextItem_->hide();
376
377             scoreCounter_.start();
378
379             autopauseTimer.start(); //Start counting towards autopause
380             deviceLockPollTimer_.start(); //Start polling whether device is locked
381         }
382
383         else
384         {
385 //         qDebug("about to stop movement");
386             emit pauseOn();
387             screenLitKeeper_.keepScreenLit(false);
388             if (pPausetextItem_ != NULL)
389             {
390 //                qDebug() << "about to show the pause text";
391                 pPausetextItem_->show();
392 //                qDebug() << "showing pause text";
393             }
394 //                else qDebug() << "No pause text available";
395
396             levelScore_ += scoreCounter_.elapsed();
397
398             autopauseTimer.stop(); //No need to count toward autopause when already paused
399             deviceLockPollTimer_.stop(); //No need to check for unlock as no unpause anyway
400         }
401 }
402
403 void SeaScene::vibrationActivate(bool on)
404 {
405     emit vibrationActivated(on);
406 }
407
408 void SeaScene::handleScreenTapped()
409 {
410
411     //If the game is going just pause it
412     if (!paused_)
413     {
414         pPauseAction_->setChecked(true);
415         return;
416     }
417
418     //If the game is paused and about box is shown, close it and show the pause text and menu again
419
420     if(pAboutBoxItem_)
421     {
422         if(pAboutBoxItem_->isVisible())
423         {
424             pAboutBoxItem_->hide();
425             pPausetextItem_->show();
426             return;
427         }
428     }
429
430     //If the game is paused, check if the level completed item is shown
431
432     if (pLevelCompletedItem_)
433     {
434         if (pLevelCompletedItem_->isVisible())
435         {
436             pLevelCompletedItem_->hide();
437             restartLevel(); //Current level has already been set to the next one before showing the level completed item
438             pPauseAction_->setChecked(false); //unpause
439             return;
440         }
441     }
442   
443     //If the game is paused, check if the victory item is being shown
444     if(pVictoryCongratulationsItem_)
445     {
446         if (pVictoryCongratulationsItem_->isVisibleTo(NULL)) //returns visibility to scene
447         {
448             pVictoryCongratulationsItem_->hide();
449             restartGame();
450             pPauseAction_->setChecked(false); // unpause
451             return;
452         }
453     }
454
455
456     //If the game is paused and no victory, check if menu item was selected
457
458     QList<QGraphicsItem *> items = selectedItems();
459
460     //if nothing selected resume play
461
462     if (items.isEmpty())
463     {
464         pPauseAction_->setChecked(false);
465         return;
466
467     }
468
469     //If something was selected check if it was one of the menu items and act on it
470     //(Nothing else should be made selectable anyway)
471
472     //Menu functions
473
474     QGraphicsItem* pItem = items.at(0); //Selecting an item brings here, thus only selecting one item should be possible
475                                        //... so we can just take the first one
476
477     //Selection is just used to get notice of a menu item being clicked, removed after use
478
479     clearSelection();
480
481
482     //Act upon the selected item
483
484
485     if (pItem == pRestartGameItem_)
486     {
487 //        qDebug() << "game restart requested";
488         restartGame();
489         pPauseAction_->setChecked(false); //unpause game
490
491     }
492
493     else if (pItem == pRestartLevelItem_)
494     {
495 //        qDebug() << "Level restart requested";
496         restartLevel();
497         pPauseAction_->setChecked(false); //unpause game
498
499     }
500
501     else if (pItem == pSettingsItem_)
502     {
503         pVibrateAction_->toggle();
504
505         QSettings settings;
506         settings.setValue("vibration",pVibrateAction_->isChecked());
507
508         QString text = pSettingsItem_->toHtml();
509         if (pVibrateAction_->isChecked())
510             text.replace(" on"," off"); //don't remove spaces or you get vibratioff...
511         else
512             text.replace(" off"," on");
513         pSettingsItem_->setHtml(text);
514     }
515
516     else if (pItem == pAboutItem_)
517     {
518         about();
519     }
520
521     else if(pItem == pMinimizeItem_)
522     {
523         emit minimizeRequested();
524     }
525
526     else if (pItem == pQuitItem_)
527     {
528         qApp->quit();
529     }
530 }
531
532
533
534 void SeaScene::createMenuItems()
535 {
536
537     QFont font;
538     font.setPixelSize(35);
539
540
541
542     pPausetextItem_ = new QGraphicsTextItem;
543     pPausetextItem_->setHtml("<font size = \"5\" color = darkorange> Game paused. Tap to continue.");
544     pPausetextItem_->setZValue(1000);
545     pPausetextItem_->setPos(165,50);
546     addItem(pPausetextItem_);
547     pPausetextItem_->hide();
548
549     menuItemCount_ = 0;
550
551     QString menufonthtml = "<font size = \"4\" color = darkorange>";
552
553     pRestartGameItem_ = new QGraphicsTextItem;
554     pRestartGameItem_->setHtml(tr("Restart <br> game").prepend(menufonthtml));
555     prepareForMenu(pRestartGameItem_);
556
557     pRestartLevelItem_ = new QGraphicsTextItem;
558     pRestartLevelItem_->setHtml(tr("Restart <br> level").prepend(menufonthtml));
559     prepareForMenu(pRestartLevelItem_);
560
561     pSettingsItem_ = new QGraphicsTextItem;
562     QString vibraText(tr("Turn vibration <br> effects "));
563     QString statusText;
564     if (pVibrateAction_->isChecked())
565     {
566         statusText = "off";
567     }
568     else
569     {
570         statusText = "on";
571     }
572     vibraText.append(statusText);
573     pSettingsItem_->setHtml(vibraText.prepend(menufonthtml));
574     prepareForMenu(pSettingsItem_);
575
576     pAboutItem_ = new QGraphicsTextItem;
577     pAboutItem_->setHtml(tr("About <br> game").prepend(menufonthtml));
578     prepareForMenu(pAboutItem_);
579
580     pMinimizeItem_ = new QGraphicsTextItem;
581     pMinimizeItem_->setHtml(tr("Show <br> status bar").prepend(menufonthtml));
582     prepareForMenu(pMinimizeItem_);
583
584     pQuitItem_ = new QGraphicsTextItem;
585     pQuitItem_->setHtml(tr("Quit <br> game").prepend(menufonthtml));
586     prepareForMenu(pQuitItem_);
587
588 }
589
590 void SeaScene::prepareForMenu(QGraphicsItem * pItem)
591 {
592
593     //Menu items have pause text item as their parent and are thus added to scene automatically
594     //They are also shown and hidden with it, resulting in the menu being visble when the game is paused
595     //Their coordinates are given relative to the parent.
596
597
598
599
600     int itemsPerRow = 3;
601
602     pItem->setParentItem(pPausetextItem_);
603     pItem->setZValue(1000);
604     pItem->setFlag(QGraphicsItem::ItemIsSelectable);
605
606     int row = menuItemCount_/(itemsPerRow);
607     pItem->setY(150+row*120);
608     pItem->setX(((menuItemCount_%(itemsPerRow))*180+5));
609
610     menuItemCount_++;
611  }
612
613
614 void SeaScene::about()
615 {
616     pPausetextItem_->hide();
617     pAboutBoxItem_->show();
618 }
619
620
621 void SeaScene::restartLevel()
622 {
623
624     levelScore_ = 0;
625
626     setupMap(levelset_.getLevel(currentLevel_));  //getLevel() returns default constructor Level if index is invalid, so no risk of crash
627
628     scoreCounter_.start();
629
630     vibrationActivate(pVibrateAction_->isChecked());  //Vibration effects are lost without this
631    // qDebug() << pVibrateAction_->isChecked();
632     autopauseTimer.start();  //reset counting towards autopause
633
634
635 }
636
637
638
639 void SeaScene::nextLevel()
640 {
641
642     //get score for previous level
643     levelScore_ += scoreCounter_.elapsed();
644     totalScore_ += levelScore_;
645     int highscore = levelset_.getLevelHighScore(currentLevel_);
646     qDebug() << highscore;
647
648     QString scoretext;
649
650     if (levelScore_ >= highscore)
651     {
652         scoretext = tr("<font size=\"5\" color = darkorange>Your time: %1.%2 s<br>Best time: %3.%4 s<br><br>Tap to start the next level").arg(levelScore_/1000).arg((levelScore_%1000)/100).arg(highscore/1000).arg((highscore%1000)/100);
653     }
654
655     else //New high score!
656
657     {
658         scoretext = tr("<font size=\"5\" color = darkorange>Your time %1.%2 s is the new best time!<br>br> Tap to start the next level").arg(levelScore_/1000).arg((levelScore_%1000)/100);
659         levelset_.setLevelHighScore(currentLevel_,levelScore_);
660     }
661
662     //pause to show the highscore or victory screen
663
664     turnPauseOn();
665     pPausetextItem_->hide();
666
667
668     //Go to the next level if available
669     currentLevel_++;
670
671     if ( currentLevel_ < levelset_.numberOfLevels() )
672     {
673        pLevelCompletedItem_->setHtml(scoretext);
674        pLevelCompletedItem_->show();
675 //       restartLevel();
676     }
677
678     else //Victory!
679     {
680         pVictoryCongratulationsItem_->show();
681     }
682 }
683
684
685 void SeaScene::restartGame()
686 {
687     currentLevel_ = 0;
688     totalScore_ = 0;
689     restartLevel();
690 }
691
692
693 void SeaScene::forcePause()
694 {
695     //Pause without setting the pause action state
696     pause(true);
697 }
698
699 void SeaScene::softContinue()
700 {
701     //Continue if not being paused by the user
702     // Reverts forcePause()
703
704     pause(pPauseAction_->isChecked());
705 }
706
707
708 void SeaScene::createVictoryItems()
709 {
710     pVictoryCongratulationsItem_ = new QGraphicsTextItem;
711     pVictoryCongratulationsItem_->setHtml("<font size=\"6\" color = darkorange> Victory!");
712     pVictoryCongratulationsItem_->hide();
713     pVictoryCongratulationsItem_->setPos(355,50);
714     pVictoryCongratulationsItem_->setZValue(1000);
715     addItem(pVictoryCongratulationsItem_);
716
717
718     //coordinates are relative to the parent
719
720     QGraphicsTextItem * pTextItem = new QGraphicsTextItem(pVictoryCongratulationsItem_);
721     pTextItem->setHtml("<font size=\"5\" color = darkorange> Congratulations!");
722     pTextItem->setPos(-50,100);
723     pTextItem->setZValue(1000);
724
725     QGraphicsTextItem * pMiddleTextItem = new QGraphicsTextItem(pVictoryCongratulationsItem_);
726     pMiddleTextItem->setHtml("<font size=\"5\" color = darkorange> You have saved all the ghosts.");
727     pMiddleTextItem->setPos(-145,140);
728     pMiddleTextItem->setZValue(1000);
729
730     QGraphicsTextItem * pLowestTextItem = new QGraphicsTextItem(pVictoryCongratulationsItem_);
731     pLowestTextItem->setHtml("<font size=\"5\" color = darkorange> Tap to play again");
732     pLowestTextItem->setPos(-50,220);
733     pLowestTextItem->setZValue(1000);
734 }
735
736 void SeaScene::createAboutBoxItems()
737 {
738     pAboutBoxItem_ = new QGraphicsTextItem;
739     addItem(pAboutBoxItem_);
740     pAboutBoxItem_->setPos(25,50);
741     pAboutBoxItem_->setZValue(1000);
742     pAboutBoxItem_->hide();
743
744     pAboutBoxItem_->setHtml(tr("<font color = darkorange size = \"7\">"
745                           "%1 <br> <font size = \"5\"> Version %2"
746                           "<p><font size = \"4\"> Copyright 2011 Heli Hyv&auml;ttinen"
747                           "<p><font size = \"4\"> License: General Public License v2"
748                           "<p><font size = \"3\"> Web: http://ghostsoverboard.garage.maemo.org/<br>"
749                           "Bug Reports: <br> https://bugs.maemo.org/"
750                           "enter_bug.cgi?product=Ghosts%20Overboard"
751                           ).arg(QApplication::applicationName(),QApplication::applicationVersion()));
752
753 }
754
755 void SeaScene::setItemPointersNull()
756 {
757     pPausetextItem_ = NULL;
758     pRestartLevelItem_ = NULL;
759     pRestartGameItem_ = NULL;
760     pSettingsItem_ = NULL;
761     pAboutItem_ = NULL;
762     pQuitItem_ = NULL ;
763     pMinimizeItem_ = NULL;
764
765     pAboutBoxItem_ = NULL;
766     pVictoryCongratulationsItem_ = NULL;
767     pLevelCompletedItem_ = NULL;
768
769
770 }
771
772 void SeaScene::turnPauseOn()
773 {
774     pPauseAction_->setChecked(true);
775 }
776
777 void SeaScene::handleDeviceLocked(bool isLocked)
778 {
779     //pauses if locked but does not unpause if unlocked
780     if(isLocked)
781     {
782         pPauseAction_->setChecked(true);
783     }
784 }
785
786 void SeaScene::pollDeviceLocked()
787 {
788
789     bool locked = deviceInfo_.isDeviceLocked();
790
791     if (locked)
792     {
793         if (!alreadyLocked_)
794         {
795             pPauseAction_->setChecked(true);
796             alreadyLocked_ = true;
797         }
798
799     else
800         {
801             alreadyLocked_ = false;
802         }
803     }
804 }
805
806 void SeaScene::createLevelCompletedItem()
807 {
808     pLevelCompletedItem_ = new QGraphicsTextItem;
809     addItem(pLevelCompletedItem_);
810     pLevelCompletedItem_->setPos(20,20);
811     pLevelCompletedItem_->setZValue(1000);
812     pLevelCompletedItem_->hide();
813     //The text is set at usetime
814
815 }