b6ba59be8e469dcad0d11ec52c5c7d147ac3b07b
[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
8 const QString ghostImageFilename_ = ":/pix/aave.png";
9 const QString rockImageFilename_ =":/pix/kari.png";
10 const QString octopusImageFilename_= ":/pix/tursas.png";
11
12
13 SeaScene::SeaScene(QObject *parent) :
14     QGraphicsScene(parent)
15 {
16
17
18 }
19
20 void SeaScene::setupMap(int ghosts, int rocks, int octopuses)
21 {
22     //empty the map
23
24     clear();
25
26     //empty the list of moving items
27
28     movingItems_.clear();
29
30     //empty the list of free slots
31     freeTiles_.clear();
32
33     //fill the list of free slots
34
35     int numberOfXTiles  = width() / 40;
36     int numberOfYTiles = height() /40;
37
38     qDebug() << numberOfXTiles << " slots in x direction";
39     qDebug() << numberOfYTiles << " slots in y rirection";
40
41     for (int i = 0; i < numberOfXTiles; i++ )
42     {
43         for (int j = 0; j < numberOfYTiles; j++)
44         {
45             freeTiles_.append(QPointF(i*40,j*40));
46         }
47     }
48
49
50     //spread the rocks
51
52     for (int i = 0; i < rocks; i++)
53     {
54         QPointF * pPosition = findRandomFreeSlot();
55
56         qDebug() << "Found a place for a rock";
57
58         //If there was no room no point to continue
59         if (pPosition == NULL)
60             break;
61
62         QPixmap rockPixmap (":/pix/kari.png");
63         QGraphicsPixmapItem * pRock = addPixmap(rockPixmap);
64         pRock->setData(0,"rock");
65         pRock->setPos(*pPosition);
66         delete pPosition;
67
68     }
69
70     //spread the ghosts
71
72     ghostsLeft_ = ghosts;
73     spreadGhosts(ghosts);
74
75
76
77     //spread the octopuses
78
79
80     for (int i=0; i < octopuses; i++)
81     {
82         QPointF * pPosition = findRandomFreeSlot();
83
84         //If there was no room no point to continue
85         if (pPosition == NULL)
86             break;
87
88     QPixmap octopusPixmap (":/pix/tursas.png");
89     TimerControlledTursas * pOctopus = new TimerControlledTursas (octopusPixmap,100);
90     pOctopus->setData(0,"octopus");
91     pOctopus->setPos(*pPosition);
92     addItem(pOctopus);
93     pOctopus->startMoving();
94     movingItems_.append(pOctopus);
95     delete pPosition;
96
97     }
98
99
100     //place the ship
101
102     QPointF * pPosition = findRandomFreeSlot();
103     if (pPosition == NULL)
104     {
105         // Game cannot begin without a free position for ship, so give an error message and return
106
107         QMessageBox::critical(NULL,"Error! Too many objects on screen","No free space to place the ship. The game cannot start. Please choose another level.");
108         return;
109     }
110
111     Ship * pShip = new Ship (QPixmap(":/pix/laiva.png"));
112     pShip->setData(0,"ship");
113     pShip->setPos(*pPosition);
114     addItem(pShip);
115     connect(pShip,SIGNAL(pickingGhost(QGraphicsItem*)),this, SLOT(removeGhost(QGraphicsItem*)) );
116     connect(pShip,SIGNAL(droppingGhosts(int)),this,SLOT(ghostsDropped(int)));
117     pShip->startMoving();
118     movingItems_.append(pShip);
119     delete pPosition;
120 }
121
122
123 void SeaScene::spreadGhosts(int ghosts)
124 {
125
126     qDebug() << "Preparing to spread ghosts";
127
128     //the octopuses and the ship may have moved from their original positions,
129     //so the list of free slots must be adjusted to exclude their current positions
130
131     QList<QPointF> temporarilyReservedSlots;
132
133     foreach (QGraphicsItem* pItem, movingItems_)
134     {
135         if (pItem == NULL)
136         {
137  //           qDebug() << "NULL item in movingItems_";
138             continue;
139         }
140
141         //round x and y down to fit the slot size
142         int x = pItem->x();
143         x = x/40;
144         x = x*40;
145
146         int y = pItem->y();
147         y = y/40;
148         y=y*40;
149
150
151         QPointF position (x,y);
152
153         //remove the tiles (potentially) occupied by the item from free slots and place in temp list if was in the list before
154
155         if (freeTiles_.removeOne(position))
156             temporarilyReservedSlots.append(position);
157
158
159         position.setX(x+40);
160
161         if (freeTiles_.removeOne(position))
162             temporarilyReservedSlots.append(position);
163
164         position.setY(y+40);
165
166         if (freeTiles_.removeOne(position))
167             temporarilyReservedSlots.append(position);
168
169         position.setX(x);
170
171         if (freeTiles_.removeOne(position))
172             temporarilyReservedSlots.append(position);
173
174     }
175
176
177     //spread ghosts in random free slots
178
179     for (int i=0; i < ghosts; i++)
180     {
181         QPointF * pPosition = findRandomFreeSlot();
182
183         //If there was no room no point to continue
184         if (pPosition == NULL)
185             return;
186
187         QPixmap ghostPixmap(":/pix/aave.png");
188         QGraphicsPixmapItem * pGhost = addPixmap(ghostPixmap);
189         pGhost->setData(0,"ghost");
190         pGhost->setPos(*pPosition);
191         delete pPosition;
192     }
193
194     //return the slots occupied by moving items to free slots
195     freeTiles_.append(temporarilyReservedSlots);
196
197     //clear temp for the next round
198     temporarilyReservedSlots.clear();
199 }
200
201 QPointF* SeaScene::findRandomFreeSlot()
202 {
203     if (freeTiles_.isEmpty())
204         return NULL;
205
206     int index = qrand()%freeTiles_.size();
207
208     qDebug()  << index << " index";
209     return new QPointF (freeTiles_.takeAt(index));
210
211 }
212
213 void SeaScene::removeGhost(QGraphicsItem *pGhost)
214 {
215     removeItem(pGhost);  //remove the item from scene
216     freeTiles_.append(pGhost->scenePos()); //add the item's position to free slots
217     delete pGhost;
218     ghostsLeft_--;
219     if (ghostsLeft_ == 0)
220     {
221         //here whatever happens when a level is complete / a signal
222         qDebug() << "All ghosts picked!";
223     }
224 }
225
226 void SeaScene::ghostsDropped(int ghosts)
227 {
228     ghostsLeft_ += ghosts;
229
230     spreadGhosts(ghosts);
231 }