Initial Commit

This commit is contained in:
Victor Tran 2019-10-23 21:45:55 +11:00
commit b3fa2ada8f
No known key found for this signature in database
GPG key ID: FBA10B22D602BAC1
26 changed files with 2368 additions and 0 deletions

73
.gitignore vendored Normal file
View file

@ -0,0 +1,73 @@
# This file is used to ignore files which are generated
# ----------------------------------------------------------------------------
*~
*.autosave
*.a
*.core
*.moc
*.o
*.obj
*.orig
*.rej
*.so
*.so.*
*_pch.h.cpp
*_resource.rc
*.qm
.#*
*.*#
core
!core/
tags
.DS_Store
.directory
*.debug
Makefile*
*.prl
*.app
moc_*.cpp
ui_*.h
qrc_*.cpp
Thumbs.db
*.res
*.rc
/.qmake.cache
/.qmake.stash
# qtcreator generated files
*.pro.user*
# xemacs temporary files
*.flc
# Vim temporary files
.*.swp
# Visual Studio generated files
*.ib_pdb_index
*.idb
*.ilk
*.pdb
*.sln
*.suo
*.vcproj
*vcproj.*.*.user
*.ncb
*.sdf
*.opensdf
*.vcxproj
*vcxproj.*
# MinGW generated files
*.Debug
*.Release
# Python byte code
*.pyc
# Binaries
# --------
*.dll
*.exe

5
audio.qrc Normal file
View file

@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/">
<file>audio/crypto.ogg</file>
</qresource>
</RCC>

BIN
audio/crypto.ogg Normal file

Binary file not shown.

47
ent-mines.pro Normal file
View file

@ -0,0 +1,47 @@
QT += core gui entertaining thelib svg
TARGET = entertaining-mines
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
game/gametile.cpp \
main.cpp \
gamewindow.cpp \
screens/gamescreen.cpp \
screens/mainscreen.cpp \
screens/pausescreen.cpp
HEADERS += \
game/gametile.h \
gamewindow.h \
screens/gamescreen.h \
screens/mainscreen.h \
screens/pausescreen.h
FORMS += \
gamewindow.ui \
screens/gamescreen.ui \
screens/mainscreen.ui \
screens/pausescreen.ui
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
RESOURCES += \
audio.qrc \
resources.qrc

351
game/gametile.cpp Normal file
View file

@ -0,0 +1,351 @@
/****************************************
*
* INSERT-PROJECT-NAME-HERE - INSERT-GENERIC-NAME-HERE
* Copyright (C) 2019 Victor Tran
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* *************************************/
#include "gametile.h"
#include "screens/gamescreen.h"
#include <QPainter>
#include <the-libs_global.h>
#include <QSvgRenderer>
#include <QMouseEvent>
#include <focuspointer.h>
struct GameTilePrivate {
GameScreen* parent;
GameTile::State state = GameTile::Idle;
int x;
int y;
int numMinesAdjacent = -1;
bool mouseIsPressed = false;
bool drawMouseIsPressed = false;
bool isMine = false;
};
GameTile::GameTile(GameScreen* parent, int x, int y) : QWidget(parent)
{
d = new GameTilePrivate();
d->parent = parent;
d->x = x;
d->y = y;
this->setMouseTracking(true);
this->setFocusPolicy(Qt::StrongFocus);
connect(d->parent, &GameScreen::boardResized, this, [=] {
this->setFixedSize(this->sizeHint());
});
}
GameTile::~GameTile()
{
delete d;
}
QSize GameTile::sizeHint() const
{
int size;
//Calculate two sizes based on the height and width, and use whichever is smaller
QSize boardDimensions = d->parent->boardDimensions();
int width = (d->parent->gameArea().width()) / boardDimensions.width();
int height = (d->parent->gameArea().height()) / boardDimensions.height();
size = qMin(width, height);
return QSize(size, size);
}
bool GameTile::isMine()
{
return d->isMine;
}
void GameTile::setIsMine(bool isMine)
{
d->isMine = isMine;
}
int GameTile::minesAdjacent()
{
if (d->numMinesAdjacent == -1) {
d->numMinesAdjacent = 0;
if (!this->isMine()) {
//Calculate number of mines adjacent
for (GameTile* tile : adjacentTiles()) {
if (tile->isMine()) d->numMinesAdjacent++;
}
}
}
return d->numMinesAdjacent;
}
bool GameTile::isFlagged()
{
return d->state == Flagged;
}
void GameTile::reveal()
{
if (d->state == Idle) {
if (!d->parent->hasGameStarted()) d->parent->distributeMines(QPoint(d->x, d->y));
d->state = Revealed;
if (this->isMine()) {
d->parent->performGameOver();
} else {
//Tell the game that we've revealed a good tile
d->parent->revealedTile();
//Calculate the number of adjacent tiles with a mine if needed
if (this->minesAdjacent() == 0) {
//Attempt to reveal all adjacent tiles
for (GameTile* tile : adjacentTiles()) {
tile->reveal();
}
}
}
this->update();
}
}
void GameTile::toggleFlagStatus()
{
switch (d->state) {
case Idle:
d->state = Flagged;
d->parent->flagChanged(true);
break;
case Flagged:
d->state = Idle; //TODO: Add marked state
d->parent->flagChanged(true);
break;
case Marked:
d->state = Idle;
break;
default:
break;
}
this->update();
}
void GameTile::sweep()
{
int numFlags = 0;
QList<GameTile*> tilesToSweep;
for (GameTile* tile : adjacentTiles()) {
if (tile->isFlagged()) {
numFlags++;
} else {
tilesToSweep.append(tile);
}
}
if (minesAdjacent() == numFlags) {
//Sweep the tile
for (GameTile* tile : tilesToSweep) {
tile->reveal();
}
}
}
QList<GameTile*> GameTile::adjacentTiles()
{
QList<GameTile*> tiles;
QRect boardDimensions = QRect(QPoint(0, 0), d->parent->boardDimensions());
auto checkAndAddPoint = [=, &tiles](QPoint point) {
if (boardDimensions.contains(point)) tiles.append(d->parent->tileAt(point));
};
QPoint thisPoint(d->x, d->y);
checkAndAddPoint(thisPoint + QPoint(-1, -1));
checkAndAddPoint(thisPoint + QPoint(-1, 0));
checkAndAddPoint(thisPoint + QPoint(-1, 1));
checkAndAddPoint(thisPoint + QPoint(0, 1));
checkAndAddPoint(thisPoint + QPoint(1, 1));
checkAndAddPoint(thisPoint + QPoint(1, 0));
checkAndAddPoint(thisPoint + QPoint(1, -1));
checkAndAddPoint(thisPoint + QPoint(0, -1));
return tiles;
}
void GameTile::paintEvent(QPaintEvent*event)
{
QPainter painter(this);
QFont font = this->font();
font.setPixelSize(this->height() - SC_DPI(18));
painter.setFont(font);
//Paint the background
switch (d->state) {
case Idle:
case Flagged:
case Marked:
if ((!FocusPointer::isEnabled() && this->underMouse()) || (FocusPointer::isEnabled() && this->hasFocus())) {
if (d->drawMouseIsPressed) {
paintSvg(&painter, ":/tiles/backgroundRev.svg");
} else {
paintSvg(&painter, ":/tiles/backgroundHov.svg");
}
} else {
paintSvg(&painter, ":/tiles/background.svg");
}
break;
case Revealed:
paintSvg(&painter, ":/tiles/backgroundRev.svg");
}
//Paint the tile
if (d->parent->isGameOver() && this->isMine()) {
//Draw the mine tile
paintSvg(&painter, ":/tiles/mine.svg");
} else {
switch (d->state) {
case Idle:
//Do nothing
break;
case Flagged:
if (d->parent->isGameOver()) {
//Draw the incorrect flag tile
paintSvg(&painter, ":/tiles/flagNot.svg");
} else {
//Draw a flag
paintSvg(&painter, ":/tiles/flag.svg");
}
break;
case Marked:
//Draw a mark
break;
case Revealed:
//Draw the number of tiles
if (d->numMinesAdjacent != 0) {
painter.setPen(Qt::white);
painter.drawText(0, 0, this->height(), this->width(), Qt::AlignCenter, QString::number(d->numMinesAdjacent));
}
}
}
}
void GameTile::paintSvg(QPainter*painter, QString filePath)
{
QSvgRenderer renderer(filePath);
renderer.render(painter, QRectF(0, 0, this->width(), this->height()));
}
void GameTile::enterEvent(QEvent*event)
{
this->update();
}
void GameTile::leaveEvent(QEvent*event)
{
this->update();
}
void GameTile::keyPressEvent(QKeyEvent*event)
{
QRect boardDimensions = QRect(QPoint(0, 0), d->parent->boardDimensions());
auto handOffFocus = [=](QPoint point) {
if (boardDimensions.contains(point)) d->parent->tileAt(point)->setFocus();
};
QPoint thisPoint(d->x, d->y);
switch (event->key()) {
case Qt::Key_Left:
handOffFocus(thisPoint + QPoint(0, -1));
break;
case Qt::Key_Right:
handOffFocus(thisPoint + QPoint(0, 1));
break;
case Qt::Key_Up:
handOffFocus(thisPoint + QPoint(-1, 0));
break;
case Qt::Key_Down:
handOffFocus(thisPoint + QPoint(1, 0));
break;
case Qt::Key_Enter:
case Qt::Key_Return:
if (d->state == Revealed) {
//Sweep this tile
this->sweep();
} else {
//Reveal this tile
this->reveal();
}
break;
case Qt::Key_Space:
case Qt::Key_Z:
//Flag this tile
this->toggleFlagStatus();
break;
}
}
void GameTile::mousePressEvent(QMouseEvent*event)
{
d->mouseIsPressed = true;
if (event->button() == Qt::LeftButton) {
d->drawMouseIsPressed = true;
} else if (event->button() == Qt::MiddleButton) {
}
this->update();
}
void GameTile::mouseMoveEvent(QMouseEvent*event)
{
this->update();
}
void GameTile::mouseReleaseEvent(QMouseEvent*event)
{
d->mouseIsPressed = false;
if (event->button() == Qt::LeftButton) {
d->drawMouseIsPressed = false;
}
this->update();
if (this->underMouse()) {
//Do cool stuff
switch (event->button()) {
case Qt::LeftButton:
//Reveal this tile
this->reveal();
break;
case Qt::RightButton:
//Flag this tile
this->toggleFlagStatus();
break;
case Qt::MiddleButton:
//Sweep this tile
this->sweep();
break;
default:
//Do nothing
break;
}
}
}

72
game/gametile.h Normal file
View file

@ -0,0 +1,72 @@
/****************************************
*
* INSERT-PROJECT-NAME-HERE - INSERT-GENERIC-NAME-HERE
* Copyright (C) 2019 Victor Tran
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* *************************************/
#ifndef GAMETILE_H
#define GAMETILE_H
#include <QWidget>
struct GameTilePrivate;
class GameScreen;
class GameTile : public QWidget
{
Q_OBJECT
public:
enum State {
Idle,
Revealed,
Flagged,
Marked
};
explicit GameTile(GameScreen *parent, int x, int y);
~GameTile();
QSize sizeHint() const;
bool isMine();
void setIsMine(bool isMine);
int minesAdjacent();
bool isFlagged();
signals:
public slots:
void reveal();
void toggleFlagStatus();
void sweep();
private:
GameTilePrivate* d;
QList<GameTile*> adjacentTiles();
void paintEvent(QPaintEvent* event);
void paintSvg(QPainter* painter, QString filePath);
void enterEvent(QEvent* event);
void leaveEvent(QEvent* event);
void keyPressEvent(QKeyEvent* event);
void mousePressEvent(QMouseEvent* event);
void mouseMoveEvent(QMouseEvent* event);
void mouseReleaseEvent(QMouseEvent* event);
};
#endif // GAMETILE_H

45
gamewindow.cpp Normal file
View file

@ -0,0 +1,45 @@
/****************************************
*
* INSERT-PROJECT-NAME-HERE - INSERT-GENERIC-NAME-HERE
* Copyright (C) 2019 Victor Tran
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* *************************************/
#include "gamewindow.h"
#include "ui_gamewindow.h"
#include <focuspointer.h>
GameWindow::GameWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::GameWindow)
{
ui->setupUi(this);
ui->menubar->setVisible(false);
connect(ui->mainScreen, &MainScreen::startGame, ui->gameScreen, &GameScreen::startGame);
connect(ui->mainScreen, &MainScreen::startGame, this, [=] {
ui->stackedWidget->setCurrentWidget(ui->gameScreen);
});
FocusPointer::enableAutomaticFocusPointer();
}
GameWindow::~GameWindow()
{
delete ui;
}

40
gamewindow.h Normal file
View file

@ -0,0 +1,40 @@
/****************************************
*
* INSERT-PROJECT-NAME-HERE - INSERT-GENERIC-NAME-HERE
* Copyright (C) 2019 Victor Tran
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* *************************************/
#ifndef GAMEWINDOW_H
#define GAMEWINDOW_H
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui { class GameWindow; }
QT_END_NAMESPACE
class GameWindow : public QMainWindow
{
Q_OBJECT
public:
GameWindow(QWidget *parent = nullptr);
~GameWindow();
private:
Ui::GameWindow *ui;
};
#endif // GAMEWINDOW_H

77
gamewindow.ui Normal file
View file

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>GameWindow</class>
<widget class="QMainWindow" name="GameWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>569</width>
<height>438</height>
</rect>
</property>
<property name="windowTitle">
<string>Entertaining Mines</string>
</property>
<widget class="QWidget" name="centralwidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Ignored" vsizetype="Ignored">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QStackedWidget" name="stackedWidget">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="MainScreen" name="mainScreen"/>
<widget class="GameScreen" name="gameScreen"/>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>569</width>
<height>22</height>
</rect>
</property>
</widget>
</widget>
<customwidgets>
<customwidget>
<class>MainScreen</class>
<extends>QWidget</extends>
<header>screens/mainscreen.h</header>
<container>1</container>
</customwidget>
<customwidget>
<class>GameScreen</class>
<extends>QWidget</extends>
<header>screens/gamescreen.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

34
main.cpp Normal file
View file

@ -0,0 +1,34 @@
/****************************************
*
* INSERT-PROJECT-NAME-HERE - INSERT-GENERIC-NAME-HERE
* Copyright (C) 2019 Victor Tran
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* *************************************/
#include "gamewindow.h"
#include <QApplication>
#include <entertaining.h>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Entertaining::initialize();
GameWindow w;
w.show();
return a.exec();
}

10
resources.qrc Normal file
View file

@ -0,0 +1,10 @@
<RCC>
<qresource prefix="/">
<file>tiles/background.svg</file>
<file>tiles/backgroundHov.svg</file>
<file>tiles/backgroundRev.svg</file>
<file>tiles/flag.svg</file>
<file>tiles/mine.svg</file>
<file>tiles/flagNot.svg</file>
</qresource>
</RCC>

245
screens/gamescreen.cpp Normal file
View file

@ -0,0 +1,245 @@
/****************************************
*
* INSERT-PROJECT-NAME-HERE - INSERT-GENERIC-NAME-HERE
* Copyright (C) 2019 Victor Tran
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* *************************************/
#include "gamescreen.h"
#include "ui_gamescreen.h"
#include <the-libs_global.h>
#include <QIcon>
#include <QRandomGenerator>
#include "game/gametile.h"
#include <pauseoverlay.h>
#include "pausescreen.h"
#include "dialogueoverlay.h"
#include <musicengine.h>
#include <QUrl>
#include <QShortcut>
struct GameScreenPrivate {
QVector<GameTile*> tiles;
int width = 0;
int mines = 0;
int remainingTileCount = 0;
int minesRemaining = 0;
bool gameStarted = false;
bool gameIsOver = false;
DialogueOverlay* dialogue;
};
GameScreen::GameScreen(QWidget *parent) :
QWidget(parent),
ui(new Ui::GameScreen)
{
ui->setupUi(this);
d = new GameScreenPrivate();
d->dialogue = new DialogueOverlay(this);
connect(d->dialogue, QOverload<QString>::of(&DialogueOverlay::progressDialogue), this, [=](QString selectedOption) {
d->dialogue->dismiss();
});
QShortcut* pauseShortcut = new QShortcut(QKeySequence(Qt::Key_Escape), this);
connect(pauseShortcut, &QShortcut::activated, this, [=] {
ui->menuButton->click();
});
}
GameScreen::~GameScreen()
{
delete ui;
delete d;
}
bool GameScreen::hasGameStarted()
{
return d->gameStarted;
}
bool GameScreen::isGameOver()
{
return d->gameIsOver;
}
QSize GameScreen::gameArea()
{
return ui->gameArea->size();
}
GameTile*GameScreen::tileAt(QPoint location)
{
return d->tiles.at(pointToIndex(location));
}
QSize GameScreen::boardDimensions()
{
return QSize(d->width, d->tiles.count() / d->width);
}
void GameScreen::revealedTile()
{
d->remainingTileCount--;
if (d->remainingTileCount == 0) {
performGameOver();
}
}
void GameScreen::flagChanged(bool didFlag)
{
if (didFlag) {
d->minesRemaining--;
} else {
d->minesRemaining++;
}
ui->minesRemainingLabel->setText(QString::number(d->minesRemaining));
}
QPoint GameScreen::indexToPoint(int index)
{
return QPoint(index % d->width, index / d->width);
}
int GameScreen::pointToIndex(QPoint point)
{
return point.y() * d->width + point.x();
}
void GameScreen::resizeEvent(QResizeEvent*event)
{
int targetHeight = qMax(SC_DPI(50), static_cast<int>(this->height() * 0.05));
int fontHeight = targetHeight - 18;
QFont fnt = ui->hudWidget->font();
fnt.setPixelSize(fontHeight);
ui->hudWidget->setFont(fnt);
QSize iconSize(fontHeight, fontHeight);
ui->menuButton->setIconSize(iconSize);
ui->mineIcon->setPixmap(QIcon(":/tiles/mine.svg").pixmap(iconSize));
emit boardResized();
}
void GameScreen::startGame(int width, int height, int mines)
{
d->width = width;
d->mines = mines;
//Ensure that the number of mines is valid for this game
if (mines > width * height - 1) mines = width * height - 1;
//Clear out the tiles
for (GameTile* tile : d->tiles) {
ui->gameGrid->removeWidget(tile);
}
d->tiles.clear();
//Create new tiles
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
GameTile* tile = new GameTile(this, x, y);
ui->gameGrid->addWidget(tile, x, y);
d->tiles.append(tile);
}
}
d->gameStarted = false;
d->gameIsOver = false;
d->remainingTileCount = width * height - mines;
d->minesRemaining = mines + 1;
flagChanged(true);
MusicEngine::setBackgroundMusic(QUrl("qrc:/audio/crypto.ogg"));
MusicEngine::playBackgroundMusic();
MusicEngine::playSoundEffect(MusicEngine::Selection);
}
void GameScreen::distributeMines(QPoint clickLocation)
{
Q_ASSERT(!d->gameStarted);
//Distribute the mines across the board
for (int i = 0; i < d->mines; i++) {
int tileNumber = QRandomGenerator::global()->bounded(d->tiles.count());
QPoint location = indexToPoint(tileNumber);
if (location == clickLocation) continue; //Never spawn a mine on the user's click point
GameTile* tile = d->tiles.at(tileNumber);
if (tile->isMine()) continue; //This tile is already a mine
//Set this tile as a mine
tile->setIsMine(true);
}
d->gameStarted = true;
}
void GameScreen::performGameOver()
{
d->gameIsOver = true;
if (d->remainingTileCount == 0) {
d->dialogue->setMultiDialogue({
tr("Congratulations! You won!"),
tr("What do you want to do now?")
}, {
{"review", tr("Review the game")},
{"newgame", tr("Start a new game")},
{"mainmenu", tr("Return to the Main Menu")},
});
} else {
d->dialogue->setMultiDialogue({
tr("You stepped on a mine"),
tr("What do you want to do now?")
}, {
{"review", tr("Review the game")},
{"newgame", tr("Start a new game")},
{"mainmenu", tr("Return to the Main Menu")},
});
}
for (GameTile* tile : d->tiles) {
tile->update();
}
}
void GameScreen::on_menuButton_clicked()
{
MusicEngine::pauseBackgroundMusic();
MusicEngine::playSoundEffect(MusicEngine::Pause);
PauseScreen* screen = new PauseScreen();
PauseOverlay* overlay = new PauseOverlay(screen);
overlay->showOverlay(this);
connect(screen, &PauseScreen::resume, this, [=] {
MusicEngine::playSoundEffect(MusicEngine::Backstep);
MusicEngine::playBackgroundMusic();
overlay->hideOverlay();
overlay->deleteLater();
screen->deleteLater();
});
screen->setFocus();
}

74
screens/gamescreen.h Normal file
View file

@ -0,0 +1,74 @@
/****************************************
*
* INSERT-PROJECT-NAME-HERE - INSERT-GENERIC-NAME-HERE
* Copyright (C) 2019 Victor Tran
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* *************************************/
#ifndef GAMESCREEN_H
#define GAMESCREEN_H
#include <QWidget>
namespace Ui {
class GameScreen;
}
struct GameScreenPrivate;
class GameTile;
class GameScreen : public QWidget
{
Q_OBJECT
public:
explicit GameScreen(QWidget *parent = nullptr);
~GameScreen();
bool hasGameStarted(); //Returns whether the user has clicked on the first tile yet
bool isGameOver();
QSize gameArea();
GameTile* tileAt(QPoint location);
public slots:
void startGame(int width, int height, int mines);
void distributeMines(QPoint clickLocation);
void performGameOver();
signals:
void boardResized();
protected:
friend GameTile;
QSize boardDimensions();
void revealedTile();
void flagChanged(bool didFlag);
private slots:
void on_menuButton_clicked();
private:
Ui::GameScreen *ui;
GameScreenPrivate* d;
QPoint indexToPoint(int index);
int pointToIndex(QPoint point);
void resizeEvent(QResizeEvent* event);
};
#endif // GAMESCREEN_H

178
screens/gamescreen.ui Normal file
View file

@ -0,0 +1,178 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>GameScreen</class>
<widget class="QWidget" name="GameScreen">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QWidget" name="hudWidget" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QPushButton" name="menuButton">
<property name="focusPolicy">
<enum>Qt::NoFocus</enum>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset theme="application-menu">
<normaloff>.</normaloff>.</iconset>
</property>
<property name="flat">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="mineIcon">
<property name="text">
<string notr="true">TextLabel</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="minesRemainingLabel">
<property name="text">
<string notr="true">300</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="gameArea" native="true">
<layout class="QGridLayout" name="gridLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<property name="spacing">
<number>0</number>
</property>
<item row="1" column="1">
<layout class="QGridLayout" name="gameGrid">
<property name="spacing">
<number>0</number>
</property>
</layout>
</item>
<item row="1" column="2">
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>161</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="1">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>102</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="1">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>125</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>165</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>

61
screens/mainscreen.cpp Normal file
View file

@ -0,0 +1,61 @@
/****************************************
*
* INSERT-PROJECT-NAME-HERE - INSERT-GENERIC-NAME-HERE
* Copyright (C) 2019 Victor Tran
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* *************************************/
#include "mainscreen.h"
#include "ui_mainscreen.h"
#include <gamepadbuttons.h>
MainScreen::MainScreen(QWidget *parent) :
QWidget(parent),
ui(new Ui::MainScreen)
{
ui->setupUi(this);
ui->AHudButton->setText(tr("%1 Select").arg(GamepadButtons::stringForButton(QGamepadManager::ButtonA)));
ui->BHudButton->setText(tr("%2 Exit").arg(GamepadButtons::stringForButton(QGamepadManager::ButtonB)));
ui->exitButton->setProperty("type", "destructive");
}
MainScreen::~MainScreen()
{
delete ui;
}
void MainScreen::resizeEvent(QResizeEvent*event)
{
ui->leftSpacing->changeSize(this->width() * 0.4, 0, QSizePolicy::Fixed, QSizePolicy::Fixed);
this->layout()->invalidate();
}
void MainScreen::on_startEasy_clicked()
{
emit startGame(9, 9, 10);
}
void MainScreen::on_startIntermediate_clicked()
{
emit startGame(16, 16, 40);
}
void MainScreen::on_startDifficult_clicked()
{
emit startGame(30, 16, 99);
}

52
screens/mainscreen.h Normal file
View file

@ -0,0 +1,52 @@
/****************************************
*
* INSERT-PROJECT-NAME-HERE - INSERT-GENERIC-NAME-HERE
* Copyright (C) 2019 Victor Tran
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* *************************************/
#ifndef MAINSCREEN_H
#define MAINSCREEN_H
#include <QWidget>
namespace Ui {
class MainScreen;
}
class MainScreen : public QWidget
{
Q_OBJECT
public:
explicit MainScreen(QWidget *parent = nullptr);
~MainScreen();
signals:
void startGame(int width, int height, int mines);
private slots:
void on_startEasy_clicked();
void on_startIntermediate_clicked();
void on_startDifficult_clicked();
private:
Ui::MainScreen *ui;
void resizeEvent(QResizeEvent* event);
};
#endif // MAINSCREEN_H

229
screens/mainscreen.ui Normal file
View file

@ -0,0 +1,229 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainScreen</class>
<widget class="QWidget" name="MainScreen">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>664</width>
<height>629</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<spacer name="leftSpacing">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
</property>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label">
<property name="font">
<font>
<pointsize>30</pointsize>
</font>
</property>
<property name="text">
<string>Entertaining Mines</string>
</property>
<property name="margin">
<number>9</number>
</property>
</widget>
</item>
<item>
<widget class="QCommandLinkButton" name="startEasy">
<property name="text">
<string>Easy Game</string>
</property>
<property name="description">
<string>Start a 9×9 game with 10 mines</string>
</property>
</widget>
</item>
<item>
<widget class="QCommandLinkButton" name="startIntermediate">
<property name="text">
<string>Intermediate Game</string>
</property>
<property name="description">
<string>Start a 16×16 game with 40 mines</string>
</property>
</widget>
</item>
<item>
<widget class="QCommandLinkButton" name="startDifficult">
<property name="text">
<string>Difficult Game</string>
</property>
<property name="description">
<string>Start a 30×16 game with 99 mines</string>
</property>
</widget>
</item>
<item>
<widget class="QCommandLinkButton" name="startCustom">
<property name="text">
<string>Custom Game</string>
</property>
<property name="description">
<string>Select the board size and number of mines to play with</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QCommandLinkButton" name="commandLinkButton">
<property name="text">
<string>Load Game</string>
</property>
<property name="description">
<string>Open a game that you have saved</string>
</property>
</widget>
</item>
<item>
<widget class="QCommandLinkButton" name="commandLinkButton_2">
<property name="text">
<string>Settings</string>
</property>
<property name="description">
<string>Go to Settings</string>
</property>
</widget>
</item>
<item>
<widget class="QCommandLinkButton" name="exitButton">
<property name="text">
<string>Exit to Desktop</string>
</property>
<property name="description">
<string>Leave Entertaining Mines</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="GamepadLabel" name="AHudButton">
<property name="text">
<string notr="true">TextLabel</string>
</property>
</widget>
</item>
<item>
<widget class="GamepadLabel" name="BHudButton">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>GamepadLabel</class>
<extends>QLabel</extends>
<header location="global">gamepadlabel.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

59
screens/pausescreen.cpp Normal file
View file

@ -0,0 +1,59 @@
/****************************************
*
* INSERT-PROJECT-NAME-HERE - INSERT-GENERIC-NAME-HERE
* Copyright (C) 2019 Victor Tran
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* *************************************/
#include "pausescreen.h"
#include "ui_pausescreen.h"
#include <QShortcut>
#include <gamepadbuttons.h>
PauseScreen::PauseScreen(QWidget *parent) :
QWidget(parent),
ui(new Ui::PauseScreen)
{
ui->setupUi(this);
this->setFocusProxy(ui->resumeButton);
ui->AHudButton->setText(tr("%1 Select").arg(GamepadButtons::stringForButton(QGamepadManager::ButtonA)));
ui->BHudButton->setText(tr("%2 Resume").arg(GamepadButtons::stringForButton(QGamepadManager::ButtonB)));
ui->mainMenuButton->setProperty("type", "destructive");
QShortcut* pauseShortcut = new QShortcut(QKeySequence(Qt::Key_Escape), this);
connect(pauseShortcut, &QShortcut::activatedAmbiguously, this, [=] {
ui->resumeButton->click();
});
}
PauseScreen::~PauseScreen()
{
delete ui;
}
void PauseScreen::on_resumeButton_clicked()
{
emit resume();
}
void PauseScreen::resizeEvent(QResizeEvent*event)
{
ui->leftSpacing->changeSize(this->width() * 0.1, 0, QSizePolicy::Fixed, QSizePolicy::Fixed);
this->layout()->invalidate();
}

48
screens/pausescreen.h Normal file
View file

@ -0,0 +1,48 @@
/****************************************
*
* INSERT-PROJECT-NAME-HERE - INSERT-GENERIC-NAME-HERE
* Copyright (C) 2019 Victor Tran
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* *************************************/
#ifndef PAUSESCREEN_H
#define PAUSESCREEN_H
#include <QWidget>
namespace Ui {
class PauseScreen;
}
class PauseScreen : public QWidget
{
Q_OBJECT
public:
explicit PauseScreen(QWidget *parent = nullptr);
~PauseScreen();
signals:
void resume();
private slots:
void on_resumeButton_clicked();
private:
Ui::PauseScreen *ui;
void resizeEvent(QResizeEvent* event);
};
#endif // PAUSESCREEN_H

189
screens/pausescreen.ui Normal file
View file

@ -0,0 +1,189 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PauseScreen</class>
<widget class="QWidget" name="PauseScreen">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>710</width>
<height>644</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<spacer name="leftSpacing">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="spacing">
<number>0</number>
</property>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="label">
<property name="font">
<font>
<pointsize>30</pointsize>
</font>
</property>
<property name="text">
<string>Pause</string>
</property>
<property name="margin">
<number>9</number>
</property>
</widget>
</item>
<item>
<widget class="QCommandLinkButton" name="resumeButton">
<property name="text">
<string>Resume</string>
</property>
<property name="description">
<string>Resume the game</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QCommandLinkButton" name="commandLinkButton_2">
<property name="text">
<string>Settings</string>
</property>
<property name="description">
<string>Go to Settings</string>
</property>
</widget>
</item>
<item>
<widget class="QCommandLinkButton" name="mainMenuButton">
<property name="text">
<string>Main Menu</string>
</property>
<property name="description">
<string>Abandon this game</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="GamepadLabel" name="AHudButton">
<property name="text">
<string notr="true">TextLabel</string>
</property>
</widget>
</item>
<item>
<widget class="GamepadLabel" name="BHudButton">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>GamepadLabel</class>
<extends>QLabel</extends>
<header location="global">gamepadlabel.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

77
tiles/background.svg Normal file
View file

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="32"
height="32"
viewBox="0 0 8.4666665 8.4666669"
version="1.1"
id="svg8"
inkscape:version="0.92.4 5da689c313, 2019-01-14"
sodipodi:docname="background.svg">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="22.4"
inkscape:cx="15.140271"
inkscape:cy="15.9107"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="true"
units="px"
inkscape:window-width="1920"
inkscape:window-height="1046"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1">
<inkscape:grid
type="xygrid"
id="grid815"
empspacing="4" />
<inkscape:grid
type="xygrid"
id="grid817"
empspacing="1"
originy="0.13229167"
originx="0.13229167"
dotted="true" />
</sodipodi:namedview>
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-288.53332)">
<rect
style="opacity:1;fill:#646464;fill-opacity:1;stroke:none;stroke-width:0.26499999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal"
id="rect840"
width="8.4666662"
height="8.4666662"
x="0"
y="288.53333" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

77
tiles/backgroundHov.svg Normal file
View file

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="32"
height="32"
viewBox="0 0 8.4666665 8.4666669"
version="1.1"
id="svg8"
inkscape:version="0.92.4 5da689c313, 2019-01-14"
sodipodi:docname="backgroundHov.svg">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="22.4"
inkscape:cx="15.140271"
inkscape:cy="15.9107"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="true"
units="px"
inkscape:window-width="1920"
inkscape:window-height="1046"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1">
<inkscape:grid
type="xygrid"
id="grid815"
empspacing="4" />
<inkscape:grid
type="xygrid"
id="grid817"
empspacing="1"
originy="0.13229167"
originx="0.13229167"
dotted="true" />
</sodipodi:namedview>
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-288.53332)">
<rect
style="opacity:1;fill:#969696;fill-opacity:1;stroke:none;stroke-width:0.26499999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal"
id="rect840"
width="8.4666662"
height="8.4666662"
x="0"
y="288.53333" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

77
tiles/backgroundRev.svg Normal file
View file

@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="32"
height="32"
viewBox="0 0 8.4666665 8.4666669"
version="1.1"
id="svg8"
inkscape:version="0.92.4 5da689c313, 2019-01-14"
sodipodi:docname="backgroundRev.svg">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="22.4"
inkscape:cx="15.140271"
inkscape:cy="15.9107"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="true"
units="px"
inkscape:window-width="1920"
inkscape:window-height="1046"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1">
<inkscape:grid
type="xygrid"
id="grid815"
empspacing="4" />
<inkscape:grid
type="xygrid"
id="grid817"
empspacing="1"
originy="0.13229167"
originx="0.13229167"
dotted="true" />
</sodipodi:namedview>
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-288.53332)">
<rect
style="opacity:1;fill:#323232;fill-opacity:1;stroke:none;stroke-width:0.26499999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal"
id="rect840"
width="8.4666662"
height="8.4666662"
x="0"
y="288.53333" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

75
tiles/flag.svg Normal file
View file

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="32"
height="32"
viewBox="0 0 8.4666665 8.4666669"
version="1.1"
id="svg8"
inkscape:version="0.92.4 5da689c313, 2019-01-14"
sodipodi:docname="flag.svg">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="22.4"
inkscape:cx="16.488072"
inkscape:cy="15.899004"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="true"
units="px"
inkscape:window-width="1920"
inkscape:window-height="1046"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1">
<inkscape:grid
type="xygrid"
id="grid815"
empspacing="4" />
<inkscape:grid
type="xygrid"
id="grid817"
empspacing="1"
originy="0.13229167"
originx="0.13229167"
dotted="true" />
</sodipodi:namedview>
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-288.53332)">
<path
style="opacity:1;fill:#c83232;fill-opacity:1;stroke:none;stroke-width:1.00157475;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal"
d="M 8 4 L 8 28 L 12 28 L 12 16 L 24 16 L 24 4 L 12 4 L 8 4 z "
transform="matrix(0.26458333,0,0,0.26458333,0,288.53332)"
id="rect886" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

85
tiles/flagNot.svg Normal file
View file

@ -0,0 +1,85 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="32"
height="32"
viewBox="0 0 8.4666665 8.4666669"
version="1.1"
id="svg8"
inkscape:version="0.92.4 5da689c313, 2019-01-14"
sodipodi:docname="flagNot.svg">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="15.839192"
inkscape:cx="13.152968"
inkscape:cy="14.96101"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="true"
units="px"
inkscape:window-width="1920"
inkscape:window-height="1046"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1">
<inkscape:grid
type="xygrid"
id="grid815"
empspacing="4" />
<inkscape:grid
type="xygrid"
id="grid817"
empspacing="1"
originy="0.13229167"
originx="0.13229167"
dotted="true" />
</sodipodi:namedview>
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-288.53332)">
<path
style="opacity:1;fill:#c83232;fill-opacity:1;stroke:none;stroke-width:1.00157475;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal"
d="M 8 4 L 8 28 L 12 28 L 12 16 L 24 16 L 24 4 L 12 4 L 8 4 z "
transform="matrix(0.26458333,0,0,0.26458333,0,288.53332)"
id="rect886" />
<path
style="fill:none;stroke:#fff800;stroke-width:0.52916667;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
d="m 0.79374999,289.32707 6.87916661,6.87917"
id="path1505"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#fff800;stroke-width:0.52916667;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
d="m 7.6729166,289.32707 -6.87916661,6.87917"
id="path1507"
inkscape:connector-curvature="0" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

88
tiles/mine.svg Normal file
View file

@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="32"
height="32"
viewBox="0 0 8.4666665 8.4666669"
version="1.1"
id="svg8"
inkscape:version="0.92.4 5da689c313, 2019-01-14"
sodipodi:docname="mine.svg">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="22.4"
inkscape:cx="16.488072"
inkscape:cy="15.899004"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="true"
units="px"
inkscape:window-width="1920"
inkscape:window-height="1046"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1">
<inkscape:grid
type="xygrid"
id="grid815"
empspacing="4" />
<inkscape:grid
type="xygrid"
id="grid817"
empspacing="1"
originy="0.13229167"
originx="0.13229167"
dotted="true" />
</sodipodi:namedview>
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-288.53332)">
<circle
style="opacity:1;fill:#ff9600;fill-opacity:1;stroke:none;stroke-width:0.26499999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal"
id="path910"
cx="4.2333331"
cy="292.76666"
r="3.175" />
<circle
style="opacity:1;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:0.26499999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal"
id="path931"
cx="5.291667"
cy="291.70834"
r="2.6458335" />
<circle
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:0.26499999;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:normal"
id="path933"
cx="4.2333331"
cy="292.76666"
r="1.0583333" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.8 KiB