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