]> Shamusworld >> Repos - warehouse-man-deluxe/blob - src/gamewidget.cpp
Moved level storage to global location.
[warehouse-man-deluxe] / src / gamewidget.cpp
1 //
2 // gamewidget.cpp: Main game window widget
3 //
4 // by James Hammons
5 // (C) 2013 Underground Software
6 //
7 // JLH = James Hammons <jlhamm@acm.org>
8 //
9 // Who  When        What
10 // ---  ----------  ------------------------------------------------------------
11 // JLH  03/01/2014  Created this file
12 //
13
14 #include "gamewidget.h"
15 #include <unistd.h>                     // for usleep()
16 #include "boards.h"
17 #include "gameboard.h"
18
19
20 GameWidget::GameWidget(QWidget * parent/*= 0*/): QWidget(parent),
21 //      level(1), gameBoard(new GameBoard(level)),
22         level(1), gameBoard(new GameBoard(&(levelStorage[level - 1]))),
23         animating(false), boxMoving(false)
24 //      score(new QLabel)
25 {
26         CreateBackground();
27 //      score->setTextFormat(Qt::PlainText);
28 }
29
30
31 GameWidget::~GameWidget(void)
32 {
33 }
34
35
36 void GameWidget::paintEvent(QPaintEvent * /*event*/)
37 {
38         QPainter painter(this);
39         QFont font;
40
41         font.setPixelSize(titleBox.height() - 8);
42         painter.setFont(font);
43         painter.setPen(QPen(Qt::black, 1.0, Qt::SolidLine));
44         painter.drawText(titleBox, Qt::AlignCenter, gameBoard->name);
45
46         painter.translate(QPoint(offsetX, offsetY));
47         int ptr = 0;
48
49         for(int y=0; y<gameBoard->height; y++)
50         {
51                 for(int x=0; x<gameBoard->width; x++)
52                 {
53                         int tile = gameBoard->board[ptr++];
54                         painter.setPen(QPen(Qt::black, 2.0, Qt::SolidLine));
55                         painter.setBrush(QBrush(Qt::black));
56                         int tileType = tile & (~GTBoxSpot);
57
58                         if (tileType == GTWall)
59                         {
60                                 painter.setBrush(QBrush(Qt::white));
61                                 painter.drawRect(x * maxLength, y * maxLength, maxLength, maxLength);
62                         }
63                         else if ((tileType == GTBox)
64                                 && (!(boxMoving && (movingBoxPositionX == x) && (movingBoxPositionY == y))))
65                         {
66                                 painter.setBrush(QBrush(tile & GTBoxSpot ? Qt::darkRed : Qt::red));
67                                 painter.drawRect(x * maxLength, y * maxLength, maxLength, maxLength);
68                         }
69                         else if ((tileType == GTSpace)
70                                 || ((tileType == GTBox) && (boxMoving && (movingBoxPositionX == x) && (movingBoxPositionY == y))))
71                         {
72                                 painter.setBrush(QBrush(QPixmap(":/bg_marble_g.bmp")));
73                                 painter.drawRect(x * maxLength, y * maxLength, maxLength, maxLength);
74
75                                 if (tile & GTBoxSpot)
76                                 {
77                                         painter.setBrush(QBrush(Qt::magenta));
78 //                              painter.drawRect((x * maxLength) + 20, (y * maxLength) + 20, maxLength - 40, maxLength - 40);
79                                         painter.drawRect((x * maxLength) + (int)(20.0/60.0*(float)maxLength), (y * maxLength) + (int)(20.0/60.0*(float)maxLength), maxLength - (int)(40.0/60.0*(float)maxLength), maxLength - (int)(40.0/60.0*(float)maxLength));
80                                 }
81                         }
82
83                         if ((gameBoard->playerX == x) && (gameBoard->playerY == y) && !animating)
84                         {
85                                 painter.setBrush(QBrush(Qt::yellow));
86 //                              painter.drawEllipse((x * maxLength) + 10, (y * maxLength) + 10, maxLength - 20, maxLength - 20);
87                                 painter.drawEllipse((x * maxLength) + (int)(10.0/60.0*(float)maxLength), (y * maxLength) + (int)(10.0/60.0*(float)maxLength), maxLength - (int)(20.0/60.0*(float)maxLength), maxLength - (int)(20.0/60.0*(float)maxLength));
88                         }
89                 }
90
91                 if (animating)
92                 {
93                         painter.setBrush(QBrush(Qt::yellow));
94 //                      painter.drawEllipse(playerX + 10, playerY + 10, maxLength - 20, maxLength - 20);
95                         painter.drawEllipse(playerX + (int)(10.0/60.0*(float)maxLength), playerY + (int)(10.0/60.0*(float)maxLength), maxLength - (int)(20.0/60.0*(float)maxLength), maxLength - (int)(20.0/60.0*(float)maxLength));
96                 }
97
98                 if (boxMoving)
99                 {
100                         painter.setBrush(QBrush(Qt::red));
101                         painter.drawRect(boxX, boxY, maxLength, maxLength);
102                 }
103         }
104 }
105
106
107 void GameWidget::mousePressEvent(QMouseEvent * event)
108 {
109         if (event->button() == Qt::LeftButton)
110         {
111                 event->accept();
112         }
113 }
114
115
116 void GameWidget::mouseMoveEvent(QMouseEvent * event)
117 {
118         if (event->buttons() & Qt::LeftButton)
119         {
120                 event->accept();
121         }
122 }
123
124
125 void GameWidget::mouseReleaseEvent(QMouseEvent * event)
126 {
127         if (event->button() == Qt::LeftButton)
128         {
129                 event->accept();
130         }
131 }
132
133
134 void GameWidget::mouseDoubleClickEvent(QMouseEvent * event)
135 {
136         if (event->button() == Qt::LeftButton)
137         {
138                 event->accept();
139         }
140 }
141
142
143 void GameWidget::keyPressEvent(QKeyEvent * event)
144 {
145         int key = event->key();
146         float deltaX = 0, deltaY = 0;
147         float px = (float)(gameBoard->playerX * maxLength);
148         float py = (float)(gameBoard->playerY * maxLength);
149         float bx = px, by = py;
150
151         if (key == Qt::Key_Up)
152         {
153                 boxMoving = gameBoard->IsBoxNOfPlayer();
154                 int moveType = gameBoard->MovePlayerN();
155
156                 if (moveType == PMInvalid)
157                         return;
158
159                 deltaY = -1.0;
160         }
161         else if (key == Qt::Key_Down)
162         {
163                 boxMoving = gameBoard->IsBoxSOfPlayer();
164
165                 if (gameBoard->MovePlayerS() == PMInvalid)
166                         return;
167
168                 deltaY = +1.0;
169         }
170         else if (key == Qt::Key_Left)
171         {
172                 boxMoving = gameBoard->IsBoxWOfPlayer();
173
174                 if (gameBoard->MovePlayerW() == PMInvalid)
175                         return;
176
177                 deltaX = -1.0;
178         }
179         else if (key == Qt::Key_Right)
180         {
181                 boxMoving = gameBoard->IsBoxEOfPlayer();
182
183                 if (gameBoard->MovePlayerE() == PMInvalid)
184                         return;
185
186                 deltaX = +1.0;
187         }
188         else
189                 return;
190
191         animating = true;
192 //      update();
193
194         if (boxMoving)
195         {
196                 movingBoxPositionX = gameBoard->playerX + (int)deltaX;
197                 movingBoxPositionY = gameBoard->playerY + (int)deltaY;
198                 bx += deltaX * (float)maxLength;
199                 by += deltaY * (float)maxLength;
200         }
201
202         int steps = 15;
203         float stepSize = (float)maxLength / (float)steps;
204         deltaX *= stepSize, deltaY *= stepSize;
205
206         for(int i=0; i<steps; i++)
207         {
208                 px += deltaX;
209                 py += deltaY;
210                 playerX = (int)px;
211                 playerY = (int)py;
212                 bx += deltaX;
213                 by += deltaY;
214                 boxX = (int)bx;
215                 boxY = (int)by;
216                 repaint();
217                 Pause(3);
218         }
219
220         animating = boxMoving = false;
221
222         // Only update if a key we recognize has been pressed!
223         update();
224
225         if (gameBoard->GameHasBeenWon())
226                 emit GameWasWon();
227 }
228
229
230 void GameWidget::keyReleaseEvent(QKeyEvent * /*event*/)
231 {
232 }
233
234
235 void GameWidget::resizeEvent(QResizeEvent * /*event*/)
236 {
237 //      QSize s = event->size();
238
239 //printf("Size of window is: %i x %i\n", s.width(), s.height());
240 //printf("Size of game grid is: %i x %i\n", gameBoard->width, gameBoard->height);
241 #if 0
242         // Find the constraints
243         float boxSizeX = s.width() / gameBoard->width;
244         float boxSizeY = s.height() / gameBoard->height;
245
246         maxLength = (int)(boxSizeX > boxSizeY ? boxSizeY : boxSizeX);
247 #else
248         ResizeGrid();
249 #endif
250 }
251
252
253 void GameWidget::CreateBackground(void)
254 {
255 #if 0
256         char BGRes[27][64] = {
257                 ":/res/grfttile.bmp",
258                 ":/res/cloth_6.bmp",
259                 ":/res/bg_tech_3.bmp",
260                 ":/res/bg_tech_2.bmp",
261                 ":/res/bg_tech_1.bmp",
262                 ":/res/bg_weave_3.bmp",
263                 ":/res/bg_weave_2.bmp",
264                 ":/res/bg_clouds_2.bmp",
265                 ":/res/bg_floor_plate.bmp",
266                 ":/res/bg_marble_b.bmp",
267                 ":/res/bg_marble_g.bmp",
268                 ":/res/bg_marble_p.bmp",
269                 ":/res/bg_marble_r.bmp",
270                 ":/res/bg_marble_rb.bmp",
271                 ":/res/bg_money_1.bmp",
272                 ":/res/bg_pinstripe2.bmp",
273                 ":/res/bg_pinstripe7.bmp",
274                 ":/res/bg_raindrops_large.bmp",
275                 ":/res/bg_raindrops_small.bmp",
276                 ":/res/bg_stucco.bmp",
277                 ":/res/bg_wood_w.bmp",
278                 ":/res/bg_wood_b1.bmp",
279                 ":/res/bg_wood_d.bmp",
280                 ":/res/bg_wood_f.bmp",
281                 ":/res/bg_wood_mh.bmp",
282                 ":/res/bg_wood_mv.bmp",
283                 ":/res/bg_wood_ro.bmp"
284         };
285
286         QPalette pal = palette();
287         pal.setBrush(backgroundRole(), QBrush(QPixmap(BGRes[m_nBackground])));
288         setAutoFillBackground(true);
289         setPalette(pal);
290
291         return true; // Ignore errors for now...
292 #else
293 //      QPalette pal = palette();
294 //      pal.setBrush(backgroundRole(), QBrush(QPixmap(":/bg_marble_g.bmp")));
295 //      setAutoFillBackground(true);
296 //      setPalette(pal);
297 #endif
298 }
299
300
301 void GameWidget::NextLevel(void)
302 {
303         level++;
304         delete gameBoard;
305 //      gameBoard = new GameBoard(level);
306         gameBoard = new GameBoard(&(levelStorage[level - 1]));
307         ResizeGrid();
308         update();
309 }
310
311
312 void GameWidget::ResetLevel(void)
313 {
314         gameBoard->ResetGame();
315         update();
316 }
317
318
319 void GameWidget::UndoLastMove(void)
320 {
321         int dx, dy, type;
322
323         float deltaX = 0, deltaY = 0;
324         float px = (float)(gameBoard->playerX * maxLength);
325         float py = (float)(gameBoard->playerY * maxLength);
326         float bx = px, by = py;
327
328         // Return if nothing to undo
329         if (!gameBoard->UndoLastMove(dx, dy, type))
330                 return;
331
332         deltaX = (float)-dx;
333         deltaY = (float)-dy;
334
335         if (type == PMPush)
336                 boxMoving = true;
337
338         animating = true;
339 //      update();
340
341         if (boxMoving)
342         {
343                 movingBoxPositionX = gameBoard->playerX + dx;
344                 movingBoxPositionY = gameBoard->playerY + dy;
345                 bx += (float)(dx * maxLength);
346                 by += (float)(dy * maxLength);
347         }
348
349         int steps = 15;
350         float stepSize = (float)maxLength / (float)steps;
351         deltaX *= stepSize, deltaY *= stepSize;
352
353         for(int i=0; i<steps; i++)
354         {
355                 px += deltaX;
356                 py += deltaY;
357                 playerX = (int)px;
358                 playerY = (int)py;
359                 bx += deltaX;
360                 by += deltaY;
361                 boxX = (int)bx;
362                 boxY = (int)by;
363                 repaint();
364                 Pause(3);
365         }
366
367         animating = boxMoving = false;
368         update();
369 }
370
371
372 void GameWidget::HandlePlayGameFromEditor(Level * l)
373 {
374 //      level++;
375         delete gameBoard;
376         gameBoard = new GameBoard(l);
377         ResizeGrid();
378         update();
379 }
380
381
382 void GameWidget::ResizeGrid(void)
383 {
384         QSize s = size();
385
386         // Set some room for the board title (7.5%)
387         float titleHeight = s.height() * 0.075;
388
389         // Find the constraints
390         float boxSizeX = s.width() / gameBoard->width;
391         float boxSizeY = (s.height() - titleHeight) / gameBoard->height;
392
393         maxLength = (int)(boxSizeX > boxSizeY ? boxSizeY : boxSizeX);
394
395         offsetX = (s.width() - (maxLength * gameBoard->width)) / 2;
396         offsetY = ((s.height() - titleHeight) - (maxLength * gameBoard->height)) / 2;
397         titleBox.setRect(0, offsetY, s.width(), titleHeight);
398         offsetY += titleHeight; // Add in the title's height
399 }
400
401
402 //
403 // Halt processing for 'count' milliseconds
404 //
405 void GameWidget::Pause(int count)
406 {
407 //      DWORD endCount = GetTickCount() + count;
408 //      while (GetTickCount() < endCount) {}     // Still crude, but better control
409 #if 1
410         usleep(count * 1000);
411 #else
412         // This causes it to lock up randomly. :-/
413         QTime time;
414         time.start();
415
416         while (time.msec() < count)
417                 ; // Do nothing...
418 #endif
419 }
420