Removed obsolete include
[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
31 const QString ghostImageFilename_ = ":/pix/aave.png";
32 const QString rockImageFilename_ =":/pix/kari.png";
33 const QString octopusImageFilename_= ":/pix/tursas.png";
34
35
36 SeaScene::SeaScene(QObject *parent) :
37     QGraphicsScene(parent)
38 {
39     paused_ = false;
40     screenLitKeeper_.keepScreenLit(true);
41
42     //set background
43
44     QPixmap waves (":/pix/meri.png");
45     waves.scaled(20,20);
46     setBackgroundBrush(QBrush(waves));
47
48     //set random seed
49
50     qsrand(QTime::currentTime().msec()+2);  //+2 to avoid setting it to 1
51
52
53
54 }
55
56 void SeaScene::setupMap(int ghosts, int rocks, int octopuses)
57 {
58     //empty the map
59
60     clear();
61
62     //empty the list of moving items
63
64     movingItems_.clear();
65
66     //empty the list of free slots
67     freeTiles_.clear();
68
69     //fill the list of free slots
70
71     int numberOfXTiles  = width() / 40;
72     int numberOfYTiles = height() /40;
73
74 //    qDebug() << numberOfXTiles << " slots in x direction";
75 //    qDebug() << numberOfYTiles << " slots in y rirection";
76
77     for (int i = 0; i < numberOfXTiles; i++ )
78     {
79         for (int j = 0; j < numberOfYTiles; j++)
80         {
81             freeTiles_.append(QPointF(i*40,j*40));
82         }
83     }
84
85
86     //spread the rocks
87
88     for (int i = 0; i < rocks; i++)
89     {
90         QPointF * pPosition = findRandomFreeSlot();
91
92         //If there was no room no point to continue
93         if (pPosition == NULL)
94             break;
95
96         QPixmap rockPixmap (":/pix/kari.png");
97         QGraphicsPixmapItem * pRock = addPixmap(rockPixmap);
98         pRock->setData(0,"rock");
99         pRock->setPos(*pPosition);
100         delete pPosition;
101
102     }
103
104     //spread the ghosts
105
106     ghostsLeft_ = ghosts;
107     spreadGhosts(ghosts);
108
109
110
111     //spread the octopuses
112
113     QList <Octopus*> octopusList;
114
115     for (int i=0; i < octopuses; i++)
116     {
117         QPointF * pPosition = findRandomFreeSlot();
118
119         //If there was no room no point to continue
120         if (pPosition == NULL)
121             break;
122
123     QPixmap octopusPixmap (":/pix/tursas.png");
124     Octopus * pOctopus = new Octopus(octopusPixmap,100);
125     pOctopus->setData(0,"octopus");
126     pOctopus->setPos(*pPosition);
127     addItem(pOctopus);
128     pOctopus->startMoving();
129     movingItems_.append(pOctopus);
130     connect(this,SIGNAL(pauseOn()),pOctopus,SLOT(stopMoving()));
131     connect(this,SIGNAL(pauseOff()),pOctopus,SLOT(startMoving()));
132     octopusList.append(pOctopus);
133     delete pPosition;
134
135     }
136
137
138     //place the ship
139
140     QPointF * pPosition = findRandomFreeSlot();
141     if (pPosition == NULL)
142     {
143         // Game cannot begin without a free position for ship, so give an error message and return
144
145         QMessageBox::critical(NULL,"Error! Too many objects on screen","No free space to place the ship. The game cannot start. Please choose another level.");
146         return;
147     }
148
149     QList<QPixmap> shipImages;
150     shipImages.append(QPixmap(":/pix/laiva.png"));
151     shipImages.append(QPixmap(":/pix/laiva_1aave.png"));
152     shipImages.append(QPixmap(":/pix/laiva_2aave.png"));
153     shipImages.append(QPixmap(":/pix/laiva_3aave.png"));
154     shipImages.append(QPixmap(":/pix/laiva_4aave.png"));
155     shipImages.append(QPixmap(":/pix/laiva_5aave.png"));
156     shipImages.append(QPixmap(":/pix/laiva_6aave.png"));
157     shipImages.append(QPixmap(":/pix/laiva_7aave.png"));
158     shipImages.append(QPixmap(":/pix/laiva_8aave.png"));
159     shipImages.append(QPixmap(":/pix/laiva_9aave.png"));
160     shipImages.append(QPixmap(":/pix/laiva_10aave.png"));
161
162     Ship * pShip = new Ship (shipImages);
163     pShip->setData(0,"ship");
164     pShip->setPos(*pPosition);
165     addItem(pShip);
166     connect(pShip,SIGNAL(pickingGhost(QGraphicsItem*)),this, SLOT(removeGhost(QGraphicsItem*)) );
167     connect(pShip,SIGNAL(droppingGhosts(int)),this,SLOT(ghostsDropped(int)));
168     pShip->startMoving();
169     movingItems_.append(pShip);
170     connect(this,SIGNAL(pauseOn()),pShip,SLOT(stopMoving()));
171     connect(this,SIGNAL(pauseOff()),pShip,SLOT(startMoving()));
172     foreach (Octopus* pOctopus, octopusList)
173     {
174         connect(pOctopus,SIGNAL(droppingGhosts()),pShip,SLOT(dropAllGhosts()));
175     }
176     delete pPosition;
177 }
178
179
180 void SeaScene::spreadGhosts(int ghosts)
181 {
182
183
184     //the octopuses and the ship may have moved from their original positions,
185     //so the list of free slots must be adjusted to exclude their current positions
186
187     QList<QPointF> temporarilyReservedSlots;
188
189     foreach (QGraphicsItem* pItem, movingItems_)
190     {
191         if (pItem == NULL)
192         {
193  //           qDebug() << "NULL item in movingItems_";
194             continue;
195         }
196
197         //round x and y down to fit the slot size
198         int x = pItem->x();
199         x = x/40;
200         x = x*40;
201
202         int y = pItem->y();
203         y = y/40;
204         y=y*40;
205
206
207         QPointF position (x,y);
208
209         //remove the tiles (potentially) occupied by the item from free slots and place in temp list if was in the list before
210
211         if (freeTiles_.removeOne(position))
212             temporarilyReservedSlots.append(position);
213
214
215         position.setX(x+40);
216
217         if (freeTiles_.removeOne(position))
218             temporarilyReservedSlots.append(position);
219
220         position.setY(y+40);
221
222         if (freeTiles_.removeOne(position))
223             temporarilyReservedSlots.append(position);
224
225         position.setX(x);
226
227         if (freeTiles_.removeOne(position))
228             temporarilyReservedSlots.append(position);
229
230     }
231
232
233     //spread ghosts in random free slots
234
235     for (int i=0; i < ghosts; i++)
236     {
237         QPointF * pPosition = findRandomFreeSlot();
238
239         //If there was no room no point to continue
240         if (pPosition == NULL)
241             return;
242
243         QPixmap ghostPixmap(":/pix/aave.png");
244         QGraphicsPixmapItem * pGhost = addPixmap(ghostPixmap);
245         pGhost->setData(0,"ghost");
246         pGhost->setPos(*pPosition);
247         delete pPosition;
248     }
249
250     //return the slots occupied by moving items to free slots
251     freeTiles_.append(temporarilyReservedSlots);
252
253     //clear temp for the next round
254     temporarilyReservedSlots.clear();
255 }
256
257 QPointF* SeaScene::findRandomFreeSlot()
258 {
259     if (freeTiles_.isEmpty())
260         return NULL;
261
262     int index = qrand()%freeTiles_.size();
263
264 //    qDebug()  << index << " index";
265     return new QPointF (freeTiles_.takeAt(index));
266
267 }
268
269 void SeaScene::removeGhost(QGraphicsItem *pGhost)
270 {
271     removeItem(pGhost);  //remove the item from scene
272     freeTiles_.append(pGhost->scenePos()); //add the item's position to free slots
273     delete pGhost;
274     ghostsLeft_--;
275     if (ghostsLeft_ == 0)
276     {
277         emit allGhostsPicked();
278  //       qDebug() << "All ghosts picked!";
279     }
280 }
281
282 void SeaScene::ghostsDropped(int ghosts)
283 {
284     ghostsLeft_ += ghosts;
285
286     spreadGhosts(ghosts);
287 }
288
289 void SeaScene::pause(bool paused)
290 {
291     //    qDebug() << "pause pressed " << paused;
292         if (paused_ == paused)
293                 return;
294
295         paused_ = paused;
296
297         if (paused == false)
298         {
299      //       qDebug() << "starting to move again";
300             emit pauseOff();
301             screenLitKeeper_.keepScreenLit(true);
302         }
303
304         else
305         {
306      //       qDebug("about to stop movement");
307             emit pauseOn();
308             screenLitKeeper_.keepScreenLit(false);
309         }
310 }