2 // gamewidget.cpp: Main game window widget
5 // (C) 2013 Underground Software
7 // JLH = James Hammons <jlhamm@acm.org>
10 // --- ---------- ------------------------------------------------------------
11 // JLH 03/01/2014 Created this file
14 #include "gamewidget.h"
15 #include <unistd.h> // for usleep()
17 #include "gameboard.h"
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)
27 // score->setTextFormat(Qt::PlainText);
31 GameWidget::~GameWidget(void)
36 void GameWidget::paintEvent(QPaintEvent * /*event*/)
38 QPainter painter(this);
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);
46 painter.translate(QPoint(offsetX, offsetY));
49 for(int y=0; y<gameBoard->height; y++)
51 for(int x=0; x<gameBoard->width; x++)
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);
58 if (tileType == GTWall)
60 painter.setBrush(QBrush(Qt::white));
61 painter.drawRect(x * maxLength, y * maxLength, maxLength, maxLength);
63 else if ((tileType == GTBox)
64 && (!(boxMoving && (movingBoxPositionX == x) && (movingBoxPositionY == y))))
66 painter.setBrush(QBrush(tile & GTBoxSpot ? Qt::darkRed : Qt::red));
67 painter.drawRect(x * maxLength, y * maxLength, maxLength, maxLength);
69 else if ((tileType == GTSpace)
70 || ((tileType == GTBox) && (boxMoving && (movingBoxPositionX == x) && (movingBoxPositionY == y))))
72 painter.setBrush(QBrush(QPixmap(":/bg_marble_g.bmp")));
73 painter.drawRect(x * maxLength, y * maxLength, maxLength, maxLength);
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));
83 if ((gameBoard->playerX == x) && (gameBoard->playerY == y) && !animating)
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));
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));
100 painter.setBrush(QBrush(Qt::red));
101 painter.drawRect(boxX, boxY, maxLength, maxLength);
107 void GameWidget::mousePressEvent(QMouseEvent * event)
109 if (event->button() == Qt::LeftButton)
116 void GameWidget::mouseMoveEvent(QMouseEvent * event)
118 if (event->buttons() & Qt::LeftButton)
125 void GameWidget::mouseReleaseEvent(QMouseEvent * event)
127 if (event->button() == Qt::LeftButton)
134 void GameWidget::mouseDoubleClickEvent(QMouseEvent * event)
136 if (event->button() == Qt::LeftButton)
143 void GameWidget::keyPressEvent(QKeyEvent * event)
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;
151 if (key == Qt::Key_Up)
153 boxMoving = gameBoard->IsBoxNOfPlayer();
154 int moveType = gameBoard->MovePlayerN();
156 if (moveType == PMInvalid)
161 else if (key == Qt::Key_Down)
163 boxMoving = gameBoard->IsBoxSOfPlayer();
165 if (gameBoard->MovePlayerS() == PMInvalid)
170 else if (key == Qt::Key_Left)
172 boxMoving = gameBoard->IsBoxWOfPlayer();
174 if (gameBoard->MovePlayerW() == PMInvalid)
179 else if (key == Qt::Key_Right)
181 boxMoving = gameBoard->IsBoxEOfPlayer();
183 if (gameBoard->MovePlayerE() == PMInvalid)
196 movingBoxPositionX = gameBoard->playerX + (int)deltaX;
197 movingBoxPositionY = gameBoard->playerY + (int)deltaY;
198 bx += deltaX * (float)maxLength;
199 by += deltaY * (float)maxLength;
203 float stepSize = (float)maxLength / (float)steps;
204 deltaX *= stepSize, deltaY *= stepSize;
206 for(int i=0; i<steps; i++)
220 animating = boxMoving = false;
222 // Only update if a key we recognize has been pressed!
225 if (gameBoard->GameHasBeenWon())
230 void GameWidget::keyReleaseEvent(QKeyEvent * /*event*/)
235 void GameWidget::resizeEvent(QResizeEvent * /*event*/)
237 // QSize s = event->size();
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);
242 // Find the constraints
243 float boxSizeX = s.width() / gameBoard->width;
244 float boxSizeY = s.height() / gameBoard->height;
246 maxLength = (int)(boxSizeX > boxSizeY ? boxSizeY : boxSizeX);
253 void GameWidget::CreateBackground(void)
256 char BGRes[27][64] = {
257 ":/res/grfttile.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"
286 QPalette pal = palette();
287 pal.setBrush(backgroundRole(), QBrush(QPixmap(BGRes[m_nBackground])));
288 setAutoFillBackground(true);
291 return true; // Ignore errors for now...
293 // QPalette pal = palette();
294 // pal.setBrush(backgroundRole(), QBrush(QPixmap(":/bg_marble_g.bmp")));
295 // setAutoFillBackground(true);
301 void GameWidget::NextLevel(void)
305 // gameBoard = new GameBoard(level);
306 gameBoard = new GameBoard(&(levelStorage[level - 1]));
312 void GameWidget::ResetLevel(void)
314 gameBoard->ResetGame();
319 void GameWidget::UndoLastMove(void)
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;
328 // Return if nothing to undo
329 if (!gameBoard->UndoLastMove(dx, dy, type))
343 movingBoxPositionX = gameBoard->playerX + dx;
344 movingBoxPositionY = gameBoard->playerY + dy;
345 bx += (float)(dx * maxLength);
346 by += (float)(dy * maxLength);
350 float stepSize = (float)maxLength / (float)steps;
351 deltaX *= stepSize, deltaY *= stepSize;
353 for(int i=0; i<steps; i++)
367 animating = boxMoving = false;
372 void GameWidget::HandlePlayGameFromEditor(Level * l)
376 gameBoard = new GameBoard(l);
382 void GameWidget::ResizeGrid(void)
386 // Set some room for the board title (7.5%)
387 float titleHeight = s.height() * 0.075;
389 // Find the constraints
390 float boxSizeX = s.width() / gameBoard->width;
391 float boxSizeY = (s.height() - titleHeight) / gameBoard->height;
393 maxLength = (int)(boxSizeX > boxSizeY ? boxSizeY : boxSizeX);
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
403 // Halt processing for 'count' milliseconds
405 void GameWidget::Pause(int count)
407 // DWORD endCount = GetTickCount() + count;
408 // while (GetTickCount() < endCount) {} // Still crude, but better control
410 usleep(count * 1000);
412 // This causes it to lock up randomly. :-/
416 while (time.msec() < count)