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