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()
16 #include "gameboard.h"
19 GameWidget::GameWidget(QWidget * parent/*= 0*/): QWidget(parent),
20 level(1), gameBoard(new GameBoard(level)),
21 animating(false), boxMoving(false)
25 // score->setTextFormat(Qt::PlainText);
29 GameWidget::~GameWidget(void)
34 void GameWidget::paintEvent(QPaintEvent * /*event*/)
36 QPainter painter(this);
39 font.setPixelSize(titleBox.height() - 8);
40 painter.setFont(font);
41 painter.setPen(QPen(Qt::black, 1.0, Qt::SolidLine));
42 painter.drawText(titleBox, Qt::AlignCenter, gameBoard->name);
44 painter.translate(QPoint(offsetX, offsetY));
47 for(int y=0; y<gameBoard->height; y++)
49 for(int x=0; x<gameBoard->width; x++)
51 int tile = gameBoard->board[ptr++];
52 painter.setPen(QPen(Qt::black, 2.0, Qt::SolidLine));
53 painter.setBrush(QBrush(Qt::black));
54 int tileType = tile & (~GTBoxSpot);
56 if (tileType == GTWall)
58 painter.setBrush(QBrush(Qt::white));
59 painter.drawRect(x * maxLength, y * maxLength, maxLength, maxLength);
61 else if ((tileType == GTBox)
62 && (!(boxMoving && (movingBoxPositionX == x) && (movingBoxPositionY == y))))
64 painter.setBrush(QBrush(tile & GTBoxSpot ? Qt::green : Qt::red));
65 painter.drawRect(x * maxLength, y * maxLength, maxLength, maxLength);
67 else if ((tileType == GTSpace)
68 || ((tileType == GTBox) && (boxMoving && (movingBoxPositionX == x) && (movingBoxPositionY == y))))
70 painter.setBrush(QBrush(QPixmap(":/bg_marble_g.bmp")));
71 painter.drawRect(x * maxLength, y * maxLength, maxLength, maxLength);
75 painter.setBrush(QBrush(Qt::magenta));
76 // painter.drawRect((x * maxLength) + 20, (y * maxLength) + 20, maxLength - 40, maxLength - 40);
77 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));
81 if ((gameBoard->playerX == x) && (gameBoard->playerY == y) && !animating)
83 painter.setBrush(QBrush(Qt::yellow));
84 // painter.drawEllipse((x * maxLength) + 10, (y * maxLength) + 10, maxLength - 20, maxLength - 20);
85 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));
91 painter.setBrush(QBrush(Qt::yellow));
92 // painter.drawEllipse(playerX + 10, playerY + 10, maxLength - 20, maxLength - 20);
93 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));
98 painter.setBrush(QBrush(Qt::red));
99 painter.drawRect(boxX, boxY, maxLength, maxLength);
105 void GameWidget::mousePressEvent(QMouseEvent * event)
107 if (event->button() == Qt::LeftButton)
114 void GameWidget::mouseMoveEvent(QMouseEvent * event)
116 if (event->buttons() & Qt::LeftButton)
123 void GameWidget::mouseReleaseEvent(QMouseEvent * event)
125 if (event->button() == Qt::LeftButton)
132 void GameWidget::mouseDoubleClickEvent(QMouseEvent * event)
134 if (event->button() == Qt::LeftButton)
141 void GameWidget::keyPressEvent(QKeyEvent * event)
143 int key = event->key();
144 float deltaX = 0, deltaY = 0;
145 float px = (float)(gameBoard->playerX * maxLength);
146 float py = (float)(gameBoard->playerY * maxLength);
147 float bx = px, by = py;
149 if (key == Qt::Key_Up)
151 boxMoving = gameBoard->IsBoxNOfPlayer();
152 int moveType = gameBoard->MovePlayerN();
154 if (moveType == PMInvalid)
159 else if (key == Qt::Key_Down)
161 boxMoving = gameBoard->IsBoxSOfPlayer();
163 if (gameBoard->MovePlayerS() == PMInvalid)
168 else if (key == Qt::Key_Left)
170 boxMoving = gameBoard->IsBoxWOfPlayer();
172 if (gameBoard->MovePlayerW() == PMInvalid)
177 else if (key == Qt::Key_Right)
179 boxMoving = gameBoard->IsBoxEOfPlayer();
181 if (gameBoard->MovePlayerE() == PMInvalid)
194 movingBoxPositionX = gameBoard->playerX + (int)deltaX;
195 movingBoxPositionY = gameBoard->playerY + (int)deltaY;
196 bx += deltaX * (float)maxLength;
197 by += deltaY * (float)maxLength;
201 float stepSize = (float)maxLength / (float)steps;
202 deltaX *= stepSize, deltaY *= stepSize;
204 for(int i=0; i<steps; i++)
218 animating = boxMoving = false;
220 // Only update if a key we recognize has been pressed!
223 if (gameBoard->GameHasBeenWon())
228 void GameWidget::keyReleaseEvent(QKeyEvent * /*event*/)
233 void GameWidget::resizeEvent(QResizeEvent * /*event*/)
235 // QSize s = event->size();
237 //printf("Size of window is: %i x %i\n", s.width(), s.height());
238 //printf("Size of game grid is: %i x %i\n", gameBoard->width, gameBoard->height);
240 // Find the constraints
241 float boxSizeX = s.width() / gameBoard->width;
242 float boxSizeY = s.height() / gameBoard->height;
244 maxLength = (int)(boxSizeX > boxSizeY ? boxSizeY : boxSizeX);
251 void GameWidget::CreateBackground(void)
254 char BGRes[27][64] = {
255 ":/res/grfttile.bmp",
257 ":/res/bg_tech_3.bmp",
258 ":/res/bg_tech_2.bmp",
259 ":/res/bg_tech_1.bmp",
260 ":/res/bg_weave_3.bmp",
261 ":/res/bg_weave_2.bmp",
262 ":/res/bg_clouds_2.bmp",
263 ":/res/bg_floor_plate.bmp",
264 ":/res/bg_marble_b.bmp",
265 ":/res/bg_marble_g.bmp",
266 ":/res/bg_marble_p.bmp",
267 ":/res/bg_marble_r.bmp",
268 ":/res/bg_marble_rb.bmp",
269 ":/res/bg_money_1.bmp",
270 ":/res/bg_pinstripe2.bmp",
271 ":/res/bg_pinstripe7.bmp",
272 ":/res/bg_raindrops_large.bmp",
273 ":/res/bg_raindrops_small.bmp",
274 ":/res/bg_stucco.bmp",
275 ":/res/bg_wood_w.bmp",
276 ":/res/bg_wood_b1.bmp",
277 ":/res/bg_wood_d.bmp",
278 ":/res/bg_wood_f.bmp",
279 ":/res/bg_wood_mh.bmp",
280 ":/res/bg_wood_mv.bmp",
281 ":/res/bg_wood_ro.bmp"
284 QPalette pal = palette();
285 pal.setBrush(backgroundRole(), QBrush(QPixmap(BGRes[m_nBackground])));
286 setAutoFillBackground(true);
289 return true; // Ignore errors for now...
291 // QPalette pal = palette();
292 // pal.setBrush(backgroundRole(), QBrush(QPixmap(":/bg_marble_g.bmp")));
293 // setAutoFillBackground(true);
299 void GameWidget::NextLevel(void)
303 gameBoard = new GameBoard(level);
309 void GameWidget::ResetLevel(void)
311 gameBoard->ResetGame();
316 void GameWidget::UndoLastMove(void)
320 float deltaX = 0, deltaY = 0;
321 float px = (float)(gameBoard->playerX * maxLength);
322 float py = (float)(gameBoard->playerY * maxLength);
323 float bx = px, by = py;
325 // Return if nothing to undo
326 if (!gameBoard->UndoLastMove(dx, dy, type))
340 movingBoxPositionX = gameBoard->playerX + dx;
341 movingBoxPositionY = gameBoard->playerY + dy;
342 bx += (float)(dx * maxLength);
343 by += (float)(dy * maxLength);
347 float stepSize = (float)maxLength / (float)steps;
348 deltaX *= stepSize, deltaY *= stepSize;
350 for(int i=0; i<steps; i++)
364 animating = boxMoving = false;
369 void GameWidget::ResizeGrid(void)
373 // Set some room for the board title (7.5%)
374 float titleHeight = s.height() * 0.075;
376 // Find the constraints
377 float boxSizeX = s.width() / gameBoard->width;
378 float boxSizeY = (s.height() - titleHeight) / gameBoard->height;
380 maxLength = (int)(boxSizeX > boxSizeY ? boxSizeY : boxSizeX);
382 offsetX = (s.width() - (maxLength * gameBoard->width)) / 2;
383 offsetY = ((s.height() - titleHeight) - (maxLength * gameBoard->height)) / 2;
384 titleBox.setRect(0, offsetY, s.width(), titleHeight);
385 offsetY += titleHeight; // Add in the title's height
390 // Halt processing for 'count' milliseconds
392 void GameWidget::Pause(int count)
394 // DWORD endCount = GetTickCount() + count;
395 // while (GetTickCount() < endCount) {} // Still crude, but better control
397 usleep(count * 1000);
399 // This causes it to lock up randomly. :-/
403 while (time.msec() < count)