Highscore strored as milliseconds instead of seconds
[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     scoreCounter_.start();
246
247
248 }
249
250 void SeaScene::setupMap(Level level)
251 {
252     setupMap(level.getNumberOfGhosts(),level.getNumberOfRocks(),level.getNumberOfOctopuses(),level.getOctopusSpeed());
253 }
254
255 void SeaScene::spreadGhosts(int ghosts)
256 {
257
258
259     //the octopuses and the ship may have moved from their original positions,
260     //so the list of free slots must be adjusted to exclude their current positions
261
262     QList<QPointF> temporarilyReservedSlots;
263
264     foreach (QGraphicsItem* pItem, movingItems_)
265     {
266         if (pItem == NULL)
267         {
268  //           qDebug() << "NULL item in movingItems_";
269             continue;
270         }
271
272         //round x and y down to fit the slot size
273         int x = pItem->x();
274         x = x/40;
275         x = x*40;
276
277         int y = pItem->y();
278         y = y/40;
279         y=y*40;
280
281
282         QPointF position (x,y);
283
284         //remove the tiles (potentially) occupied by the item from free slots and place in temp list if was in the list before
285
286         if (freeTiles_.removeOne(position))
287             temporarilyReservedSlots.append(position);
288
289
290         position.setX(x+40);
291
292         if (freeTiles_.removeOne(position))
293             temporarilyReservedSlots.append(position);
294
295         position.setY(y+40);
296
297         if (freeTiles_.removeOne(position))
298             temporarilyReservedSlots.append(position);
299
300         position.setX(x);
301
302         if (freeTiles_.removeOne(position))
303             temporarilyReservedSlots.append(position);
304
305     }
306
307
308     //spread ghosts in random free slots
309
310     for (int i=0; i < ghosts; i++)
311     {
312         QPointF * pPosition = findRandomFreeSlot();
313
314         //If there was no room no point to continue
315         if (pPosition == NULL)
316             return;
317
318         QPixmap ghostPixmap(":/pix/aave.png");
319         QGraphicsPixmapItem * pGhost = addPixmap(ghostPixmap);
320         pGhost->setData(0,"ghost");
321         pGhost->setPos(*pPosition);
322         delete pPosition;
323     }
324
325     //return the slots occupied by moving items to free slots
326     freeTiles_.append(temporarilyReservedSlots);
327
328     //clear temp for the next round
329     temporarilyReservedSlots.clear();
330 }
331
332 QPointF* SeaScene::findRandomFreeSlot()
333 {
334     if (freeTiles_.isEmpty())
335         return NULL;
336
337     int index = qrand()%freeTiles_.size();
338
339 //    qDebug()  << index << " index";
340     return new QPointF (freeTiles_.takeAt(index));
341
342 }
343
344 void SeaScene::removeGhost(QGraphicsItem *pGhost)
345 {
346     removeItem(pGhost);  //remove the item from scene
347     freeTiles_.append(pGhost->scenePos()); //add the item's position to free slots
348     delete pGhost;
349     ghostsLeft_--;
350     if (ghostsLeft_ == 0)
351     {
352         emit allGhostsPicked();
353  //       qDebug() << "All ghosts picked!";
354     }
355 }
356
357 void SeaScene::ghostsDropped(int ghosts)
358 {
359     ghostsLeft_ += ghosts;
360
361     spreadGhosts(ghosts);
362 }
363
364 void SeaScene::pause(bool paused)
365 {
366     //    qDebug() << "pause pressed " << paused;
367         if (paused_ == paused)
368                 return;
369
370         paused_ = paused;
371
372         if (paused == false)
373         {
374      //       qDebug() << "starting to move again";
375             emit fullscreenRequested();
376             emit pauseOff();
377             screenLitKeeper_.keepScreenLit(true);
378             if (pPausetextItem_)
379                 pPausetextItem_->hide();
380
381             autopauseTimer.start(); //Start counting towards autopause
382             deviceLockPollTimer_.start(); //Start polling whether device is locked
383         }
384
385         else
386         {
387 //         qDebug("about to stop movement");
388             emit pauseOn();
389             screenLitKeeper_.keepScreenLit(false);
390             if (pPausetextItem_ != NULL)
391             {
392 //                qDebug() << "about to show the pause text";
393                 pPausetextItem_->show();
394 //                qDebug() << "showing pause text";
395             }
396 //                else qDebug() << "No pause text available";
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     setupMap(levelset_.getLevel(currentLevel_));  //getLevel() returns default constructor Level if index is invalid, so no risk of crash
624     vibrationActivate(pVibrateAction_->isChecked());  //Vibration effects are lost without this
625    // qDebug() << pVibrateAction_->isChecked();
626     autopauseTimer.start();  //reset counting towards autopause
627 }
628
629
630
631 void SeaScene::nextLevel()
632 {
633
634     //get score for previous level
635     int score = scoreCounter_.elapsed();
636     totalScore_ += score;
637     int highscore = levelset_.getLevelHighScore(currentLevel_);
638     qDebug() << highscore;
639
640     QString scoretext;
641
642     if (score >= highscore)
643     {
644         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(score/1000).arg((score%1000)/100).arg(highscore/1000).arg((highscore%1000)/100);
645     }
646
647     else //New high score!
648
649     {
650         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(score/1000).arg((score%1000)/100);
651         levelset_.setLevelHighScore(currentLevel_,score);
652     }
653
654     //pause to show the highscore or victory screen
655
656     turnPauseOn();
657     pPausetextItem_->hide();
658
659
660     //Go to the next level if available
661     currentLevel_++;
662
663     if ( currentLevel_ < levelset_.numberOfLevels() )
664     {
665        pLevelCompletedItem_->setHtml(scoretext);
666        pLevelCompletedItem_->show();
667 //       restartLevel();
668     }
669
670     else //Victory!
671     {
672         pVictoryCongratulationsItem_->show();
673     }
674 }
675
676
677 void SeaScene::restartGame()
678 {
679     currentLevel_ = 0;
680     totalScore_ = 0;
681     restartLevel();
682 }
683
684
685 void SeaScene::forcePause()
686 {
687     //Pause without setting the pause action state
688     pause(true);
689 }
690
691 void SeaScene::softContinue()
692 {
693     //Continue if not being paused by the user
694     // Reverts forcePause()
695
696     pause(pPauseAction_->isChecked());
697 }
698
699
700 void SeaScene::createVictoryItems()
701 {
702     pVictoryCongratulationsItem_ = new QGraphicsTextItem;
703     pVictoryCongratulationsItem_->setHtml("<font size=\"6\" color = darkorange> Victory!");
704     pVictoryCongratulationsItem_->hide();
705     pVictoryCongratulationsItem_->setPos(355,50);
706     pVictoryCongratulationsItem_->setZValue(1000);
707     addItem(pVictoryCongratulationsItem_);
708
709
710     //coordinates are relative to the parent
711
712     QGraphicsTextItem * pTextItem = new QGraphicsTextItem(pVictoryCongratulationsItem_);
713     pTextItem->setHtml("<font size=\"5\" color = darkorange> Congratulations!");
714     pTextItem->setPos(-50,100);
715     pTextItem->setZValue(1000);
716
717     QGraphicsTextItem * pMiddleTextItem = new QGraphicsTextItem(pVictoryCongratulationsItem_);
718     pMiddleTextItem->setHtml("<font size=\"5\" color = darkorange> You have saved all the ghosts.");
719     pMiddleTextItem->setPos(-145,140);
720     pMiddleTextItem->setZValue(1000);
721
722     QGraphicsTextItem * pLowestTextItem = new QGraphicsTextItem(pVictoryCongratulationsItem_);
723     pLowestTextItem->setHtml("<font size=\"5\" color = darkorange> Tap to play again");
724     pLowestTextItem->setPos(-50,220);
725     pLowestTextItem->setZValue(1000);
726 }
727
728 void SeaScene::createAboutBoxItems()
729 {
730     pAboutBoxItem_ = new QGraphicsTextItem;
731     addItem(pAboutBoxItem_);
732     pAboutBoxItem_->setPos(25,50);
733     pAboutBoxItem_->setZValue(1000);
734     pAboutBoxItem_->hide();
735
736     pAboutBoxItem_->setHtml(tr("<font color = darkorange size = \"7\">"
737                           "%1 <br> <font size = \"5\"> Version %2"
738                           "<p><font size = \"4\"> Copyright 2011 Heli Hyv&auml;ttinen"
739                           "<p><font size = \"4\"> License: General Public License v2"
740                           "<p><font size = \"3\"> Web: http://ghostsoverboard.garage.maemo.org/<br>"
741                           "Bug Reports: <br> https://bugs.maemo.org/"
742                           "enter_bug.cgi?product=Ghosts%20Overboard"
743                           ).arg(QApplication::applicationName(),QApplication::applicationVersion()));
744
745 }
746
747 void SeaScene::setItemPointersNull()
748 {
749     pPausetextItem_ = NULL;
750     pRestartLevelItem_ = NULL;
751     pRestartGameItem_ = NULL;
752     pSettingsItem_ = NULL;
753     pAboutItem_ = NULL;
754     pQuitItem_ = NULL ;
755     pMinimizeItem_ = NULL;
756
757     pAboutBoxItem_ = NULL;
758     pVictoryCongratulationsItem_ = NULL;
759     pLevelCompletedItem_ = NULL;
760
761
762 }
763
764 void SeaScene::turnPauseOn()
765 {
766     pPauseAction_->setChecked(true);
767 }
768
769 void SeaScene::handleDeviceLocked(bool isLocked)
770 {
771     //pauses if locked but does not unpause if unlocked
772     if(isLocked)
773     {
774         pPauseAction_->setChecked(true);
775     }
776 }
777
778 void SeaScene::pollDeviceLocked()
779 {
780
781     bool locked = deviceInfo_.isDeviceLocked();
782
783     if (locked)
784     {
785         if (!alreadyLocked_)
786         {
787             pPauseAction_->setChecked(true);
788             alreadyLocked_ = true;
789         }
790
791     else
792         {
793             alreadyLocked_ = false;
794         }
795     }
796 }
797
798 void SeaScene::createLevelCompletedItem()
799 {
800     pLevelCompletedItem_ = new QGraphicsTextItem;
801     addItem(pLevelCompletedItem_);
802     pLevelCompletedItem_->setPos(20,20);
803     pLevelCompletedItem_->setZValue(1000);
804     pLevelCompletedItem_->hide();
805     //The text is set at usetime
806
807 }