From 651b321cb2cb0545d475ead324e1b1db086b3f0e Mon Sep 17 00:00:00 2001 From: Elvina <99557373+Ar444ri@users.noreply.github.com> Date: Sun, 10 Dec 2023 23:44:57 +0300 Subject: [PATCH] Add files via upload --- GraphicsFrameworkSample.pro | 38 +++++ main.cpp | 22 +-- src/dragitem/dragitem.cpp | 30 ++++ src/dragitem/dragitem.h | 30 ++++ src/game.cpp | 131 +++++++++++++++++ src/game.h | 52 +++++++ src/itemswidget/itemswidget.cpp | 54 +++++++ src/itemswidget/itemswidget.h | 25 ++++ src/mainwindow/mainwindow.cpp | 67 +++++++++ src/mainwindow/mainwindow.h | 40 ++++++ src/mainwindow/mainwindow.ui | 218 ++++++++++++++++++++++++++++ src/scene/scene.cpp | 139 ++++++++++++++++++ src/scene/scene.h | 38 +++++ src/scene_items/itemsfactory.cpp | 26 ++++ src/scene_items/itemsfactory.h | 21 +++ src/scene_items/sceneitem.cpp | 123 ++++++++++++++++ src/scene_items/sceneitem.h | 46 ++++++ ui_mainwindow.h | 235 +++++++++++++++++++++++++++++++ 18 files changed, 1324 insertions(+), 11 deletions(-) create mode 100644 GraphicsFrameworkSample.pro create mode 100644 src/dragitem/dragitem.cpp create mode 100644 src/dragitem/dragitem.h create mode 100644 src/game.cpp create mode 100644 src/game.h create mode 100644 src/itemswidget/itemswidget.cpp create mode 100644 src/itemswidget/itemswidget.h create mode 100644 src/mainwindow/mainwindow.cpp create mode 100644 src/mainwindow/mainwindow.h create mode 100644 src/mainwindow/mainwindow.ui create mode 100644 src/scene/scene.cpp create mode 100644 src/scene/scene.h create mode 100644 src/scene_items/itemsfactory.cpp create mode 100644 src/scene_items/itemsfactory.h create mode 100644 src/scene_items/sceneitem.cpp create mode 100644 src/scene_items/sceneitem.h create mode 100644 ui_mainwindow.h diff --git a/GraphicsFrameworkSample.pro b/GraphicsFrameworkSample.pro new file mode 100644 index 0000000..d8e4392 --- /dev/null +++ b/GraphicsFrameworkSample.pro @@ -0,0 +1,38 @@ +QT += core gui + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +CONFIG += c++17 + +# You can make your code fail to compile if it uses deprecated APIs. +# In order to do so, uncomment the following line. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +SOURCES += \ + main.cpp \ + src/dragitem/dragitem.cpp \ + src/game.cpp \ + src/itemswidget/itemswidget.cpp \ + src/mainwindow/mainwindow.cpp \ + src/scene/scene.cpp \ + src/scene_items/itemsfactory.cpp \ + src/scene_items/sceneitem.cpp \ + +HEADERS += \ + src/dragitem/dragitem.h \ + src/game.h \ + src/itemswidget/itemswidget.h \ + src/mainwindow/mainwindow.h \ + src/scene/scene.h \ + src/scene_items/itemsfactory.h \ + src/scene_items/sceneitem.h \ + +FORMS += \ + src/mainwindow/mainwindow.ui + +INCLUDEPATH += $$PWD/src/itemswidget + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target diff --git a/main.cpp b/main.cpp index e9562cc..7ad2410 100644 --- a/main.cpp +++ b/main.cpp @@ -1,11 +1,11 @@ -#include "mainwindow.h" - -#include - -int main(int argc, char *argv[]) -{ - QApplication a(argc, argv); - MainWindow w; - w.show(); - return a.exec(); -} +#include + +#include + +int main(int argc, char *argv[]) { + QApplication a(argc, argv); + MainWindow w; + w.setWindowTitle("Да начнутся голодные игры"); + w.show(); + return a.exec(); +} diff --git a/src/dragitem/dragitem.cpp b/src/dragitem/dragitem.cpp new file mode 100644 index 0000000..eb3dfa9 --- /dev/null +++ b/src/dragitem/dragitem.cpp @@ -0,0 +1,30 @@ +#include "dragitem.h" + +#include +#include + +DragItem::DragItem(const QString &type, QWidget *parent) + : QWidget{parent}, QListWidgetItem() { + graphicsItem_ = ItemsFactory::Create(type); + type_ = type; + + QRect geometry = graphicsItem_->boundingRect().toRect(); + setGeometry(geometry); + int additionalHeight = 2; + setSizeHint(QSize(geometry.width(), geometry.height() + additionalHeight)); +} + +void DragItem::paintEvent(QPaintEvent *event) { + Q_UNUSED(event) + + QPainter painter(this); + painter.setPen(graphicsItem_->pen()); + painter.setBrush(graphicsItem_->brush()); + + QStyleOptionGraphicsItem itemOption; + graphicsItem_->paint(&painter, &itemOption, nullptr); +} + +SceneItem *DragItem::GetGraphicsItem() const { return graphicsItem_; } + +QString DragItem::GetType() const { return type_; } diff --git a/src/dragitem/dragitem.h b/src/dragitem/dragitem.h new file mode 100644 index 0000000..d6e150e --- /dev/null +++ b/src/dragitem/dragitem.h @@ -0,0 +1,30 @@ +#ifndef DRAGITEM_H +#define DRAGITEM_H + +#include + +#include +#include +#include + +class DragItem : public QWidget, public QListWidgetItem { + Q_OBJECT + public: + explicit DragItem(const QString &type, QWidget *parent = nullptr); + + protected: + void paintEvent(QPaintEvent *event); + + public: + SceneItem *GetGraphicsItem() const; + QString GetType() const; + + public: + static const inline QString kMimeFormat = "application/x-dnditemdata"; + + private: + SceneItem *graphicsItem_; + QString type_; +}; + +#endif // DRAGITEM_H diff --git a/src/game.cpp b/src/game.cpp new file mode 100644 index 0000000..d65ae21 --- /dev/null +++ b/src/game.cpp @@ -0,0 +1,131 @@ +#include "game.h" + +#include +#include +#include + +Game::Game(Scene &scene, QWidget *parent) : QWidget(parent), scene_(scene) { + collisionColor_ = Qt::red; + originColor_ = Qt::yellow; +} + +void Game::StartGame() { + player_ = scene_.GetPlayer(); + if (player_ == nullptr) { + return; + } else { + MainWindow *mainWindow = qobject_cast(parent()); + + if (mainWindow) { + mainWindow->SetListWidgetEnabled(false); + } + + gameTimer_.start(intervalTime_, this); + qDebug() << player_; + } +} + +void Game::StopGame() { + if (!gameTimer_.isActive()) { + return; + } + MainWindow *mainWindow = qobject_cast(parent()); + qDebug() << parent(); + if (mainWindow) { + mainWindow->SetListWidgetEnabled(true); + } + gameTimer_.stop(); +} + +void Game::ShowAbout() { + QMessageBox::information( + this, "Справка", + "Нажимаем кнопочку начать игру и тыкаем влево/вправо/вверх/вниз в " + "зависимости от того,куда хотите его отправить"); +} + +void Game::timerEvent(QTimerEvent *event) { + if (event->timerId() == gameTimer_.timerId() && player_) { + int newX = + player_->pos().x() + player_->GetDirectionX() * player_->GetStep(); + int newY = + player_->pos().y() + player_->GetDirectionY() * player_->GetStep(); + + if (IsOutOfBounds(newX, newY) || HasCollision()) { + player_->ChangeBrush(collisionColor_); + player_->InvertDirection(); + } + player_->Move(); + } else { + QWidget::timerEvent(event); + } +} + +void Game::WonGame() { + scene_.SetFiguresInteraction(true); + QMessageBox::information( + this, "Так держать!!!", + "Вас конечно зовут не Виктор, но здесь вы победили)"); + MainWindow *mainWindow = qobject_cast(parent()); + qDebug() << parent(); + if (mainWindow) { + mainWindow->SetListWidgetEnabled(true); + } + score_ = 0; + UpdateScore(score_); +} +void Game::UpdateScore(int score) { + score_ += score; + qDebug() << score_; + emit ScoreChanged(score_); +} + +void Game::DeleteCoin(SceneItem *coin) { + if (scene_.DeleteCoin(coin)) { + int score = 1; + UpdateScore(score); + score = score + 1; + if (scene_.GetCoins().isEmpty()) { + WonGame(); + StopGame(); + } + } +} + +bool Game::HasCollision() { + const QList &walls = scene_.GetWalls(); + const QList &coins = scene_.GetCoins(); + + for (SceneItem *wall : walls) { + if (player_->collidesWithItem(wall)) { + return true; + } + } + + for (SceneItem *coin : coins) { + if (player_->collidesWithItem(coin)) { + DeleteCoin(coin); + } + } + + player_->ChangeBrush(originColor_); + return false; +} + +bool Game::IsOutOfBounds(int newX, int newY) { + qDebug() << newX << newY; + + const QRectF sceneRect = scene_.sceneRect(); + qDebug() << sceneRect; + QRectF playerRect(newX, newY, player_->sceneBoundingRect().width(), + player_->sceneBoundingRect().height()); + + if (newX < sceneRect.left() || + newX + playerRect.width() > sceneRect.right() || newY < sceneRect.top() || + newY + playerRect.height() > sceneRect.bottom()) { + qDebug() << "Игрок достиг границы"; + return true; + } + + return false; +} diff --git a/src/game.h b/src/game.h new file mode 100644 index 0000000..a2b69b9 --- /dev/null +++ b/src/game.h @@ -0,0 +1,52 @@ +#ifndef GAME_H +#define GAME_H + +#include +#include +#include +#include + +#include +#include +#include +#include + +class ItemsFactory; +class DragItem; +class Game : public QWidget { + Q_OBJECT + public: + Game(Scene& scene, QWidget* parent = nullptr); + + public slots: + void StartGame(); + void StopGame(); + void ShowAbout(); + + signals: + void ScoreChanged(int score); + + protected: + void timerEvent(QTimerEvent* event); + + private: + void WonGame(); + void UpdateScore(int addScore); + void DeleteCoin(SceneItem* coin); + bool HasCollision(); + bool IsOutOfBounds(int newX, int newY); + + private: + uint intervalTime_ = 200; + uint score_ = 0; + + Scene& scene_; + SceneItem* player_; + + QColor collisionColor_; + QBrush originColor_; + + QBasicTimer gameTimer_; +}; + +#endif // GAME_H diff --git a/src/itemswidget/itemswidget.cpp b/src/itemswidget/itemswidget.cpp new file mode 100644 index 0000000..02fb972 --- /dev/null +++ b/src/itemswidget/itemswidget.cpp @@ -0,0 +1,54 @@ +#include "itemswidget.h" + +#include +#include +#include +#include +#include +#include + +ItemsWidget::ItemsWidget(QWidget *parent) : QListWidget(parent) { + setSelectionMode(SingleSelection); + setDragEnabled(true); +} + +void ItemsWidget::mousePressEvent(QMouseEvent *event) { + dragStartPosition_ = event->pos(); + dragableItem_ = dynamic_cast(itemAt(dragStartPosition_)); + + QListWidget::mousePressEvent(event); +} + +void ItemsWidget::mouseMoveEvent(QMouseEvent *event) { + if ((event->buttons() == Qt::LeftButton) == false || + dragableItem_ == nullptr) { + return; + } + + QByteArray itemData; + QDataStream dataStream(&itemData, QIODevice::WriteOnly); + dataStream << dragableItem_->GetType(); + + QMimeData *mimeData = new QMimeData; + mimeData->setData(dragableItem_->kMimeFormat, itemData); + + QDrag *drag = new QDrag(this); + drag->setMimeData(mimeData); + drag->setPixmap(GetPreview()); + + drag->exec(Qt::CopyAction | Qt::MoveAction); +} + +QPixmap ItemsWidget::GetPreview() const { + auto *item = dragableItem_->GetGraphicsItem(); + + QPixmap pixmap(item->boundingRect().size().toSize()); + pixmap.fill(Qt::transparent); + + QPainter painter(&pixmap); + painter.setPen(item->pen()); + painter.setBrush(item->brush()); + painter.drawPath(item->shape()); + + return pixmap; +} diff --git a/src/itemswidget/itemswidget.h b/src/itemswidget/itemswidget.h new file mode 100644 index 0000000..4e32f10 --- /dev/null +++ b/src/itemswidget/itemswidget.h @@ -0,0 +1,25 @@ +#ifndef ITEMSWIDGET_H +#define ITEMSWIDGET_H + +#include + +#include + +class ItemsWidget : public QListWidget { + Q_OBJECT + public: + explicit ItemsWidget(QWidget *parent = nullptr); + + protected: + void mousePressEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + + private: + QPixmap GetPreview() const; + + private: + QPoint dragStartPosition_; + DragItem *dragableItem_; +}; + +#endif // ITEMSWIDGET_H diff --git a/src/mainwindow/mainwindow.cpp b/src/mainwindow/mainwindow.cpp new file mode 100644 index 0000000..367f11f --- /dev/null +++ b/src/mainwindow/mainwindow.cpp @@ -0,0 +1,67 @@ +#include "mainwindow.h" + +#include + +#include +#include + +#include "ui_mainwindow.h" + +MainWindow::MainWindow(QWidget *parent) + : QMainWindow(parent), ui_(new Ui::MainWindow) { + ui_->setupUi(this); + + SetUi(); + SetConnections(); +} + +MainWindow::~MainWindow() { delete ui_; } + +void MainWindow::SetListWidgetEnabled(bool enabled) { + ui_->listWidget->setEnabled(enabled); +} + +void MainWindow::UpdateScoreLabel(int score) { + ui_->counterLCD->display(score); +} + +void MainWindow::SetConnections() { + connect(ui_->rotateButton, &QPushButton::clicked, scene_, + &Scene::RotateSelectedItems); + connect(ui_->zoomInButton, &QPushButton::clicked, this, + [=]() { scene_->ScaleSelectedItems(itemScaleFactor_); }); + connect(ui_->zoomOutButton, &QPushButton::clicked, this, + [=]() { scene_->ScaleSelectedItems(-itemScaleFactor_); }); + connect(ui_->resetZoomButton, &QPushButton::clicked, scene_, + &Scene::ResetSelectedItemsScale); + connect(ui_->removeButton, &QPushButton::clicked, scene_, + &Scene::RemoveSelectedItems); + connect(ui_->startButton, &QPushButton::clicked, game_, &Game::StartGame); + connect(ui_->graphicsViewRotateButton, &QPushButton::clicked, this, + [=]() { ui_->graphicsView->rotate(rotationAngle_); }); + connect(ui_->startButton, &QPushButton::clicked, + [=]() { scene_->SetFiguresInteraction(false); }); + connect(ui_->pauseButton, &QPushButton::clicked, game_, &Game::StopGame); + connect(ui_->pauseButton, &QPushButton::clicked, + [=]() { ui_->listWidget->setEnabled(true); }); + connect(ui_->pauseButton, &QPushButton::clicked, + [=]() { scene_->SetFiguresInteraction(true); }); + connect(game_, &Game::ScoreChanged, this, &MainWindow::UpdateScoreLabel); + connect(ui_->pauseButton, &QPushButton::clicked, game_, &Game::StopGame); + connect(ui_->aboutButton, &QPushButton::clicked, game_, &Game::ShowAbout); +} + +void MainWindow::SetUi() { + scene_ = new Scene(this); + game_ = new Game(*scene_, this); + ui_->graphicsView->setScene(scene_); + AddItemToList(ItemsFactory::kBorder); + AddItemToList(ItemsFactory::kCoin); + AddItemToList(ItemsFactory::kPlayer); +} + +void MainWindow::AddItemToList(const QString &itemType) { + DragItem *item = new DragItem(itemType); + ui_->listWidget->addItem(item); + ui_->listWidget->setItemWidget(item, item); +} diff --git a/src/mainwindow/mainwindow.h b/src/mainwindow/mainwindow.h new file mode 100644 index 0000000..c594c6d --- /dev/null +++ b/src/mainwindow/mainwindow.h @@ -0,0 +1,40 @@ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include +#include +#include +#include + +#include +class Game; +QT_BEGIN_NAMESPACE +namespace Ui { +class MainWindow; +} +QT_END_NAMESPACE + +class MainWindow : public QMainWindow { + Q_OBJECT + + public: + MainWindow(QWidget *parent = nullptr); + ~MainWindow(); + void SetListWidgetEnabled(bool enabled); + private slots: + void UpdateScoreLabel(int newScore); + + private: + void SetConnections(); + void SetUi(); + void AddItemToList(const QString &type); + + private: + Ui::MainWindow *ui_; + Scene *scene_; + int rotationAngle_ = 10; + qreal itemScaleFactor_ = 0.1; + Game *game_; + SceneItem *player_; +}; +#endif // MAINWINDOW_H diff --git a/src/mainwindow/mainwindow.ui b/src/mainwindow/mainwindow.ui new file mode 100644 index 0000000..215bae0 --- /dev/null +++ b/src/mainwindow/mainwindow.ui @@ -0,0 +1,218 @@ + + + MainWindow + + + + 0 + 0 + 820 + 746 + + + + MainWindow + + + + + + + + + + + + + 20 + 100 + + + + Игра + + + Qt::AlignCenter + + + + + 10 + 20 + 191 + 80 + + + + + + + Начать игру + + + + + + + Пауза + + + + + + + Справка + + + + + + + + + + + Выделенные фигуры + + + + + + Повернуть + + + + + + + Удалить + + + + + + + Масштаб + + + + + + + + + + + + + + + + - + + + + + + + + + Сбросить + + + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Представление + + + + + + + + + Повернуть + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + 0 + 0 + + + + + 200 + 16777215 + + + + + + + + + + + + 0 + 0 + 820 + 20 + + + + + + + + ItemsWidget + QListWidget +
itemswidget.h
+
+
+ + +
diff --git a/src/scene/scene.cpp b/src/scene/scene.cpp new file mode 100644 index 0000000..4cf9f36 --- /dev/null +++ b/src/scene/scene.cpp @@ -0,0 +1,139 @@ +#include "scene.h" + +#include + +#include +#include +#include +#include +#include + +#include "qmimedata.h" +#include "src/dragitem/dragitem.h" + +Scene::Scene(QObject *parent) : QGraphicsScene{parent} { + setSceneRect(QRectF(0, 0, 400, 500)); +} + +const QList &Scene::GetWalls() const { return walls_; } +const QList &Scene::GetCoins() const { return coins_; } +SceneItem *Scene::GetPlayer() const { return player_; } + +bool Scene::DeleteCoin(SceneItem *coin) { + if (!coins_.contains(coin)) { + return false; + } + removeItem(coin); + coins_.removeOne(coin); + delete coin; + return true; +} +void Scene::SetFiguresInteraction(bool enable) { + for (auto &item : items()) { + item->setFlag(QGraphicsItem::ItemIsMovable, enable); + item->setFlag(QGraphicsItem::ItemIsSelectable, enable); + item->setFlag(QGraphicsItem::ItemIsFocusable, enable); + } +} + +void Scene::RotateSelectedItems() { + int angle = 10; + + for (auto &item : selectedItems()) { + item->setRotation(item->rotation() + angle); + } +} + +void Scene::ScaleSelectedItems(qreal scaleFactor) { + for (auto &item : selectedItems()) { + item->setScale(item->scale() + scaleFactor); + } +} + +void Scene::RemoveSelectedItems() { + for (auto &item : selectedItems()) { + if (item == player_) { + player_ = nullptr; + } + removeItem(item); + } +} + +void Scene::ResetSelectedItemsScale() { + int defaultScale = 1; + + for (auto &item : selectedItems()) { + item->setScale(defaultScale); + } +} + +void Scene::dragEnterEvent(QGraphicsSceneDragDropEvent *event) { + if (event->mimeData()->hasFormat(DragItem::kMimeFormat)) { + event->acceptProposedAction(); + } else { + event->ignore(); + } +} + +void Scene::dragMoveEvent(QGraphicsSceneDragDropEvent *event) { + if (event->mimeData()->hasFormat(DragItem::kMimeFormat)) { + event->accept(); + } +} + +void Scene::dropEvent(QGraphicsSceneDragDropEvent *event) { + if (event->mimeData()->hasFormat(DragItem::kMimeFormat)) { + QByteArray itemData = event->mimeData()->data(DragItem::kMimeFormat); + QDataStream dataStream(&itemData, QIODevice::ReadOnly); + + QString itemType; + dataStream >> itemType; + qDebug() << itemType; + SceneItem *item = ItemsFactory::Create(itemType); + item->setPos(event->scenePos()); + + if (itemType == "Игрок") { + if (player_ == nullptr) { + player_ = item; + qDebug() << player_; + } else { + item = nullptr; + } + } + + if (itemType == "Монетка") { + coins_.append(item); + } + + if (itemType == "Стенка") { + walls_.append(item); + } + addItem(item); + event->acceptProposedAction(); + } else { + event->ignore(); + } +} + +void Scene::keyPressEvent(QKeyEvent *pressedKey) { + if (player_ != nullptr) { + switch (pressedKey->key()) { + case Qt::Key_Left: + qDebug() << "Влево"; + player_->SetDirection(-1, 0); + break; + case Qt::Key_Right: + player_->SetDirection(1, 0); + qDebug() << "Вправо"; + break; + case Qt::Key_Up: + player_->SetDirection(0, -1); + qDebug() << "Вверх"; + break; + case Qt::Key_Down: + player_->SetDirection(0, 1); + qDebug() << "Вниз"; + break; + } + } +} diff --git a/src/scene/scene.h b/src/scene/scene.h new file mode 100644 index 0000000..be4890d --- /dev/null +++ b/src/scene/scene.h @@ -0,0 +1,38 @@ +#ifndef SCENE_H +#define SCENE_H + +#include + +#include +#include + +class Scene : public QGraphicsScene { + // Q_OBJECT + public: + explicit Scene(QObject *parent = nullptr); + const QList &GetWalls() const; + const QList &GetCoins() const; + const QList &SetCoins(QList) const; + SceneItem *GetPlayer() const; + bool DeleteCoin(SceneItem *coin); + void SetFiguresInteraction(bool enable); + + public slots: + void RotateSelectedItems(); + void ScaleSelectedItems(qreal scaleFactor); + void RemoveSelectedItems(); + void ResetSelectedItemsScale(); + + protected: + void dragEnterEvent(QGraphicsSceneDragDropEvent *event); + void dragMoveEvent(QGraphicsSceneDragDropEvent *event); + void dropEvent(QGraphicsSceneDragDropEvent *event); + void keyPressEvent(QKeyEvent *event); + + private: + QList walls_; + QList coins_; + SceneItem *player_; +}; + +#endif // SCENE_H diff --git a/src/scene_items/itemsfactory.cpp b/src/scene_items/itemsfactory.cpp new file mode 100644 index 0000000..05064ec --- /dev/null +++ b/src/scene_items/itemsfactory.cpp @@ -0,0 +1,26 @@ +#include "itemsfactory.h" + +ItemsFactory::ItemsFactory() {} + +SceneItem *ItemsFactory::Create(const QString &type) { + if (type == kBorder) { + return new SceneItem(QRectF(0, 0, 70, 40), QPen(Qt::black, 1), + QBrush(Qt::green, Qt::SolidPattern), type); + } else if (type == kCoin) { + return new SceneItem(QRectF(0, 0, 40, 40), QPen(Qt::black), + QBrush(QColor(255, 215, 0), Qt::SolidPattern), type); + } else { + return new SceneItem((QRectF(0, 0, 60, 60)), QPen(), + QBrush(Qt::yellow, Qt::SolidPattern), type); + } +} + +QColor ItemsFactory::GetColorByItemTypeconst(const QString &type) { + if (type == kBorder) { + return Qt::gray; + } else if (type == kCoin) { + return Qt::cyan; + } else { + return Qt::yellow; + } +} diff --git a/src/scene_items/itemsfactory.h b/src/scene_items/itemsfactory.h new file mode 100644 index 0000000..34119d9 --- /dev/null +++ b/src/scene_items/itemsfactory.h @@ -0,0 +1,21 @@ +#ifndef ITEMSFACTORY_H +#define ITEMSFACTORY_H + +#include +#include + +#include "src/scene_items/sceneitem.h" + +class ItemsFactory : public QObject { + private: + ItemsFactory(); + + public: + static SceneItem* Create(const QString& type); + static QColor GetColorByItemTypeconst(const QString& type); + static inline const QString kBorder = "Стенка"; + static inline const QString kPlayer = "Игрок"; + static inline const QString kCoin = "Монетка"; +}; + +#endif // ITEMSFACTORY_H diff --git a/src/scene_items/sceneitem.cpp b/src/scene_items/sceneitem.cpp new file mode 100644 index 0000000..5e45986 --- /dev/null +++ b/src/scene_items/sceneitem.cpp @@ -0,0 +1,123 @@ +#include "sceneitem.h" + +#include + +SceneItem::SceneItem(QRectF rect, QPen pen, QBrush brush, QString type) + : QAbstractGraphicsShapeItem() { + geometry_ = rect; + type_ = type; + setPen(pen); + setBrush(brush); + selectedPenBack_ = QPen(kSelectedPenColor_, pen.width(), Qt::SolidLine); + selectedPenFront_ = QPen(pen.color(), pen.width(), kSelectedPenStyle_); + + setFlags(ItemIsMovable | ItemIsSelectable); + + step_ = 10; +} + +SceneItem::SceneItem(SceneItem const &sceneItem) + : QAbstractGraphicsShapeItem() { + SceneItem(sceneItem.boundingRect(), sceneItem.pen(), sceneItem.brush()); +} + +QPainterPath SceneItem::shape() { + QPainterPath path; + if (type_ == "Монетка") { + path.addEllipse(boundingRect()); + } else if (type_ == "Игрок") { + path.addPolygon(DrawPacmanShape()); + } else { + path.addRect(boundingRect()); + } + + return path; +} + +QRectF SceneItem::boundingRect() const { + int divider = 2; + qreal penThickness = pen().widthF(); + + return QRectF(-penThickness / divider, -penThickness / divider, + geometry_.width() + penThickness, + geometry_.height() + penThickness); +} + +void SceneItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, + QWidget *widget) { + Q_UNUSED(option); + Q_UNUSED(widget); + + painter->setRenderHint(QPainter::Antialiasing); + + painter->setPen(pen()); + painter->setBrush(brush()); + + if (type_ == "Монетка") { + painter->drawEllipse(geometry_); + + } else if (type_ == "Игрок") { + painter->drawPolygon(DrawPacmanShape()); + } else { + painter->drawRect(geometry_); + } + + if (isSelected()) { + painter->setPen(selectedPenBack_); + DrawBorder(painter); + + painter->setPen(selectedPenFront_); + DrawBorder(painter); + } +} + +void SceneItem::Move() { + int newX = pos().x() + directionX_ * step_; + int newY = pos().y() + directionY_ * step_; + setPos(newX, newY); +} +void SceneItem::SetDirection(int x, int y) { + directionX_ = x; + directionY_ = y; +} +void SceneItem::InvertDirection() { + directionX_ = -directionX_; + directionY_ = -directionY_; +} + +void SceneItem::DrawBorder(QPainter *painter) { + painter->drawLine(geometry_.topLeft(), geometry_.topRight()); + painter->drawLine(geometry_.topLeft(), geometry_.bottomLeft()); + painter->drawLine(geometry_.bottomRight(), geometry_.topRight()); + painter->drawLine(geometry_.bottomRight(), geometry_.bottomLeft()); +} + +QPolygonF SceneItem::DrawPacmanShape() { + int delimiter = 2; + QPolygonF pacmanShape; + float centerX = geometry_.width() / delimiter; + float centerY = geometry_.height() / delimiter; + float radius = geometry_.height() / delimiter; + + float angleStart = 60; + float angleEnd = 300; + pacmanShape << QPointF(centerX, centerY); + + for (int angle = angleStart; angle <= angleEnd; angle++) { + float radians = angle * M_PI / 180.0f; + float x = centerX + radius * std::cos(radians); + float y = centerY + radius * std::sin(radians); + pacmanShape << QPointF(x, y); + } + return pacmanShape; +} +int SceneItem::GetDirectionX() { return directionX_; } + +int SceneItem::GetDirectionY() { return directionY_; } + +int SceneItem::GetStep() { return step_; } + +void SceneItem::ChangeBrush(const QBrush &newBrush) { + currentBrush_ = newBrush; + setBrush(currentBrush_); +} diff --git a/src/scene_items/sceneitem.h b/src/scene_items/sceneitem.h new file mode 100644 index 0000000..a0d2993 --- /dev/null +++ b/src/scene_items/sceneitem.h @@ -0,0 +1,46 @@ +#ifndef SCENEITEM_H +#define SCENEITEM_H + +#include +#include +#include +#include +#include + +class SceneItem : public QAbstractGraphicsShapeItem { + public: + explicit SceneItem(QRectF rect, QPen pen, QBrush brush, QString type = ""); + SceneItem(SceneItem const &sceneItem); + + public: + QPainterPath shape(); + QRectF boundingRect() const; + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, + QWidget *widget); + void Move(); + void SetDirection(int x, int y); + void InvertDirection(); + void ChangeBrush(const QBrush &newBrush); + int GetDirectionX(); + int GetDirectionY(); + int GetStep(); + + private: + void DrawBorder(QPainter *painter); + QPolygonF DrawPacmanShape(); + + private: + const QColor kSelectedPenColor_ = Qt::white; + const Qt::PenStyle kSelectedPenStyle_ = Qt::DashLine; + QBrush originalBrush_; + QBrush currentBrush_; + QRectF geometry_; + QPen selectedPenFront_; + QPen selectedPenBack_; + int directionX_; + int directionY_; + int step_; + QString type_; +}; + +#endif // SCENEITEM_H diff --git a/ui_mainwindow.h b/ui_mainwindow.h new file mode 100644 index 0000000..e0160be --- /dev/null +++ b/ui_mainwindow.h @@ -0,0 +1,235 @@ +/******************************************************************************** +** Form generated from reading UI file 'mainwindow.ui' +** +** Created by: Qt User Interface Compiler version 5.12.12 +** +** WARNING! All changes made in this file will be lost when recompiling UI file! +********************************************************************************/ + +#ifndef UI_MAINWINDOW_H +#define UI_MAINWINDOW_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class Ui_MainWindow +{ +public: + QWidget *centralwidget; + QHBoxLayout *horizontalLayout; + QGraphicsView *graphicsView; + QVBoxLayout *verticalLayout; + QGroupBox *groupBox_5; + QWidget *verticalLayoutWidget; + QVBoxLayout *verticalLayout_6; + QPushButton *startButton; + QPushButton *pauseButton; + QPushButton *aboutButton; + QGroupBox *groupBox_2; + QVBoxLayout *verticalLayout_4; + QPushButton *rotateButton; + QPushButton *removeButton; + QGroupBox *groupBox_4; + QVBoxLayout *verticalLayout_2; + QHBoxLayout *horizontalLayout_3; + QPushButton *zoomInButton; + QPushButton *zoomOutButton; + QPushButton *resetZoomButton; + QLCDNumber *counterLCD; + QSpacerItem *verticalSpacer_2; + QGroupBox *groupBox; + QVBoxLayout *verticalLayout_3; + QHBoxLayout *horizontalLayout_2; + QPushButton *graphicsViewRotateButton; + QSpacerItem *verticalSpacer_4; + ItemsWidget *listWidget; + QMenuBar *menubar; + QStatusBar *statusbar; + + void setupUi(QMainWindow *MainWindow) + { + if (MainWindow->objectName().isEmpty()) + MainWindow->setObjectName(QString::fromUtf8("MainWindow")); + MainWindow->resize(820, 746); + centralwidget = new QWidget(MainWindow); + centralwidget->setObjectName(QString::fromUtf8("centralwidget")); + horizontalLayout = new QHBoxLayout(centralwidget); + horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout")); + graphicsView = new QGraphicsView(centralwidget); + graphicsView->setObjectName(QString::fromUtf8("graphicsView")); + + horizontalLayout->addWidget(graphicsView); + + verticalLayout = new QVBoxLayout(); + verticalLayout->setObjectName(QString::fromUtf8("verticalLayout")); + groupBox_5 = new QGroupBox(centralwidget); + groupBox_5->setObjectName(QString::fromUtf8("groupBox_5")); + groupBox_5->setMinimumSize(QSize(20, 100)); + groupBox_5->setAlignment(Qt::AlignCenter); + verticalLayoutWidget = new QWidget(groupBox_5); + verticalLayoutWidget->setObjectName(QString::fromUtf8("verticalLayoutWidget")); + verticalLayoutWidget->setGeometry(QRect(10, 20, 191, 80)); + verticalLayout_6 = new QVBoxLayout(verticalLayoutWidget); + verticalLayout_6->setObjectName(QString::fromUtf8("verticalLayout_6")); + verticalLayout_6->setContentsMargins(0, 0, 0, 0); + startButton = new QPushButton(verticalLayoutWidget); + startButton->setObjectName(QString::fromUtf8("startButton")); + + verticalLayout_6->addWidget(startButton); + + pauseButton = new QPushButton(verticalLayoutWidget); + pauseButton->setObjectName(QString::fromUtf8("pauseButton")); + + verticalLayout_6->addWidget(pauseButton); + + aboutButton = new QPushButton(verticalLayoutWidget); + aboutButton->setObjectName(QString::fromUtf8("aboutButton")); + + verticalLayout_6->addWidget(aboutButton); + + + verticalLayout->addWidget(groupBox_5); + + groupBox_2 = new QGroupBox(centralwidget); + groupBox_2->setObjectName(QString::fromUtf8("groupBox_2")); + verticalLayout_4 = new QVBoxLayout(groupBox_2); + verticalLayout_4->setObjectName(QString::fromUtf8("verticalLayout_4")); + rotateButton = new QPushButton(groupBox_2); + rotateButton->setObjectName(QString::fromUtf8("rotateButton")); + + verticalLayout_4->addWidget(rotateButton); + + removeButton = new QPushButton(groupBox_2); + removeButton->setObjectName(QString::fromUtf8("removeButton")); + + verticalLayout_4->addWidget(removeButton); + + groupBox_4 = new QGroupBox(groupBox_2); + groupBox_4->setObjectName(QString::fromUtf8("groupBox_4")); + verticalLayout_2 = new QVBoxLayout(groupBox_4); + verticalLayout_2->setObjectName(QString::fromUtf8("verticalLayout_2")); + horizontalLayout_3 = new QHBoxLayout(); + horizontalLayout_3->setObjectName(QString::fromUtf8("horizontalLayout_3")); + zoomInButton = new QPushButton(groupBox_4); + zoomInButton->setObjectName(QString::fromUtf8("zoomInButton")); + + horizontalLayout_3->addWidget(zoomInButton); + + zoomOutButton = new QPushButton(groupBox_4); + zoomOutButton->setObjectName(QString::fromUtf8("zoomOutButton")); + + horizontalLayout_3->addWidget(zoomOutButton); + + + verticalLayout_2->addLayout(horizontalLayout_3); + + resetZoomButton = new QPushButton(groupBox_4); + resetZoomButton->setObjectName(QString::fromUtf8("resetZoomButton")); + + verticalLayout_2->addWidget(resetZoomButton); + + counterLCD = new QLCDNumber(groupBox_4); + counterLCD->setObjectName(QString::fromUtf8("counterLCD")); + + verticalLayout_2->addWidget(counterLCD); + + + verticalLayout_4->addWidget(groupBox_4); + + + verticalLayout->addWidget(groupBox_2); + + verticalSpacer_2 = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding); + + verticalLayout->addItem(verticalSpacer_2); + + groupBox = new QGroupBox(centralwidget); + groupBox->setObjectName(QString::fromUtf8("groupBox")); + verticalLayout_3 = new QVBoxLayout(groupBox); + verticalLayout_3->setObjectName(QString::fromUtf8("verticalLayout_3")); + horizontalLayout_2 = new QHBoxLayout(); + horizontalLayout_2->setObjectName(QString::fromUtf8("horizontalLayout_2")); + + verticalLayout_3->addLayout(horizontalLayout_2); + + graphicsViewRotateButton = new QPushButton(groupBox); + graphicsViewRotateButton->setObjectName(QString::fromUtf8("graphicsViewRotateButton")); + + verticalLayout_3->addWidget(graphicsViewRotateButton); + + + verticalLayout->addWidget(groupBox); + + verticalSpacer_4 = new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding); + + verticalLayout->addItem(verticalSpacer_4); + + listWidget = new ItemsWidget(centralwidget); + listWidget->setObjectName(QString::fromUtf8("listWidget")); + QSizePolicy sizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding); + sizePolicy.setHorizontalStretch(0); + sizePolicy.setVerticalStretch(0); + sizePolicy.setHeightForWidth(listWidget->sizePolicy().hasHeightForWidth()); + listWidget->setSizePolicy(sizePolicy); + listWidget->setMaximumSize(QSize(200, 16777215)); + + verticalLayout->addWidget(listWidget); + + + horizontalLayout->addLayout(verticalLayout); + + MainWindow->setCentralWidget(centralwidget); + menubar = new QMenuBar(MainWindow); + menubar->setObjectName(QString::fromUtf8("menubar")); + menubar->setGeometry(QRect(0, 0, 820, 20)); + MainWindow->setMenuBar(menubar); + statusbar = new QStatusBar(MainWindow); + statusbar->setObjectName(QString::fromUtf8("statusbar")); + MainWindow->setStatusBar(statusbar); + + retranslateUi(MainWindow); + + QMetaObject::connectSlotsByName(MainWindow); + } // setupUi + + void retranslateUi(QMainWindow *MainWindow) + { + MainWindow->setWindowTitle(QApplication::translate("MainWindow", "MainWindow", nullptr)); + groupBox_5->setTitle(QApplication::translate("MainWindow", "\320\230\320\263\321\200\320\260", nullptr)); + startButton->setText(QApplication::translate("MainWindow", "\320\235\320\260\321\207\320\260\321\202\321\214 \320\270\320\263\321\200\321\203", nullptr)); + pauseButton->setText(QApplication::translate("MainWindow", "\320\237\320\260\321\203\320\267\320\260", nullptr)); + aboutButton->setText(QApplication::translate("MainWindow", "\320\241\320\277\321\200\320\260\320\262\320\272\320\260", nullptr)); + groupBox_2->setTitle(QApplication::translate("MainWindow", "\320\222\321\213\320\264\320\265\320\273\320\265\320\275\320\275\321\213\320\265 \321\204\320\270\320\263\321\203\321\200\321\213", nullptr)); + rotateButton->setText(QApplication::translate("MainWindow", "\320\237\320\276\320\262\320\265\321\200\320\275\321\203\321\202\321\214", nullptr)); + removeButton->setText(QApplication::translate("MainWindow", "\320\243\320\264\320\260\320\273\320\270\321\202\321\214", nullptr)); + groupBox_4->setTitle(QApplication::translate("MainWindow", "\320\234\320\260\321\201\321\210\321\202\320\260\320\261", nullptr)); + zoomInButton->setText(QApplication::translate("MainWindow", "+", nullptr)); + zoomOutButton->setText(QApplication::translate("MainWindow", "-", nullptr)); + resetZoomButton->setText(QApplication::translate("MainWindow", "\320\241\320\261\321\200\320\276\321\201\320\270\321\202\321\214", nullptr)); + groupBox->setTitle(QApplication::translate("MainWindow", "\320\237\321\200\320\265\320\264\321\201\321\202\320\260\320\262\320\273\320\265\320\275\320\270\320\265", nullptr)); + graphicsViewRotateButton->setText(QApplication::translate("MainWindow", "\320\237\320\276\320\262\320\265\321\200\320\275\321\203\321\202\321\214", nullptr)); + } // retranslateUi + +}; + +namespace Ui { + class MainWindow: public Ui_MainWindow {}; +} // namespace Ui + +QT_END_NAMESPACE + +#endif // UI_MAINWINDOW_H