Проблемы с коллизией

Qt, С++, Игры

У меня есть три основным класса land из него состоит поле 30 на 30 это картинка, класс blockland это тоже картинка которую я добавляю при нажатии на правую кнопку мыши на поле и есть класс actor это герой он по клеткам идет туда куда я кликнул. Мне нужно сделать проверку коллизии, чтобы при встрече на сцене blockland он его обходил. Пытаюсь сделать так:

blockland *test;
case  ActorAction::Down: m_moveAnimation->setPosAt(1.0, pos()+QPointF(0, SpeedPx));
            QList<QGraphicsItem*>items = scene()->items(QPolygonF()<<mapToScene(0,0)<<mapToScene(20,20)<<mapToScene(-20,-20));
            foreach (QGraphicsItem *item,items)
            {
                if(item==this)
                {
                    continue;
                }
                if(item==test)
                {
                     m_moveAnimation->setPosAt(1.0, pos()+QPointF(0, -SpeedPx));
                }
            }
В итоге он разворачивает совершенно в рандомный момент когда я устанавливаю blockland на сцене. Пытался сделать через if(!scene()->collidingItems(this).isEmpty()) тоже не получилось ни как обозначить класс blockland. Пытался написать через формирование абстрактоного пула для объектов но после установление этого пула как одного из родителей класс выдавал ошибки типа : invalid new-expression of abstract class type. Уже всю голову сломал как еще можно это сделать.
Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.

Вам это нравится? Поделитесь в социальных сетях!

20

Еще попробовал таким образом

QList<QGraphicsItem*>item = this->collidingItems(m_actor);
        if(!item.isEmpty())
        {
            for (auto items : item)
            {
                if(testl)
                {
                    m_actor->processMouse(ActorAction::Left);
                }
            }
        }
но так как isEmpty срабатывает тогда когда объект сталкивается с каким либо объектом а все мое состоит из объектов то условие срабатывает всегда, не как не могу заставить персонажа отличать обычную ячейку от заблокированной
    Evgenii Legotckoi
    • 30 мая 2018 г. 3:05
    • (ред.)

    Добрый день!

    Вам нужно создать базовый класс, который наследован от QGraphicsItem, а все ваши игровые объекты уже наследовать от него.
    В этой базовом классе вам нужно добавить метод getType(), который будет возвращать либо тип int, либо enum.
    Также в базовом классе нужно будет перечислить все в enum все типы игровых объектов, а когда будетт брать объекты через collidingItems, то кастовать каждый объект к типу вашего нового базового класса и проверять через метод getType(), можно ли на этот объект реагировать или нет.
    В каждом наследованном классе нужно будет переопределить метод getType() так, чтобы он возвращал enum, который соответствует типу этого объекта.
    Подобный функционал был реализован вот в этой статье по полиморфизму

    Если не понятно, то вечером постараюсь накидать пример кода, сейчас немного некогда.

      Я уже пытался сделать таким образом, видел ваш пример в другом посте сделал вот так вот

      новый класс gameobject:
      h файл
      #ifndef GAMEOBJECT_H
      #define GAMEOBJECT_H
      
       
      #include <QGraphicsItem>
      
       
      class gameobject : public QGraphicsItem
      {
          Q_OBJECT
      public:
          explicit gameobject(QGraphicsItem *parent =nullptr);
          enum Type
          {
              blockwall,
              bullet,
              mod,
          };
      
       
      };
      
       
      #endif // GAMEOBJECT_H
      срр файл
      #include "gameobject.h"
      
       
      gameobject::gameobject(QGraphicsItem *parent)
      {
      
       
      }

      Наследовал класс который хотел занести туда

      #include <gameobject.h>
      class TestLand :public gameobject
      
      определял слот возврата
      virtual int type() const override;
      это в h файле в срр так писал
       
      int TestLand::type()
      {
          return Type::blockwall;
      }
      
      в итоге этот класс при попытке обозначит его на сцене
       TestLand *mi = new TestLand (it->pos().x(),it->pos().y(),30,30);
      возвращал такую ошибку:  invalid new-expression of abstract class type
        Evgenii Legotckoi
        • 31 мая 2018 г. 3:21

        вам нудно переопределить метод boundingRect.

        Он объявлен в классе QGraphicsItem и не имеет реализации, поэтому его нужно также переопределить и дать своб реализацию.

          Попытался переопределить boundingRec() и процессе поиска информации понял что он вроде как применяется только для непосредственно нарисованных объектов а у меня все в картинка. После этого наследовал базовый класс от QGraphicsPixMapItem и теперь у меня ошибка при попытке вернуть тип в классе который я наследую от базового


          virtual int type() const override;
          вот в этой строке, следующая ошибка
          ошибка: prototype for 'int TestLand::type()' does not match any in class 'TestLand' int TestLand::type()

            написал так

            в H файле
            #ifndef GAMEOBJECT_H
            #define GAMEOBJECT_H
            
            #include <QGraphicsItem>
            #include <QObject>
            #include <QGraphicsPixmapItem>
            
            
            class gameobject: public QObject, public QGraphicsPixmapItem
            {
                Q_OBJECT
            public:
               explicit gameobject(qreal x, qreal y, qreal w, qreal h, QGraphicsItem *parent=0);
                enum Type
                {
                    blockland,
                    mob,
                    tower,
                    bullet,
                    hero,
                    land
                };
            public:
            
            
            };
            
            #endif // GAMEOBJECT_H
            и в срр
            #include "gameobject.h"
            
            gameobject::gameobject(qreal x, qreal y, qreal w, qreal h, QGraphicsItem *parent)
                :QObject()
            {
            
            }
            
            пока что по крайней мере нет ошибок

              Но теперь все классы которые я наследую от базового вызывают ошибку при попытке их добавить на сцену и установить их позицию методами addItem и setPos или при использовании setZValue

                А вы текст ошибки прилагать будете?
                Плюсом я вам указывал на статью, где есть пример с абстрактным методом getType() в базовом классе. Пробовали сделать, как в той статье?

                  Ошибки вот такого типа

                  При использовании setPose  и setZValue
                  ошибка: request for member 'setPos' is ambiguous
                  При использовании addItem
                  ошибка: 'QGraphicsItem' is an ambiguous base of 'hero_actor'
                  Да конечно пытался, я уже не один день пытаюсь сделать это и все найденные примеры перепробовал

                    тааак...

                    Есть одна мысль.
                    Реализация конструктора точно не правильно написана. У вас там множественное наследование.
                    gameobject::gameobject(qreal x, qreal y, qreal w, qreal h, QGraphicsItem *parent)
                        : QObject(), QGraphicsPixmapItem(parent)
                    {
                    }
                    Исправьте это, а там скажете, какие ещё ошибки посыпятся. Но так конструктор будет правильный.

                      TestLand *mi = new TestLand (it->pos().x(),it->pos().y(),30,30);
                                  addItem(mi);
                      вот тут ругается на добавление
                       
                      ошибка: 'QGraphicsItem' is an ambiguous base of 'TestLand' addItem(mi);
                      ^

                        Какая у вас иерархия наследования классов сейчас? Что-то совсем по ходу намудрили.

                          есть gameobject

                          h:
                          #ifndef GAMEOBJECT_H
                          #define GAMEOBJECT_H
                          
                          #include <QGraphicsItem>
                          #include <QObject>
                          #include <QGraphicsPixmapItem>
                          
                          
                          class gameobject: public QObject, public QGraphicsPixmapItem
                          {
                              Q_OBJECT
                          public:
                             explicit gameobject(qreal x, qreal y, qreal w, qreal h, QGraphicsItem *parent=0);
                              enum Type
                              {
                                  blockland,
                                  mob,
                                  tower,
                                  bullet,
                                  hero,
                                  land
                              };
                          public:
                          
                          
                          };
                          
                          #endif // GAMEOBJECT_H
                          
                          cpp
                          #include "gameobject.h"
                          
                          gameobject::gameobject(qreal x, qreal y, qreal w, qreal h, QGraphicsItem *parent)
                              : QObject(), QGraphicsPixmapItem(parent)
                          {
                          
                          }
                          
                          и есть testland
                          h
                          #ifndef TESTLAND_H
                          #define TESTLAND_H
                          
                          
                          #include <QtWidgets>
                          #include <QObject>
                          #include <gameobject.h>
                          
                          
                          
                          
                          class TestLand :public gameobject, public QGraphicsPixmapItem
                          {
                              Q_OBJECT
                          public:
                               TestLand(qreal x, qreal y, qreal w, qreal h, QGraphicsItem *parent=0);
                               virtual int type() const;
                          };
                          
                          #endif // TESTLAND_H
                          
                          cpp
                          #include "testland.h"
                          #include <QGraphicsItem>
                          
                          
                          
                          TestLand::TestLand(qreal x, qreal y, qreal w, qreal h, QGraphicsItem *parent)
                              :gameobject(parent)
                          {
                              setPos(QPointF(x,y));
                              this->setPixmap(QPixmap("land_2.jpg"));
                          }
                          
                          int TestLand::type() const
                          {
                          
                          }

                           

                          ну и сцена где я все добавляю, там у меня много классов которые я пока еще ни от кого не наследую
                            Evgenii Legotckoi
                            • 1 июня 2018 г. 18:16

                            Вот так должно выглядеть наследование для класса TestLand


                            class TestLand :public gameobject
                            {
                                Q_OBJECT
                            public:
                                 TestLand(qreal x, qreal y, qreal w, qreal h, QGraphicsItem *parent=0);
                                 virtual int type() const;
                            };
                            У вас gameobject и так уже наследован от QGraphicsPixmapItem , поэтому добавлять это наследование в TestLand не нужно. Это неправильно.

                              Теперь снова ошибка

                              TestLand::TestLand(qreal x, qreal y, qreal w, qreal h, QGraphicsItem *parent)
                                  :gameobject(parent) // ругается на это
                              ошибка: no matching function for call to 'gameobject::gameobject(QGraphicsItem*&)'
                              :gameobject(parent)
                              ^

                                Эх... ну правильно, у вас же конструктора такого у gameobject нет.

                                TestLand::TestLand(qreal x, qreal y, qreal w, qreal h, QGraphicsItem *parent)
                                    : gameobject(x, y, w, h, parent)
                                {
                                    setPos(QPointF(x,y));
                                    this->setPixmap(QPixmap("land_2.jpg"));
                                }

                                  Спасибо огромное за помощь. Намучился ты со мною конечно, без тебя бы не зделал

                                    Еще один вопрос, можно ли использовать collidingitem перед объектом.

                                    Что нибудь наподобие такого
                                    1. QList<QGraphicsItem *> foundItems = scene()->items(QPolygonF()
                                    2. << mapToScene(0, 0)
                                    3. << mapToScene(-20, -20)
                                    4. << mapToScene(20, -20));
                                    Только для collidingitem?

                                      Вы можете использовать метод items() только передавать в него форму вашего объекта.

                                      Так
                                      QList<QGraphicsItem *> foundItems = scene()->items(myItem->boundingRect());
                                      Или так
                                      QList<QGraphicsItem *> foundItems = scene()->items(myItem->shape());

                                      P/S/ Используйте, пожалуйста, для вставки кода специальное диалоговое окно, это кнопочка на панели инструментов со значками <>

                                        Учту, еще раз спасибо большое за помощь

                                          Комментарии

                                          Только авторизованные пользователи могут публиковать комментарии.
                                          Пожалуйста, авторизуйтесь или зарегистрируйтесь
                                          SH
                                          • Sak Hax
                                          • 25 апреля 2024 г. 14:00

                                          C++ - Тест 001. Первая программа и типы данных

                                          • Результат:33баллов,
                                          • Очки рейтинга-10
                                          г
                                          • ги
                                          • 23 апреля 2024 г. 15:51

                                          C++ - Тест 005. Структуры и Классы

                                          • Результат:41баллов,
                                          • Очки рейтинга-8
                                          l
                                          • laei
                                          • 23 апреля 2024 г. 9:19

                                          C++ - Тест 004. Указатели, Массивы и Циклы

                                          • Результат:10баллов,
                                          • Очки рейтинга-10
                                          Последние комментарии
                                          k
                                          kmssr8 февраля 2024 г. 18:43
                                          Qt Linux - Урок 001. Автозапуск Qt приложения под Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
                                          АК
                                          Анатолий Кононенко5 февраля 2024 г. 1:50
                                          Qt WinAPI - Урок 007. Работаем с ICMP Ping в Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
                                          EVA
                                          EVA25 декабря 2023 г. 10:30
                                          Boost - статическая линковка в CMake проекте под Windows Ошибка LNK1104 часто возникает, когда компоновщик не может найти или открыть файл библиотеки. В вашем случае, это файл libboost_locale-vc142-mt-gd-x64-1_74.lib из библиотеки Boost для C+…
                                          J
                                          JonnyJo25 декабря 2023 г. 8:38
                                          Boost - статическая линковка в CMake проекте под Windows Сделал всё по-как у вас, но выдаёт ошибку [build] LINK : fatal error LNK1104: не удается открыть файл "libboost_locale-vc142-mt-gd-x64-1_74.lib" Хоть убей, не могу понять в чём дел…
                                          G
                                          Gvozdik18 декабря 2023 г. 21:01
                                          Qt/C++ - Урок 056. Подключение библиотеки Boost в Qt для компиляторов MinGW и MSVC Для решения твой проблемы добавь в файл .pro строчку "LIBS += -lws2_32" она решит проблему , лично мне помогло.
                                          Сейчас обсуждают на форуме
                                          G
                                          Gar22 апреля 2024 г. 5:46
                                          Clipboard Как скопировать окно целиком в clipb?
                                          DA
                                          Dr Gangil Academics20 апреля 2024 г. 7:45
                                          Unlock Your Aesthetic Potential: Explore MSC in Facial Aesthetics and Cosmetology in India Embark on a transformative journey with an msc in facial aesthetics and cosmetology in india . Delve into the intricate world of beauty and rejuvenation, guided by expert faculty and …
                                          a
                                          a_vlasov14 апреля 2024 г. 6:41
                                          Мобильное приложение на C++Qt и бэкенд к нему на Django Rest Framework Евгений, добрый день! Такой вопрос. Верно ли следующее утверждение: Любое Android-приложение, написанное на Java/Kotlin чисто теоретически (пусть и с большими трудностями) можно написать и на C+…
                                          Павел Дорофеев
                                          Павел Дорофеев14 апреля 2024 г. 2:35
                                          QTableWidget с 2 заголовками Вот тут есть кастомный QTableView с многорядностью проект поддерживается, обращайтесь
                                          f
                                          fastrex4 апреля 2024 г. 4:47
                                          Вернуть старое поведение QComboBox, не менять индекс при resetModel Добрый день! У нас много проектов в которых используется QComboBox, в версии 5.5.1, когда модель испускает сигнал resetModel, currentIndex не менялся. В версии 5.15 при resetModel происходит try…

                                          Следите за нами в социальных сетях