Форум программистов, компьютерный форум, киберфорум
C++ Qt
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.59/186: Рейтинг темы: голосов - 186, средняя оценка - 4.59
15 / 11 / 4
Регистрация: 03.08.2019
Сообщений: 209
1

Qt, лего игрушка (2д), трудности с наследованием и "детальками"

06.06.2021, 11:21. Показов 34852. Ответов 406

Author24 — интернет-сервис помощи студентам
Здравствуйте

К чему стремлюсь:
лего-стройка, 2д, детали крепятся в пазы (собственно, как в лего), детали не могут висеть в воздухе, не стыкуемые - не стыкуются, детальки можно вертеть (т.к. есть г-образные). В общем, думаю нет смысла сильно углубляться в лего

В моем представлении:
деталь (класс element) должна состоять из прототипов (класс block)
Деталь должна как бы "заполняться" прототипами, примерно так: элемент3х1 (деталь) заполняется (состоит из) 3-мя блоками по горизонтали, и сам элемент (деталь) является объектом, к которому мы потом можем обращаться по this в функциях (совсем круто, если каким то образом мы сможем обращаться !помимо этого! еще и к конкретным блокам-прототипам, из которых состоит элемент-деталь (кажется, это пригодится для состыковки по клеткам)

На моменте "складывания" детали из блока я окончательно иссяк

Прошу помочь реализовать

block.h
Кликните здесь для просмотра всего текста

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#ifndef BLOCK_H
#define BLOCK_H
#include <QObject>
#include <QGraphicsItem>
#include <QGraphicsScene>
#include <QPainter>
 
//простой блок:
class Block : public QObject, public QGraphicsItem
{
    Q_OBJECT
public: //Передаются размеры Блока:
    Block(int W=32, int H=32, QObject *parent = 0);
    ~Block();
protected:
    QRectF boundingRect() const;
    void paint(QPainter *painter,
               const QStyleOptionGraphicsItem *option,
                                   QWidget *widget);
    void mousePressEvent(QGraphicsSceneMouseEvent *event);
    void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
    void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
 
private:
    int wBlock, hBlock;//Размеры
    QBrush brush;  QPen pen, selectPen;
    bool blockCaptured {false};//Блок захвачен?
 
 
    //вставляемости (по направлениям света):
    int N{1}; //North - Север
    int S{-1}; //South - Юг
    int E{0}; //East - Восток
    int W{0}; //West - Запад
 
};
#endif // BLOCK_H


block.cpp
Кликните здесь для просмотра всего текста

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
#include <QPainter>
#include <QGraphicsSceneMouseEvent>
#include <QCursor>
#include <QKeyEvent>
#include "block.h"
 
#include <iostream>
 
Block::Block(int W, int H, QObject *parent)
    : QObject(parent), QGraphicsItem()
{
    this->wBlock = W;
    this->hBlock = H;
 
    pen.setColor(Qt::darkRed);
    pen.setWidth(1);
 
    selectPen.setColor(Qt::black);
    selectPen.setWidth(3);
 
    //brush.setColor(qRgb(230,0,0));
    brush.setColor(Qt::lightGray);
    brush.setStyle(Qt::SolidPattern);
    //brush.setStyle(Qt::Dense3Pattern);
 
    //вставляемости:
    /*
    this->N = 1;
    this->S = -1;
    this->E = 0;
    this->W = 0;
    */
}
 
Block::~Block() {}
 
QRectF Block::boundingRect() const
{
    //Область занятая Блоком:
    return QRectF(-wBlock*0.5,-hBlock*0.5,wBlock,hBlock);
}
 
void Block::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    //Устанавливаем перо:
    if (this->isSelected()) painter->setPen(selectPen);
    else painter->setPen(pen);
 
    painter->setBrush(brush); //устанавливаем кисть
 
//(upd) перенести лэндинг блока в отдельную область?
    //Рисуем Блок в стандартной позиции (центр в (0; 0))
    //painter->drawRect(-wBlock*0.5,-hBlock*0.5,wBlock,hBlock);
    painter->drawRect(-wBlock*0.5,-hBlock*0.5,wBlock,hBlock);
    //painter->drawRect(0, 0, wBlock*2, hBlock*2);
 
 
/*
//добавляем сетку (upd)
    painter->setBrush(Qt::black);
    for (int i{0}; i<16; i=i+16)
    {
        painter->drawLine(-i*2+2, -hBlock+2, -i*2+2, hBlock-2); //в минус от центра - вертикальные
        painter->drawLine(i*2-2, -hBlock+2, i*2-2, hBlock-2); //в плюс от центра - вертикальные
 
        painter->drawLine(-wBlock+2, -i+2, wBlock-2, -i+2); //в минус от центра - горизонтальные
        painter->drawLine(-wBlock+2, i-2, wBlock-2, i-2); //в плюс от центра - горизонтальные
    }
*/
 
    Q_UNUSED(option);
    Q_UNUSED(widget);
}
 
void Block::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
   if(event->button() == Qt::LeftButton)
   {
        blockCaptured = true; //Захват
        this->setCursor(QCursor(Qt::ClosedHandCursor));
   }
}
 
void Block::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    //qDebug() << event->pos();
    //qDebug() << x();
    //qDebug() << QCursor::pos();
    //qDebug() << event->pos().y();
 
    //Перенос мышкой:
    if (blockCaptured) //Пересчет из локальных в координаты сцены:
        this->setPos(mapToScene(event->pos()));
 
     //QPoint pointBreak = QCursor::pos();
 
//(upd) очень костыльно
    //столкновение:
    if (!scene()->collidingItems(this).isEmpty())
    {
        //qDebug() << scene()->collidingItems(this);
 
//(upd) нужно искать не первый объект а ближайший
        QGraphicsItem* collidingWith = scene()->collidingItems(this).at(0); //вытащили с кем столкнулись
        Block* collidingBlock;
        collidingBlock = static_cast<Block*>(collidingWith);
        qDebug() << collidingBlock->x();
 
        if (event->pos().y() != 0) //двигали по вертикали
        {
            if (event->pos().y() > 2) //вниз
            {
                qDebug() << "вниз";
                if (this->S == -1 && //Юг - вход
                        collidingBlock->N == 1) //Север - выход
                {
                    qDebug() << "стыковка вниз доступна";
                    this->setX(collidingBlock->x());
                    this->setY(collidingBlock->y()-32); //32-размер одной клетки
                    return;
                }
            }
            else if (event->pos().y() < -2) { //вверх
                qDebug() << "вверх";
                if (this->N == 1 && //Юг - вход
                        collidingBlock->S == -1) //Север - выход
                {
                    qDebug() << "стыковка вверх доступна";
                    this->setX(collidingBlock->x());
                    this->setY(collidingBlock->y()+32); //32-размер одной клетки
                    return;
                }
            }
        }
 
        if (event->pos().x() != 0) //двигали по горизонтали
        {
            if (event->pos().x() > 2) //вправо
            {
                qDebug() << "вправо";
            }
            else if (event->pos().x() < 2) { //влево
                qDebug() << "влево";
            }
        }
 
        //QPoint pointBreak = QCursor::pos();
        //QPointF pointBreak2 = this->pos();
 
        //std::cerr << qPrintable("NUKE\n");
        //std::cerr << pointBreak.x() << std::endl;
        //std::cerr << pointBreak.y() << std::endl;
 
        //this->setPos(pointBreak2);
        //QCursor::setPos(x(),y());
        QCursor::setPos(QCursor::pos().x() - event->pos().x(), QCursor::pos().y() - event->pos().y());
        //QCursor::setPos(pointBreak);
 
    }
}
 
void Block::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
{
    if (blockCaptured)
    {
        blockCaptured = false;
           this->setCursor(QCursor(Qt::ArrowCursor));//Восстановили курсор
           this->setFlag(QGraphicsItem::ItemIsSelectable);
             //Снимаем выделение с ранее выделенных:
             QList<QGraphicsItem*> selected = this->scene()->selectedItems();
             foreach (QGraphicsItem* item, selected)
                        item->setSelected(false);
           this->setSelected(true);//Выделяем новый блок
     }
   Q_UNUSED(event);
}


mainwindow.h
Кликните здесь для просмотра всего текста

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
 
#include <QMainWindow>
#include <QGraphicsScene>
class Cloud;
 
namespace Ui { class MainWindow; }
 
class MainWindow : public QMainWindow
{  Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
private slots:
    void on_pushBtnAdd1_clicked();
    void on_pushBtnAdd2_clicked();
    //void on_pushBtnMove_clicked();
    //void slotTicTimer();
private:
    Ui::MainWindow *ui;
    QGraphicsScene *scene; //Сцена
 
//_потом заменю, пока это ключи
    //int x{0}, y{0};
 
    //Размеры основной части сцены и поля (допустим 20х20):
    //_сцена от центра, поэтому цифры х2 s= размеры
 
    int w{720},h{480}; //размеры сцены
 
    //int mw{5},mh{5}; //маргины (пока как часть сцены (рамки офнуль))
 
    int wBlock{32}, hBlock{32};//Размеры строительных Блоков
 
 
};
#endif // MAINWINDOW_H


mainwindow.cpp
Кликните здесь для просмотра всего текста

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#include <QList>
#include "mainwindow.h"
#include "ui_mainwindow.h"
//#include "cloud.h"
#include "block.h"
#include "element.h"
 
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent), ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    scene = new QGraphicsScene(this);//Создаем сцену
    scene->setItemIndexMethod(QGraphicsScene::NoIndex); // настраиваем индексацию элементов
 
    //---------------
    //ui->graphicsView->resize(2*(w+mw),2*(h+mh));  /// Устанавливаем размер graphicsView
    ui->graphicsView->resize(w,h);
    ui->graphicsView->setScene(scene);  /// Устанавливаем графическую сцену в graphicsView
    ui->graphicsView->setRenderHint(QPainter::Antialiasing);    /// Устанавливаем сглаживание
    ui->graphicsView->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); /// Отключаем скроллбар по вертикали
    ui->graphicsView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); /// Отключаем скроллбар по горизонтали
    //ui->graphicsView->setFixedSize(2*(w+mw),2*(h+mh)); ///Фиксируем размер области отображения
    ui->graphicsView->setFixedSize(w,h);
    ui->graphicsView->setCacheMode(QGraphicsView::CacheBackground); // Кэш фона
 
    ///Установили режим обновления в зоне прямоугольника, охватывающего все элементы:
    ui->graphicsView->setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);
 
    //scene->setSceneRect(-(w+mw),-(h+mh),2*(w+mw),2*(h+mh)); /// Устанавливаем область графической сцены
    scene->setSceneRect(0, 0, w, h);
 
    /*
//добавляем сетку (upd) - конфликты колизии
    for (int i{0}; i<160; i=i+16)
    {
        scene->addLine(-i*2, -h, -i*2, h, QPen(Qt::gray)); //в минус от центра - вертикальные
        scene->addLine(i*2, -h, i*2, h, QPen(Qt::gray)); //в плюс от центра - вертикальные
 
        scene->addLine(-w, -i, w, -i, QPen(Qt::gray)); //в минус от центра - горизонтальные
        scene->addLine(-w, i, w, i, QPen(Qt::gray)); //в плюс от центра - горизонтальные
    }
    */
 
 
     /* Добавляем линии-органичения рабочей территории в графической сцене */
    /*
    scene->addLine(-w,-h, w,-h, QPen(Qt::black)); //верх
    scene->addLine(-w, h, w, h, QPen(Qt::red)); //низ
    scene->addLine(-w,-h,-w, h, QPen(Qt::black)); //лево
    scene->addLine( w,-h, w, h, QPen(Qt::black)); //право
    */
 
 
 
       //---Создаем и добавляем в сцену подвижный элемент - Облако
       //cloud = new Cloud(-w, w ); //Передали границы плавания Облака
       //int wCloud = cloud->getWidth();
       //scene->addItem(cloud); //Добавляем свой элемент - Облако
       //cloud->setPos(-w +wCloud*0.5 + 1, startYCloud);//Начальная позиция
       //y = h - hBlock*0.55  ; x = -w + wBlock*0.55;
       //timer = new QTimer(this);
       //timer->setInterval(500);
       //timer->start();
       // Подключаем сигнал таймера к слоту окна:
       //connect(timer, &QTimer::timeout, this, &MainWindow::slotTicTimer);
}
 
MainWindow::~MainWindow()
{  delete ui;  delete scene; }
 
void MainWindow::on_pushBtnAdd1_clicked()
{
    //Добавление и укладка нового блока:
    QGraphicsItem * newItem = new Block(wBlock, hBlock);
    /*
    x+= wBlock*0.7;
    if (x + wBlock*0.5 > w) x = -w + wBlock*0.55;
    //newItem->setPos(x,y);
    */
    newItem->setPos(this->wBlock/2, this->hBlock/2);
    scene->addItem(newItem);//Добавление в сцену
}
 
void MainWindow::on_pushBtnAdd2_clicked()
{
    //Добавление и укладка нового блока:
    QGraphicsItem * newItem = new Element(); //слегка неверный подход, нам нужно бы набирать из деталей с параметрами, а не просто отрисовывать
    /*
    x+= wBlock*0.7;
    if (x + wBlock*0.5 > w) x = -w + wBlock*0.55;
    //newItem->setPos(x,y);
    */
    newItem->setPos(this->wBlock/2, this->hBlock/2);
    scene->addItem(newItem);//Добавление в сцену
    qDebug() << this->wBlock;
    qDebug() << this->hBlock;
}


element.h
Кликните здесь для просмотра всего текста

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#ifndef ELEMENT_H
#define ELEMENT_H
#include <block.h>
 
class Element : public Block
{
    //Q_OBJECT;
public:
    Element();
    ~Element();
 
private:
    int wValue;
    int hValue;
 
};
#endif // ELEMENT_H


element.cpp
Кликните здесь для просмотра всего текста

C++
1
2
3
4
5
6
7
8
9
10
#include "element.h"
 
Element::Element()
 
{
    wValue=100;
    hValue=100;
}
 
Element::~Element() {}


mainwindow.ui
Кликните здесь для просмотра всего текста

XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>600</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <widget class="QPushButton" name="pushBtnAdd1">
    <property name="geometry">
     <rect>
      <x>10</x>
      <y>0</y>
      <width>75</width>
      <height>23</height>
     </rect>
    </property>
    <property name="text">
     <string>1х1 блок</string>
    </property>
   </widget>
   <widget class="QGraphicsView" name="graphicsView">
    <property name="geometry">
     <rect>
      <x>60</x>
      <y>90</y>
      <width>256</width>
      <height>192</height>
     </rect>
    </property>
   </widget>
   <widget class="QPushButton" name="pushBtnAdd2">
    <property name="geometry">
     <rect>
      <x>130</x>
      <y>0</y>
      <width>75</width>
      <height>23</height>
     </rect>
    </property>
    <property name="text">
     <string>2х1 блок</string>
    </property>
   </widget>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>800</width>
     <height>21</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>




//
Еще хотелось бы узнать для чего необходим третий параметр, и для чего вторая строчка (знаю что вопросы из разряда сиди я сам открою, но что то до меня никак не доходит, пишу такие вещи просто копипастом)
C++
1
2
Block::Block(int W, int H, QObject *parent)
    : QObject(parent), QGraphicsItem()
1
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
06.06.2021, 11:21
Ответы с готовыми решениями:

Некоторые трудности с наследованием
Всё описание в комментариях в коде. Спасибо. //Мне нужны функции в классе B, выполняющие то же...

В 90-е годы у детей была популярная игрушка - тамагочи. Игрушка представляла собой виртуальный домашний питомец
В 90-е годы у детей была популярная игрушка - тамагочи. Игрушка представляла собой виртуальный...

Создание лего
День добрый, только начал изучать Юнити, хочу сделать игру на подобии лего как майнкрафт, то есть...

2д лего. QGraphicsItemGroup?
Здравствуйте Программа лего, вид с боку Я хочу с помощью класса (detail_4) группировать блоки...

программа для роботов Лего на С++
Составить программу на С++ для роботов Лего, чтобы при загрузки программы в NXT она работала....

406
фрилансер
5838 / 5358 / 1102
Регистрация: 11.10.2019
Сообщений: 14,324
06.06.2021, 17:04 2
Цитата Сообщение от Serg1234321 Посмотреть сообщение
для чего необходим третий парамет
QObject *parent - указатель на объект, который будет владеть данным объектом (относится к Qt, читать справку по классу QObject)

Цитата Сообщение от Serg1234321 Посмотреть сообщение
и для чего вторая строчка
вызывается конструктор предка Block, то есть QObject, и в этот конструктор передаётся как раз "родитель" - будущий владелец нашего объекта. После запятой - инициализация ещё одного предка (в данном случае можно не записывать, так как параметры всё равно никакие в конструктор не переданы) (относится к C++, читать про наследование)
2
1081 / 685 / 184
Регистрация: 30.03.2021
Сообщений: 2,138
06.06.2021, 20:51 3
Цитата Сообщение от Serg1234321 Посмотреть сообщение
Деталь должна как бы "заполняться" прототипами, примерно так: элемент3х1 (деталь) заполняется (состоит из) 3-мя блоками по горизонтали, и сам элемент (деталь) является объектом, к которому мы потом можем обращаться по this в функциях (совсем круто, если каким то образом мы сможем обращаться !помимо этого! еще и к конкретным блокам-прототипам, из которых состоит элемент-деталь (кажется, это пригодится для состыковки по клеткам)
обратите внимание на

QGraphicsItemGroup * QGraphicsScene::createItemGroup ( const QList<QGraphicsItem *> & items )

Группирует все элементы в items в новую группу QGraphicsItemGroup и возвращает указатель на эту группу. Группа создаётся с общим предком items в качестве родителя и располагается в точке (0, 0). Элементы меняют родителя на эту группу и их положения и преобразования отображаются на группу.
например блок отвечает только за свою отрисовку и точку привязки, деталь создает группу из блоков, отвечает за расположение блоков относительно точки привязки детали, трансформации при клике мышкой, взаимодействие с другими деталями

зы интересно, а как вообще выглядит это лего 2д?
1
15 / 11 / 4
Регистрация: 03.08.2019
Сообщений: 209
06.06.2021, 22:07  [ТС] 4
Алексей1153, благодарю Вас за ответ. Справки читаю, но поскольку область для меня новая - многие вещи доходят как до жирафа

Цитата Сообщение от Алексей1153 Посмотреть сообщение
QObject *parent - указатель на объект, который будет владеть данным объектом
что означает "будет владеть"? я так понимаю допустим:
Кликните здесь для просмотра всего текста

[CPP]
Element elem; //допустим, являющийся потомком QObject
Block blox;
blox(0,0,Element elem);
[/CPP
]

здесь получается, что elem - parent,
то есть в дальнейшем я смогу получать доступ из elem к полям blox?

Цитата Сообщение от Алексей1153 Посмотреть сообщение
вызывается конструктор предка Block, то есть QObject
Буду благодарен, если Вы сможете более подробно объяснить что дает нам (Block'у) вызов данного конструктора QObject

//______________________

sdf45, благодарю Вас за ответ. Надеюсь, я смогу разобраться с идеей, изложенной Вами.

Цитата Сообщение от sdf45 Посмотреть сообщение
например блок отвечает только за свою отрисовку и точку привязки, деталь создает группу из блоков, отвечает за расположение блоков относительно точки привязки детали, трансформации при клике мышкой, взаимодействие с другими деталями
Примерно так я себе это и представлял, но пока не очень понимаю как реализовать это в рамках ООП, совсем недавно начал с ним знакомиться. Многие вещи для меня в новинку

ЗЫ
Цитата Сообщение от sdf45 Посмотреть сообщение
зы интересно, а как вообще выглядит это лего 2д?
Так же как и шахматы с видом сверху
А если по простому - примерно как тетрис из лего. Только детальки выбираем сами, размещаем сами, не убираем "заполненный" ряд, ну и еще пару мелочей
0
1081 / 685 / 184
Регистрация: 30.03.2021
Сообщений: 2,138
06.06.2021, 22:17 5
Цитата Сообщение от Serg1234321 Посмотреть сообщение
Так же как и шахматы с видом сверху
А если по простому - примерно как тетрис из лего. Только детальки выбираем сами, размещаем сами, не убираем "заполненный" ряд, ну и еще пару мелочей
дык вид сверху или сбоку? если свеху то нижний слой фигур перекрывается фигурами, лежащими сверху?
а если сбоку то да, получается тетрис

Добавлено через 2 минуты
Цитата Сообщение от Serg1234321 Посмотреть сообщение
Примерно так я себе это и представлял, но пока не очень понимаю как реализовать это в рамках ООП, совсем недавно начал с ним знакомиться. Многие вещи для меня в новинку
ну если код который выше выложили-Ваш, то вполне понимаете
1
19409 / 10028 / 2443
Регистрация: 30.01.2014
Сообщений: 17,678
06.06.2021, 22:25 6
Цитата Сообщение от Serg1234321 Посмотреть сообщение
что означает "будет владеть"?
Владеть - значит контролировать время жизни. Если объект создан динамически, то владеет им тот, кто вызывает delete.

Добавлено через 5 минут
Цитата Сообщение от Serg1234321 Посмотреть сообщение
что дает нам (Block'у) вызов данного конструктора QObject
Дает корректную инициализацию объекта.
Если вы ничего не напишите, то будет вызван конструктор по умолчанию.
Но в данном случае автору кода, видимо, было интересно, чтобы наследнику (Block) тоже можно было назначить владельца, на общих для всех классов Qt основаниях. Поэтому необходим был вызов конструктора, который пробросит указатель на владельца в базовый класс QObject, т.к. в нем сосредоточена вся нужная для работы машинерия. Что это дало в целом для программы - надо у автора спрашивать.
Иными словами, если этот механизм не интересен, то это минус один повод вообще наследоваться от QObject.

Цитата Сообщение от Serg1234321 Посмотреть сообщение
пишу такие вещи просто копипастом
Что из литературы читаете?
1
15 / 11 / 4
Регистрация: 03.08.2019
Сообщений: 209
06.06.2021, 22:32  [ТС] 7
sdf45, пардоньте, правильно излагаете, вид сбоку

Цитата Сообщение от sdf45 Посмотреть сообщение
ну если код который выше выложили-Ваш, то вполне понимаете
ну как тут сказать. Что то представляю, что то понимаю. Но многие вещи я делаю впервые, а большую их часть я делаю а-ля, из каких либо материалов интернетов или лекций, учебников

если вас не затруднит, могли бы Вы предложить какой то прототип для создания детали:
Цитата Сообщение от sdf45 Посмотреть сообщение
деталь создает группу из блоков
здесь у меня какой то клин. потому что, так как я придумываю, эта деталь получается просто контейнером под блоки, без какого либо логического смысла. то есть, просто переменная под три блока в ряд

Добавлено через 5 минут
DrOffset,
Цитата Сообщение от DrOffset Посмотреть сообщение
Что из литературы читаете?
по Qt - больше интернетов. Также, имеется курс лекций одного из местных университетов, с практическими примерами, собственно, хищения кода происходят преимущественно из этих лекций
по C++ - Павловская, Щупак, в свое время один хороший преподаватель порекомендовал именно эти книги
0
19409 / 10028 / 2443
Регистрация: 30.01.2014
Сообщений: 17,678
06.06.2021, 22:41 8
Цитата Сообщение от Serg1234321 Посмотреть сообщение
по Qt - больше интернетов.
Это же не относиться к Qt непосредственно. В ваших вопросах вещи-то общие для всего C++.

Цитата Сообщение от Serg1234321 Посмотреть сообщение
по C++ - Павловская, Щупак
Ну понятно.
Загляните сюда: Литература C++
1
1081 / 685 / 184
Регистрация: 30.03.2021
Сообщений: 2,138
06.06.2021, 23:18 9
Лучший ответ Сообщение было отмечено Serg1234321 как решение

Решение

Цитата Сообщение от Serg1234321 Посмотреть сообщение
деталь получается просто контейнером под блоки, без какого либо логического смысла. то есть, просто переменная под три блока в ряд
ну правильно, так и есть, вот у Вас для блока переопределен boundingRect() и paint() - габариты и отрисовка, и этого вполне достаточно для блока, думаю для него не стоит определять события для мыши.

то имеем (схематически) класс блока
C++ (Qt)
1
2
3
4
5
class block :public QGraphicsItem
  {
    boundingRect();
    paint();
  }
а в детали уже создаем группу блоков как единое целое, деталь как логический контейнер плюс взаимодействие с игроком
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
class detail :public QGraphicsItem
{
 
QGraphicsItemGroup * blocks;//группа блоков в детали
 
int geometry[2][2]; //геометрия расположения блоков в сетке 3х3
...
    void mousePressEvent(QGraphicsSceneMouseEvent *event);
    void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
    void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
}
и где-то создаете деталь
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include "block.h"
#include "detail.h"
detail detail1;
QList<block*> _blocks;
for(int i=0; i<3; i++){
  _blocks.append(new block);//создаем список из 3 блоков
}
detail1->blocks=QGraphicsScene::createItemGroup (_blocks);//группируем блоки в деталь
 
detail1.geometry[0][0]=0;
detail1.geometry[0][1]=1;
...
//геометрия детали, в виде матрицы
//0 0 0
//1 1 1
//0 0 0
//например прямая линия
//пишем функцию отображения детали на основе матрицы
зы: всё это просто наброски, схемы классов
1
15 / 11 / 4
Регистрация: 03.08.2019
Сообщений: 209
06.06.2021, 23:34  [ТС] 10
sdf45, премного благодарен, думаю, у меня получится использовать данные наработки!

возникли еще некоторые вопросы, в основном касательно запрета перемещения при столкновении блоков:

Кликните здесь для просмотра всего текста

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
void Block::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
    //qDebug() << event->pos();
    //qDebug() << x();
    //qDebug() << QCursor::pos();
    //qDebug() << event->pos().y();
 
    //Перенос мышкой:
    if (blockCaptured) //Пересчет из локальных в координаты сцены:
        this->setPos(mapToScene(event->pos()));
//(upd) очень костыльно
    //столкновение:
    if (!scene()->collidingItems(this).isEmpty())
    {
 
//(upd) нужно искать не первый объект а ближайший
        QGraphicsItem* collidingWith = scene()->collidingItems(this).at(0); //вытащили с кем столкнулись
        Block* collidingBlock;
        collidingBlock = static_cast<Block*>(collidingWith);
        qDebug() << collidingBlock->x();
 
        if (event->pos().y() != 0) //двигали по вертикали
        {
            if (event->pos().y() > 2) //вниз
            {
                qDebug() << "вниз";
                if (this->S == -1 && //Юг - вход
                        collidingBlock->N == 1) //Север - выход
                {
                    qDebug() << "стыковка вниз доступна";
                    this->setX(collidingBlock->x());
                    this->setY(collidingBlock->y()-32); //32-размер одной клетки
                    return;
                }
            }
            else if (event->pos().y() < -2) { //вверх
                qDebug() << "вверх";
                if (this->N == 1 && //Юг - вход
                        collidingBlock->S == -1) //Север - выход
                {
                    qDebug() << "стыковка вверх доступна";
                    this->setX(collidingBlock->x());
                    this->setY(collidingBlock->y()+32); //32-размер одной клетки
                    return;
                }
            }
        }
 
        if (event->pos().x() != 0) //двигали по горизонтали
        {
            if (event->pos().x() > 2) //вправо
            {
                qDebug() << "вправо";
            }
            else if (event->pos().x() < 2) { //влево
                qDebug() << "влево";
            }
        }
 
        QCursor::setPos(QCursor::pos().x() - event->pos().x(), QCursor::pos().y() - event->pos().y());
 
    }
}


1-й вопрос, касательно положения курсора. изначально я хотел при столкновении запрещать движение посредством того, чтобы возвращать курсор в положение до столкновения. но у меня возникли проблемы с глобальными координатами курсора и координатами сцены (условно, столкновение произошло в точке сцены 0х0, в таком случае, курсор выкидывало за сцену в 0х0 монитора), поэтому сделал костыль:
C++ (Qt)
1
 QCursor::setPos(QCursor::pos().x() - event->pos().x(), QCursor::pos().y() - event->pos().y());
ЗЫ даже если реализация будет другая, вопрос о курсоре в координатах сцены точно пригодиться. mapToScene пробовал, не получилось (если не ошибаюсь, из-за несоответствия типов)

2-й вопрос, я думаю, что существуют методы, запрещающие движение по какой либо из координат в +(-). к сожалению, найти таких мне не удалось. но здесь, возникает вопрос о том, как, и по какому событию возвращать права на движение
0
1081 / 685 / 184
Регистрация: 30.03.2021
Сообщений: 2,138
07.06.2021, 00:08 11
mapToScene(event->pos()).x() попробуйте так, и это же и есть координаты курсора.
попробуйте выводить интерисующие данные в qDebug(а я частенько вывожу в какойнить QTextEdit а то и вовсе в setWindowTitle(QString::number(mapToScene(event->pos()).x() )) как-то так)

Добавлено через 1 минуту
и кстати event->scenePos().x() лутше так

Добавлено через 19 минут
Цитата Сообщение от Serg1234321 Посмотреть сообщение
2-й вопрос, я думаю, что существуют методы, запрещающие движение по какой либо из координат в +(-). к сожалению, найти таких мне не удалось. но здесь, возникает вопрос о том, как, и по какому событию возвращать права на движение
я про такие не знаю, думаю это самому надо реализовывать примерно так
(хотя могу ошибаться, я эту тему только сам начал изучать так что сорри если что )
C++ (Qt)
1
2
3
4
5
6
7
8
//где-то в классе 
  QPointF oldPos;
//и в событиях мыши
 mouseMoveEvent(){
     QPointF newPos=event->pos();
     if(newPos().x()!=oldPos().x()) newPos().x()=oldPos().x();
     oldPos=newPos;
}
типа если по Х позиция изменилась - возвращаем старую -но это я на коленке, неуверен что правильно
1
15 / 11 / 4
Регистрация: 03.08.2019
Сообщений: 209
07.06.2021, 00:08  [ТС] 12
sdf45, qDebug'ом пользуюсь постоянно, отслеживаю в нем все подряд с чем возникают проблемы, порой полезно просто посмотреть какую информацию в себе хранит тот или иной объект

и прошу прощения за вопрос касательно mapToScene. вчера уже под ночь сидел с этим, очень много всего перепробовал и почему то не получалось. сейчас за пару минут:
C++ (Qt)
1
2
3
4
5
QPoint pointBreak = QCursor::pos();
//________
mapToScene(pointBreak);
        pointBreak.setY(pointBreak.y()-10); //пока костыль там заменю в условиях по направлениям
        QCursor::setPos(pointBreak);
сижу и не могу поверить, вчера столько бубнов отбил. не понимаю...
не думаю, что я действительно мог не попробовать сразу так сделать... невероятно

sdf45, большое спасибо, Ваши ответы помогли решить многие мои вопросы!

ЗЫ скоро будут вопросы касательно реализации "стыковок"
1
1081 / 685 / 184
Регистрация: 30.03.2021
Сообщений: 2,138
07.06.2021, 00:11 13
всегда рад помочь
1
15 / 11 / 4
Регистрация: 03.08.2019
Сообщений: 209
10.06.2021, 10:06  [ТС] 14
Здравствуйте.

Пытаюсь создать класс детали, в котором (внутри) буду создавать группу блоков, но что то никак до меня не дойдет что я делаю не так.
Конечно с QGraphicsItemGroup я работаю впервые.
Я думал получится так: внутри класса
создали указатель на QGraphicsItemGroup
создали 2 блока, задали им координаты
добавили эти блоки в группу.
Но что то я видимо не так понял...


.h
Кликните здесь для просмотра всего текста

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#ifndef DETAIL_H
#define DETAIL_H
#include <block.h>
#include "block.h"
#include <QGraphicsItemGroup>
 
class Detail : public Block/*, public QGraphicsItemGroup*/
{
    //Q_OBJECT;
public:
    Detail(int geo = 1);
    ~Detail();
 
private:
    QGraphicsItemGroup * blocks;
    //QList<Block*> blocks_list;
    int geometry;
};
#endif // DETAIL_H


.cpp
Кликните здесь для просмотра всего текста

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include "detail.h"
 
Detail::Detail(int geo)
{
    geometry = geo;
 
    blocks = new QGraphicsItemGroup;
 
    QGraphicsItem * block1 = new Block();
    QGraphicsItem * block2 = new Block();
 
    block1->setPos(50, 50);
 
    block2->setPos(100, 100);
 
    blocks->addToGroup(block1);
    blocks->addToGroup(block2);
}
 
Detail::~Detail() {};



Вызов с кнопки:
Кликните здесь для просмотра всего текста

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void MainWindow::on_pushBtnAdd2_clicked()
{
 
    //Добавление и укладка нового блока:
    QGraphicsItem * newDetail = new Detail(); //слегка неверный подход, нам нужно бы набирать из деталей с параметрами, а не просто отрисовывать
    /*
    x+= wBlock*0.7;
    if (x + wBlock*0.5 > w) x = -w + wBlock*0.55;
    //newItem->setPos(x,y);
    */
    newDetail->setPos(this->wBlock/2, this->hBlock/2);
    scene->addItem(newDetail);//Добавление в сцену
    //qDebug() << this->wBlock;
    //qDebug() << this->hBlock;
}


судя по дебагу блоки то добавляются... не пойму совсем

"процедурно", вроде бы получилось, но я хочу получать объект класса, и дописывать ему свои методы...

вызов с кнопки:
Кликните здесь для просмотра всего текста

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
void MainWindow::on_test_clicked()
{
 
     QGraphicsItem * newItem1 = new Block(wBlock, hBlock);
 
     QGraphicsItem * newItem2 = new Block(wBlock, hBlock);
 
 
     newItem1->setPos(50, 50);
     newItem1->setPos(100, 100);
 
 
 
     QList<QGraphicsItem*> blocks_list;
 
     blocks_list.append(newItem1);
     blocks_list.append(newItem2);
 
     QGraphicsItemGroup * group = scene->createItemGroup(blocks_list);
 
     group->setPos(200, 200);
 
     scene->addItem(group);//Добавление в сцену
    //qDebug() << this->wBlock;
    //qDebug() << this->hBlock;
}


Добавлено через 3 часа 45 минут
пардоньте. вопрос снимаю. вроде как разобрался

но все же, любые рекомендации, или подсказки где можно сделать лучше - приветствуются!

как сделал:

.h
Кликните здесь для просмотра всего текста
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#ifndef DETAIL_2_H
#define DETAIL_2_H
#include <QGraphicsItemGroup>
#include "block.h"
 
class Detail_2 :public QGraphicsItemGroup
{
public:
    Detail_2();
    ~Detail_2();
 
private: //в след прототипе:
    //сюда наверное пихну геометрию
 
    //сюда наверное пихну сенсу
};
 
#endif // DETAIL_2_H


.cpp
Кликните здесь для просмотра всего текста
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "detail_2.h"
 
Detail_2::Detail_2()
    //: QGraphicsItemGroup()
{
    setFlags(QGraphicsItem::ItemIsMovable);
    QGraphicsItem * newItem1 = new Block();
    QGraphicsItem * newItem2 = new Block();
    newItem2->setPos(32,0);
    addToGroup(newItem1);
    addToGroup(newItem2);
}
 
Detail_2::~Detail_2(){};


черновые версии
0
1081 / 685 / 184
Регистрация: 30.03.2021
Сообщений: 2,138
10.06.2021, 17:23 15
Цитата Сообщение от Serg1234321 Посмотреть сообщение
я хочу получать объект класса, и дописывать ему свои методы...
вызов с кнопки
несовсем понял проблему, ну так как решилось - и ладно

Цитата Сообщение от Serg1234321 Посмотреть сообщение
но все же, любые рекомендации, или подсказки где можно сделать лучше - приветствуются!
Я похоже сделал, с Вашего кода скопипастил отрисовку, задается геометрия детали в сетке 3х3, деталь двигается мышкой.
Можно тетрис зафигачить
Сорри за эту простыню, как сделать чтобы блок кода сворачивался?
Сделал обработку мыши в классе детали-но по феншую, имхо, надо бы в кастомной сцене ловить.
Ну и, геометрию задавать массивом - наверное не очень красиво, но больше ничего не придумалось.

block.h
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#ifndef BLOCK_H
#define BLOCK_H
 
#include <QGraphicsItem>
#include <QObject>
#include <QPainter>
 
class block : public QObject, public QGraphicsItem
{
    Q_OBJECT
public:
    block(int dx=0, int dy=0, QObject *parent = 0);
    //dx, dy - положение блока в детали
    int width=30;
    int heigth=30;
private:
 
    QBrush brush;
    QPen pen;
protected:
    QRectF boundingRect() const ;
    void paint(QPainter *painter,
               const QStyleOptionGraphicsItem *option,
               QWidget *widget);
};
 
#endif // BLOCK_H
block.cpp
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include "block.h"
 
block::block(int dx, int dy, QObject *parent) : QObject(parent), QGraphicsItem(){
        pen.setColor(Qt::darkRed);
        pen.setWidth(3);
        brush.setColor(Qt::lightGray);
        brush.setStyle(Qt::SolidPattern);
        moveBy(dx,dy); //смещаем на свою позицию
}
 
 
void block::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget){
    painter->setPen(pen);
    painter->setBrush(brush);
    painter->drawRect(0, 0, width, heigth);
    Q_UNUSED(option)
    Q_UNUSED(widget)
}
 
QRectF block::boundingRect() const{
    return QRectF(0, 0, width, heigth);
}
detail.h
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#ifndef DETAIL_H
#define DETAIL_H
 
#include <QObject>
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsItemGroup>
#include "block.h"
#include <QGraphicsScene>
 
 
class detail : public QObject , public QGraphicsItemGroup
{
    Q_OBJECT
public:
    detail(QGraphicsScene * _scene, int geometry[3][3], QObject *parent = 0);
    //в конструкторе передаем сцену и геометрию в виде массива
 
    QGraphicsItemGroup *group;//группа блоков в детали
 
    void mousePressEvent(QGraphicsSceneMouseEvent *event);
    void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
    void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
};
 
#endif // DETAIL_H
detail.cpp
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include "detail.h"
 
detail::detail(QGraphicsScene * _scene, int geometry[3][3], QObject *parent)
                          : QObject(parent), QGraphicsItemGroup() {
 
    QList<QGraphicsItem*> _blocks;
    //список итемов(блоков), которые передадим в группу детали
    for(int x=0; x<3; x++){
        for(int y=0; y<3; y++){
            if(geometry[x][y]==1){
                auto *_block=new block;
                int width = _block->width;
                int height = _block->heigth;
                _blocks.append(new block(x*width, y*height));
                //раскручиваем массив, создаем блок если элемент массива=1
                //передавая позицию блока при его создании
            }
        }
    }
 
    group = _scene->createItemGroup(_blocks);//добавляем список блоков в группу детали
    group->setFlag(QGraphicsItem::ItemIsMovable);
}
 
 
void detail::mouseMoveEvent(QGraphicsSceneMouseEvent *event){
    this->setPos(mapToScene(event->pos()));//двигаем деталь
}
 
void detail::mouseReleaseEvent(QGraphicsSceneMouseEvent *event){}]
void detail::mousePressEvent(QGraphicsSceneMouseEvent *event){}
mainwindow.h
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include "mainwindow.h"
 
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
       scene=new QGraphicsScene(this);
       view =new QGraphicsView(scene);
       setCentralWidget(view);
 
       int geometry[3][3]={0};
           geometry[0][0]=1;
           geometry[1][0]=1;
           geometry[2][0]=1;
           geometry[0][1]=1;
           //указываем геометрию детали
 
       detail detail1(scene, geometry);//создаем деталь
}
 
MainWindow::~MainWindow()
{
}
выглядит так:
https://www.cyberforum.ru/atta... 1623334974
Миниатюры
Qt, лего игрушка (2д), трудности с наследованием и "детальками"  
0
1081 / 685 / 184
Регистрация: 30.03.2021
Сообщений: 2,138
10.06.2021, 18:24 16
mainwindow.cpp очепятался
main.cpp дефолтный.

Добавлено через 15 минут
и тут ерунду конечно написал костыли
C++ (Qt)
1
2
3
4
5
6
7
if(geometry[x][y]==1){
                auto *_block=new block;
                int width = _block->width;
                int height = _block->heigth;
 
                _blocks.append(new block(x*width, y*height));               
            }
тогда или delete _block; после получения width и height, либо уже напрямую
_blocks.append(new block(x*30, y*30)); без auto и так далее
либо в классе детали определить размеры блока, чет у меня разум за ум зашол уже

Добавлено через 19 минут
если кто из спецов это читает, как кастануть мой класс (block) в QGraphicsItem?
методом тыка пробовал static_cast, dynamic_cast, qgraphics_cast но видимо надо выпрямитель для рук, ничего не вышло
0
фрилансер
5838 / 5358 / 1102
Регистрация: 11.10.2019
Сообщений: 14,324
10.06.2021, 18:30 17
sdf45, а зачем явно кастить, он же потомок? Что именно не получилось ?
0
15 / 11 / 4
Регистрация: 03.08.2019
Сообщений: 209
10.06.2021, 18:42  [ТС] 18
sdf45, здравствуйте

я реализовал вот так (пока тоже довольно черновые варианты):
block и тд - старые

прототип детали.h
Кликните здесь для просмотра всего текста
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#ifndef DETAIL_3_H
#define DETAIL_3_H
#include <QGraphicsItem>
#include <block.h>
 
class Detail_3 :public QGraphicsItemGroup
{
public:
    Detail_3(bool geometry[3][3]);
    ~Detail_3();
 
private: //в след прототипе:
    //сюда наверное пихну геометрию
    bool geometry[3][3];
 
    //сюда наверное пихну сенсу
    //int sens[3][3];
    //придумать как будут пихаться значения
    //прото:
    /*
    0 0 0
    0 0 0
    0 0 0
 
    и дропать структуру? (WASD) или (NSEW) в каждую из клеток
 
    */
};
#endif // DETAIL_3_H


прототип детали.cpp
Кликните здесь для просмотра всего текста
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include "detail_3.h"
 
Detail_3::Detail_3(bool geometry[3][3])
    //: QGraphicsItemGroup()
{
    //int i_y
    for(int i{}; i<3; i++) //проход строк (по y)
    {
        for(int n{}; n<3; n++) //проход столбов (по x)
        {
            if(geometry[i][n]==1)
            {
                //addToGroup(new Block());
                QGraphicsItem* newBlock = new Block();
                newBlock->setPos(i*32, n*32);
                addToGroup(newBlock);
            }
        }
    }
    setFlags(QGraphicsItem::ItemIsMovable);
}
 
Detail_3::~Detail_3(){};


вызов с кнопки:
Кликните здесь для просмотра всего текста
C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void MainWindow::on_pushBtnAdd3_clicked()
{
    bool geo[3][3] =
    {
        {0, 0, 1},
        {0, 1, 1},
        {1, 1, 1}
    };
 
    QGraphicsItem * newItem = new Detail_3(geo);
 
    newItem->setPos(20,20);
    scene->addItem(newItem);//Добавление в сцену
}


картинка прилагается

но, тут один важный вопрос появляется. если раньше можно было "стыковать" блоки 1х1 с помощью scene()->collidingItems(this), то теперь у нас есть QGraphicsItemGroup, и если деталь неправильной формы (как у Вас, или как у меня на скрине) - то данный подход кажется не получится использовать, т.к. QGraphicsItemGroup вернет нам форму (не уверен что правильно называю это) квадрата (как если бы матрица была заполнена 3х3)
возможно, существуют способы вернуть форму, отличную от овала или прямоугольника?
не знаю даже, я думал о том, что возможно, придется писать собственные методы для проверки на столкновение, наезды, стыковки, но что то ничего умного не придумал

здесь еще добавляется вопрос о том, что несколько деталей могут образовывать дополнительные "неправильные" формы, и каждое столкновение нужно рассматривать по типу:
каждый блок (из которого набирается наша деталь) каким то волшебством должна "ощущать" столкновение с блоками (!именно блоками) другой (сборной из блоков) детали, и "упираться", либо допускать стыковку, и в этом случае проверять возможность стыковки следующего блока этой детали. пока это лучшее, что удалось придумать. реализацией пока не занимался. но думаю, дополнительно в поле "геометрии - стыкуемости" (матрица) детали - нужно хранить центральные точки каждого блока, из которого состоит деталь

Не по теме:

ЗЫ в спойлер оборачивать - на панельке кнопочка +

0
15 / 11 / 4
Регистрация: 03.08.2019
Сообщений: 209
10.06.2021, 18:47  [ТС] 19

Не по теме:

ЗЫ ЗЫ а как картинку то выложить?

Миниатюры
Qt, лего игрушка (2д), трудности с наследованием и "детальками"  
0
1081 / 685 / 184
Регистрация: 30.03.2021
Сообщений: 2,138
10.06.2021, 18:53 20
Цитата Сообщение от Алексей1153 Посмотреть сообщение
sdf45, а зачем явно кастить, он же потомок? Что именно не получилось ?
простите это я уже черте-что понавыдумывал, вся моя проблема вот тут вот
C++ (Qt)
1
2
3
4
5
auto *_block=new block;
                int width = _block->width;
                int height = _block->heigth;
                delete _block;
                _blocks.append(new block(x*width, y*height));
надо узнать ширину и высоту блока, что бы использовать в конструкторе этого самого блока, сам себя перемудрил как говорится просто переработал наверное, сорри за дурные вопросы

Добавлено через 6 минут
Цитата Сообщение от Serg1234321 Посмотреть сообщение
здесь еще добавляется вопрос о том, что несколько деталей могут образовывать дополнительные "неправильные" формы, и каждое столкновение нужно рассматривать по типу:
каждый блок (из которого набирается наша деталь) каким то волшебством должна "ощущать" столкновение с блоками (!именно блоками) другой (сборной из блоков) детали, и "упираться", либо допускать стыковку, и в этом случае проверять возможность стыковки следующего блока этой детали. пока это лучшее, что удалось придумать. реализацией пока не занимался. но думаю, дополнительно в поле "геометрии - стыкуемости" (матрица) детали - нужно хранить центральные точки каждого блока, из которого состоит деталь
немножко позжее попробую разобраться, надо тестить, сейчас немогу сказать, сорри
0
10.06.2021, 18:53
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
10.06.2021, 18:53
Помогаю со студенческими работами здесь

3D Конструктор в стиле лего с облетом камеры
Доброй ночи всем. Возникла необходимость для преподавателя сделать трехмерный конструктор,...

Игрушка
Класс игрока : class Player: def __init__(self, hp=200, mana=200): self.hp = hp ...

Игрушка
Ребят есть у кого нить простенькая игрушка написанная на Microsoft Visual Basic 2005/ Скиньте пж.

Игрушка
Как сделать игру Когда наступаешь на платформу открывается меню с вопросами, отвечаешь на ответ...

Игрушка на с++
хочу сделать небольшую игру на с++, в которой можно будет кататься на машинке(вид сверху), будут...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru