Вы находитесь на странице: 1из 10

Минцифры РФ

Сибирский государственный университет

телекоммуникаций и информатики

Кафедра прикладной математики и кибернетики

Расчетно-графическая работа

по дисциплине: «Языки программирования высокого уровня»

Выполнил: студент гр.ММП-81

Пытаева А.Г.

Проверил: Мерзлякова Е. Ю.

Новосибирск 2021
Содержание
Задание.....................................................................................................................3
Заголовочные...........................................................................................................4
Исходники................................................................................................................5
Скриншоты созданного приложения, которые иллюстрируют работу
приложения............................................................................................................10

2
Задание
1. Создать графическую сцену.

2. Поместить на сцену различные элементы для составления картинки


определенного вами сюжета. Обязательно использовать и геометрические
фигуры, и картинки. Они должны перемещаться с помощью мыши.

3. Ограничить края сцены «стенами» в виде каких-либо графических


элементов, например, квадратов или изображений кирпича.

4. Поместить на сцену движущийся элемент. Он должен перемещаться с


заданной скоростью, сталкиваться со «стенами» и фигурами на сцене.
Используйте таймер и функцию обнаружения столкновений.

5. Поместить на сцену элемент, который можно перемещать с помощью


клавиатуры. Реализуйте обработку столкновений.

3
Заголовочные
Game.h

#ifndef GAME_H
#define GAME_H
#include <QWidget>
#include <QGraphicsScene>
#include <QLabel>
#include <QGraphicsPixmapItem>

//создаем потомок класса QGraphicsScene


class Game : public QGraphicsScene{
Q_OBJECT
public:
Game(QObject *parent = nullptr);//конструктор
void makeWall();// отвечает за рисование лабиринта
protected:
virtual void keyPressEvent(QKeyEvent *keyEvent);
private:
//создаем игроков:
QGraphicsPixmapItem *Fox;
QGraphicsPixmapItem *Rabbit;
QGraphicsPixmapItem *Carrot;

//создаем случайное число, чтобы определить в какую сторону будет


двигаться враг
int R;

void The_End();// действия в случае проигрыша (враг и герой столкнулись)


void Win();/* действия в случае выигрыша, т.е. когда игрок достиг
морковки */
QGraphicsItem *itemCollidesWith(QGraphicsItem *item);/* метод
возвращающий одну из коллизий для объекта */

private slots://отвечают за случайное передвижение врага по лабиринту


void FoxGo();/* функция перемещения врага в заданном направлении R (R-
переменная направления движения лисы)*/
void Rand_Fox();/*определяет направление перемещения врага (от 1 до 4
направлений)*/
};
#endif // GAME_H

Mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>

namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow// Класс главного окна
{
Q_OBJECT

public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();

Ui::MainWindow *ui;

4
};

#endif // MAINWINDOW_H

Исходники
Game.cpp

#include "game.h"
#include <mainwindow.cpp>
#include <QWidget>
#include <QTransform>
#include <QTimer>
#include <QTime>
#include <QGraphicsItem>
#include <QPointF>
#include <QKeyEvent>
#include <QDebug>
#include <QMessageBox>
#include <QRectF>

//конструктор класса Game

Game::Game(QObject *parent): QGraphicsScene(parent)


{
makeWall();//вызываем функцию рисования стен для рисования стен

Fox=addPixmap(QPixmap("Fox.png"));//вставляем картинку врага


QTransform tran=Fox->transform();// создается трансформация для врага
tran.translate(100,400);// перемещаем на позицию x = 100, y = 400
Fox->setTransform(tran);// применяется трансформация (т.е. устанавливаем
позицию врага)
//setData(0, "Fox") 0- численный идентификатор элемента данных, т.к.
первое поле ставим 0. Второй аргумент - сами данные(любого типа)
Fox->setData(0, "Fox");// наделяем объект дополнительными свойствами.
т.е. враг является контейнером, в который записываем данные объекта
Fox->setFlags(QGraphicsItem::ItemIsMovable);// для того чтобы можно было
двигать мышкой

Rabbit=addPixmap(QPixmap("Rabbit.png"));//вставляем картинку игрока


tran=Rabbit->transform();// создается трансформация для игрока
tran.translate(50,10);// перемещаем на позицию x = 50, y = 20
Rabbit->setTransform(tran);// применяется трансформация (т.е.
устанавливаем позицию игрока)
Rabbit->setData(0, "Rabbit");// записываем в данные объекта, что это
игрок
Rabbit->setFlags(QGraphicsItem::ItemIsMovable);// для того чтобы можно
было двигать мышкой

Carrot=addPixmap(QPixmap("Carrot.png"));//вставляем картинку "приза"


tran=Carrot->transform();// создается трансформация для "приза"
tran.translate(500,250);// перемещаем на позицию x = 500, y = 250
Carrot->setTransform(tran);// применяется трансформация (т.е.
устанавливаем позицию "приза")
Carrot->setData(0, "Carrot");// записываем в данные объекта, что это
"приз"
Carrot->setFlags(QGraphicsItem::ItemIsMovable);// для того чтобы можно
было двигать мышкой

setBackgroundBrush(QBrush(QColor(255,255,255),
QPixmap("background.png")));//устанавливается кисть фона сцены. загружаем фон
сцены

5
qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));//
(инициализируем)задаем генератор случайных чисел, чтобы потом их получать
Rand_Fox();// вызываем функцию (от 1 до 4 направлений) и записываем в
переменную R-переменная направления движения лисы

// создается таймер ответственный за вызов FoxGo, по срабатыванию


которого враг делает ход
//в функции FoxGo будет осуществляться перемещение лисы, а для
перемещения нужен таймер
QTimer *timer=new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(FoxGo()));
timer->start(1000);// скорость перемещения 1 секунда ВРАГ

// создается таймер ответственный за вызов Rand_Fox, по срабатыванию


которого враг меняет направление движения
QTimer *timer2=new QTimer(this);
connect(timer2, SIGNAL(timeout()), this, SLOT(Rand_Fox()));
timer2->start(5000);//с такой частотой меняется направление (5 секунд)
}

void Game::makeWall()
{
//создаем координаты стен
// 1-ая координата - начальное положение по x
// 2-ая координата - начальное положение по y
// 3-ая координата - ширина прямоугольника
// 4-ая координата - длина прямоугольника
float wall [20] [4] = {
{32,80,128,16},
{32,0,672,10},
{32,0,16,96},
{704,0,16,96},
{448, 80, 256, 16},
{448, 80, 16, 128},
{160, 80, 16, 128},
{16, 208, 160, 16},
{448, 208, 160, 16},
{16, 208, 16, 396},
{16, 592, 608, 16},
{608, 208, 16, 396},
{128, 208, 16, 192},
{128, 464, 16, 54},
{128, 464, 192, 16},
{320, 464, 16, 144},
{352, 208, 16, 112},
{256, 208, 96, 16},
{256, 208, 16, 64},
{480, 208, 16, 300}
};

QBrush brush(QColor(255,255,255),QPixmap("wall.png"));//устанавливается
кисть для рисования прямоугольников и добавление картинки стен
QPen pen(Qt::NoPen);//устанавливается кисть для рисования прямоугольников
и они добавляются на сцену
for (int i = 0; i<20; i++){//20-размер массива, количество прохода цикла
//создаем стену
QGraphicsItem * item =
addRect(QRectF(wall[i][0], wall[i][1], wall[i][2], wall[i]
[3]), pen, brush);
item->setData(0, "Wall");//каждому прямоугольнику
устанавливается метка wall
}

6
}

void Game::keyPressEvent(QKeyEvent *keyEvent)//отвечает за передвижение


игрока
{
QPointF np;// создаем переменную которая будет хранить новую позицию
игрока
np.setX(0);
np.setY(0);
// определяем какая стрелочка была нажата
switch(keyEvent->key())//перемещение в зависимости от стрелок, которые
мы нажали
{
case Qt::Key_Left://влево
np.setX(-10);
break;
case Qt::Key_Right://вправо
np.setX(10);
break;
case Qt::Key_Up://вверх
np.setY(-10);
break;
case Qt::Key_Down://вниз
np.setY(10);
break;
}
QTransform tran=Rabbit->transform();// перемещение игрока по
координатам, которые мы задали
tran.translate(np.x(),np.y());// задаем новую позицию
Rabbit->setTransform(tran);// ставим новую позицию для игрока

// производим обработку столкновения кролик


QGraphicsItem *obtacle=itemCollidesWith(Rabbit);//для проверки служит
функция itemCollides
if(obtacle)// если есть столкновение
{
// если игрок натолкнулся на стену, возвращаемся обратно
if(obtacle->data(0)=="Wall")
{
tran.translate(-np.x(),-np.y());
Rabbit->setTransform(tran);
}
else
if (obtacle->data(0) == "Fox") The_End();// если это враг, игрок
умирает. Проигрыш
else if (obtacle->data(0) == "Carrot") Win();// если это "приз", то
игрок выиграл
}
}

QGraphicsItem* Game::itemCollidesWith(QGraphicsItem *item)


{
QList<QGraphicsItem*> collisions=collidingItems(item);// берем список
коллизий
foreach(QGraphicsItem *it,collisions)
{
if(it==item)
continue;
return it;
}
return NULL;
}

7
void Game::FoxGo()//функция перемещения врага в заданном направлении R (R-
переменная направления движения лисы)
{
// фрагмент кода, осуществляющий перемещение лисы
QPointF np;
np.setX(0);
np.setY(0);
// определяем направление
switch(R)
{
case 1 : np.setX(-20); break;// Налево
case 2 : np.setX(20); break;// Направо
case 3 : np.setY(-20); break;// Вверх
case 4 : np.setY(20); break;// Вниз
}
QTransform tran=Fox->transform();// берем позицию врага
tran.translate(np.x(),np.y());//задаемся новой позицией врага
Fox->setTransform(tran);// ставим врага в заданную выше позицию

//продолжение функции обработки коллизии


QGraphicsItem *obtacle=itemCollidesWith(Fox);
tran=Fox->transform();
if(obtacle)//если коллизия найдена
{
if((obtacle->data(0)=="Wall")|| (obtacle->data(0) == "Carrot"))//если
это стена или морковка, враг возвращается обратно
{
tran.translate(-np.x(),-np.y());
Fox->setTransform(tran);
Rand_Fox();//тут еще изменение направления врага после
столкновения
}
else
if (obtacle->data(0) == "Rabbit") The_End();
else
if (obtacle->data(0) == "Carrot") Win();
}
}

void Game::Rand_Fox()// определяет направление перемещения врага (от 1 до 4


направлений)
{
R=qrand()%4+1;
}

void Game::The_End()
{
Rabbit->hide(); // прячем игрока
QMessageBox endingMsgBox; // Создаем диалоговое окно
endingMsgBox.setWindowTitle("Ловушка"); // Задаем название диалогового
окна.
endingMsgBox.setText(tr("Вы попали в логово врага и проиграли")); //
Текст диалогового окна.
endingMsgBox.exec(); // Запускаем цикл обработки окна.
QApplication::instance()->exit(1); // Завершаем приложение с кодом 1.
}

void Game::Win(){
Rabbit->hide(); // прячем игрока
Carrot->hide();// прячем приз
QMessageBox endingMsgBox; // Создаем диалоговое окно
endingMsgBox.setWindowTitle("Выигрыш"); // Задаем название диалогового
окна.

8
endingMsgBox.setText(tr("Предмет достигнут. Вы выиграли")); // Текст
диалогового окна.
endingMsgBox.exec(); // Запускаем цикл обработки окна.
QApplication::instance()->exit(1); // Завершаем приложение с кодом 1.
}
Main.cpp

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])


{
QApplication a(argc, argv);
MainWindow w;// Создаем главное окно
w.show();// Показываем главное окно

return a.exec();// Запускаем событийный цикл главного окна. Теперь оно


может обрабатывать события
}

Mainwindow.cpp

//конструктор главного окна


#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "game.h"
#include <QDebug>

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
Game *scene=new Game();//создается сцена
ui->graphicsView->setScene(scene);//на сцену помещаем
виджет(graphicsView)
}

MainWindow::~MainWindow()
{
delete ui;
}

9
Скриншоты созданного приложения, которые иллюстрируют работу
приложения

10

Вам также может понравиться