diff options
| author | Gustav Sörnäs <gustav@sornas.net> | 2020-09-21 16:13:25 +0200 |
|---|---|---|
| committer | Gustav Sörnäs <gustav@sornas.net> | 2020-09-21 21:38:35 +0200 |
| commit | 3686258d2fa6fdffebb57f7d530952fd4dabf366 (patch) | |
| tree | d0290f2dc79698a4c73beeb58dd8f39b8b718edf /labb4/mainwindow.cpp | |
| parent | 245a34f1fad0e4fe2fb6401dc1d5352e4914b48a (diff) | |
| download | tddd86-l4.tar.gz | |
Given files L4l4
Diffstat (limited to 'labb4/mainwindow.cpp')
| -rw-r--r-- | labb4/mainwindow.cpp | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/labb4/mainwindow.cpp b/labb4/mainwindow.cpp new file mode 100644 index 0000000..99d288f --- /dev/null +++ b/labb4/mainwindow.cpp @@ -0,0 +1,199 @@ +/** + * TDDD86 Robots + * This file contains the implementation of the mainwindow class. + * See mainwindow.h for comments about each member. + */ + +#include <algorithm> +#include "mainwindow.h" +#include "Hero.h" +#include "Robot.h" +#include "Junk.h" + +MainWindow::MainWindow(QWidget *parent) : + QWidget(parent) { + // set default size and color + scene = new QGraphicsScene(0, 0, SCENE_WIDTH, SCENE_HEIGHT); + scene->setBackgroundBrush(QBrush(QColor(204, 192, 179))); + view = new QGraphicsView(scene); + + // create the main layout + mainLayout = new QVBoxLayout(); + setLayout(mainLayout); + + // add game board to layout + mainLayout->insertWidget(0, view); + + // start new game and draw state + gameState.draw(scene); + + // create label layout + labelLayout = new QHBoxLayout(); + + // create the score widget + scoreLabel = new QLabel(QString("SCORE: %1").arg(score)); + scoreLabel->setStyleSheet("QLabel { color: rgb(235,224,214); font: 16pt; }"); + scoreLabel->setFixedHeight(35); + + // create the level widget + levelLabel = new QLabel(QString("LEVEL: %1").arg(level)); + levelLabel->setStyleSheet("QLabel { color: rgb(235,224,214); font: 16pt; }"); + levelLabel->setFixedHeight(35); + + // add score and level widgets to board + labelLayout->insertWidget(0, levelLabel, 0, Qt::AlignLeft); + labelLayout->insertWidget(1, scoreLabel, 0, Qt::AlignRight); + mainLayout->insertLayout(1, labelLayout); + + // style sheet of the game board + setStyleSheet("MainWindow { background-color: rgb(187,173,160) }"); + + // no resizing of game window + setFixedSize(sizeHint()); + + connect(gameOverWindow.getResetBtn(), SIGNAL(clicked()), this, SLOT(resetGame())); +} + +MainWindow::~MainWindow() { + delete scoreLabel; + delete levelLabel; + delete labelLayout; + delete scene; + delete view; + delete mainLayout; +} + +/* + * Listens to key press events from the graphical subsystem, + * and handles the events appropriately: + * - '[n]' moves hero in direction [n], + * where n = 1, 2, 3, 4, 6, 7, 8, 9 on the numeric keypad + * - '5' on the numeric keypad makes the hero wait one turn + * - 'T' teleports hero + */ +void MainWindow::keyPressEvent(QKeyEvent *e) +{ + if (!gameOver) { // only process key presses while game is not over + Hero hero = gameState.getHero(); + Point pt = hero.asPoint(); + bool actionTaken = false; + bool waiting = false; + + if (e->modifiers() == Qt::KeypadModifier) { + switch (e->key()) { + case Qt::Key_1: + actionTaken = tryMove(hero, Point{pt.x - 1, pt.y + 1}); + break; + case Qt::Key_2: + actionTaken = tryMove(hero, Point{pt.x, pt.y + 1}); + break; + case Qt::Key_3: + actionTaken = tryMove(hero, Point{pt.x + 1, pt.y + 1}); + break; + case Qt::Key_4: + actionTaken = tryMove(hero, Point{pt.x - 1, pt.y}); + break; + case Qt::Key_6: + actionTaken = tryMove(hero, Point{pt.x + 1, pt.y}); + break; + case Qt::Key_7: + actionTaken = tryMove(hero, Point{pt.x - 1, pt.y - 1}); + break; + case Qt::Key_8: + actionTaken = tryMove(hero, Point{pt.x, pt.y - 1}); + break; + case Qt::Key_9: + actionTaken = tryMove(hero, Point{pt.x + 1, pt.y - 1}); + break; + case Qt::Key_5: + actionTaken = true; + waiting = true; + break; + default: + QWidget::keyPressEvent(e); + } + } else { + switch (e->key()) { + case Qt::Key_T: + gameState.teleportHero(); + actionTaken = true; + break; + default: + QWidget::keyPressEvent(e); + } + } + + if (actionTaken) { // process results of viable move + processMove(waiting); + } + } else { // game is over - do not process key press + QWidget::keyPressEvent(e); + } +} + +/* + * Try to move hero to unit + */ +bool MainWindow::tryMove(Hero hero, const Point& point) { + if (!outsideBorder(point)) { + hero.moveTowards(point); + if (gameState.isSafe(hero)) { + gameState.moveHeroTowards(point); + return true; + } + } + return false; +} + +/* + * Process results of viable move + */ +void MainWindow::processMove(bool waiting) { + gameState.moveRobots(); + score += gameState.countCollisions() * (POINTS_PER_ROBOT + + (waiting ? WAIT_BONUS : 0)); + gameState.draw(scene); + displayScore(); + + if (!gameState.anyRobotsLeft()) { // won level + numberOfRobots = std::min(MAX_ROBOTS, numberOfRobots + ROBOTS_INC); + gameState = GameState(numberOfRobots); + gameState.draw(scene); + ++level; + displayLevel(); + } else if (gameState.heroDead()) { // game over + gameOver = true; + gameOverWindow.show(); + } +} + +/* + * Is point outside of playing field? + */ +bool MainWindow::outsideBorder(Point const& point) const { + return point.x > MAX_X + || point.y > MAX_Y + || point.x < MIN_X + || point.y < MIN_Y; +} + + +void MainWindow::displayScore() const { + scoreLabel->setText(QString("SCORE: %1").arg(score)); +} + +void MainWindow::displayLevel() const { + levelLabel->setText(QString("LEVEL: %1").arg(level)); +} + +void MainWindow::resetGame() { + score = 0; + level = 1; + numberOfRobots = MIN_ROBOTS; + gameState = GameState(numberOfRobots); + gameState.draw(scene); + displayScore(); + displayLevel(); + gameOver = false; + gameOverWindow.hide(); +} |
