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