Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions GraphicsFrameworkSample.pro
Original file line number Diff line number Diff line change
@@ -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
22 changes: 11 additions & 11 deletions main.cpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
#include "mainwindow.h"

#include <QApplication>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
#include <src/mainwindow/mainwindow.h>
#include <QApplication>
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
MainWindow w;
w.setWindowTitle("Да начнутся голодные игры");
w.show();
return a.exec();
}
30 changes: 30 additions & 0 deletions src/dragitem/dragitem.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#include "dragitem.h"

#include <QPainter>
#include <QRect>

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_; }
30 changes: 30 additions & 0 deletions src/dragitem/dragitem.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#ifndef DRAGITEM_H
#define DRAGITEM_H

#include <src/scene_items/itemsfactory.h>

#include <QGraphicsItem>
#include <QListWidget>
#include <QWidget>

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
131 changes: 131 additions & 0 deletions src/game.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
#include "game.h"

#include <QDebug>
#include <QEvent>
#include <QString>

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<MainWindow *>(parent());

if (mainWindow) {
mainWindow->SetListWidgetEnabled(false);
}

gameTimer_.start(intervalTime_, this);
qDebug() << player_;
}
}

void Game::StopGame() {
if (!gameTimer_.isActive()) {
return;
}
MainWindow *mainWindow = qobject_cast<MainWindow *>(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<MainWindow *>(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<SceneItem *> &walls = scene_.GetWalls();
const QList<SceneItem *> &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;
}
52 changes: 52 additions & 0 deletions src/game.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#ifndef GAME_H
#define GAME_H

#include <src/dragitem/dragitem.h>
#include <src/mainwindow/mainwindow.h>
#include <src/scene/scene.h>
#include <src/scene_items/itemsfactory.h>

#include <QKeyEvent>
#include <QMessageBox>
#include <QTimer>
#include <QWidget>

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
54 changes: 54 additions & 0 deletions src/itemswidget/itemswidget.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#include "itemswidget.h"

#include <QByteArray>
#include <QDataStream>
#include <QDrag>
#include <QMimeData>
#include <QMouseEvent>
#include <QPainter>

ItemsWidget::ItemsWidget(QWidget *parent) : QListWidget(parent) {
setSelectionMode(SingleSelection);
setDragEnabled(true);
}

void ItemsWidget::mousePressEvent(QMouseEvent *event) {
dragStartPosition_ = event->pos();
dragableItem_ = dynamic_cast<DragItem *>(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;
}
25 changes: 25 additions & 0 deletions src/itemswidget/itemswidget.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#ifndef ITEMSWIDGET_H
#define ITEMSWIDGET_H

#include <src/dragitem/dragitem.h>

#include <QListWidget>

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
Loading