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

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 г. 13: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 г. 13: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
                            • 2 июня 2018 г. 4: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/ Используйте, пожалуйста, для вставки кода специальное диалоговое окно, это кнопочка на панели инструментов со значками <>

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

                                          Комментарии

                                          Только авторизованные пользователи могут публиковать комментарии.
                                          Пожалуйста, авторизуйтесь или зарегистрируйтесь
                                          Ua

                                          Qt - Тест 001. Сигналы и слоты

                                          • Результат:84баллов,
                                          • Очки рейтинга4
                                          Ua

                                          Qt - Тест 001. Сигналы и слоты

                                          • Результат:42баллов,
                                          • Очки рейтинга-8
                                          ОК

                                          Qt - Тест 001. Сигналы и слоты

                                          • Результат:47баллов,
                                          • Очки рейтинга-6
                                          Последние комментарии
                                          ИМ
                                          Игорь Максимов22 ноября 2024 г. 21:51
                                          Django - Урок 017. Кастомизированная страница авторизации на Django Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
                                          Evgenii Legotckoi
                                          Evgenii Legotckoi31 октября 2024 г. 23:37
                                          Django - Урок 064. Как написать расширение для Python Markdown Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
                                          A
                                          ALO1ZE19 октября 2024 г. 17:19
                                          Читалка fb3-файлов на Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
                                          ИМ
                                          Игорь Максимов5 октября 2024 г. 16:51
                                          Django - Урок 064. Как написать расширение для Python Markdown Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
                                          d
                                          dblas55 июля 2024 г. 20:02
                                          QML - Урок 016. База данных SQLite и работа с ней в QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
                                          Сейчас обсуждают на форуме
                                          f
                                          firstlunoxod15 февраля 2025 г. 13:46
                                          Рисование на QGraphicsScene при зажатой кнопке мыши Подскажите, пожалуйста! Как данный класс можно дополнить, чтобы созданные объекты можно было перемещать мышкой по сцене?
                                          Дмитрий
                                          Дмитрий3 февраля 2025 г. 16:24
                                          Создание deb-пакета. Как создать ярлык на рабочем столе после установки собственного deb-пакета? Всем привет. Сделал свой deb-пакет с программой. Всё устанавливается и работает. Ставлю по пути /usr/bin/my_application. Как для пользователя при установке пакета сразу создать ярлык на раб…
                                          NW
                                          Nayo Wai30 января 2025 г. 19:22
                                          не запускается компьютер!!! Не запускается компьютер (точнее работает блок , но сам монитор вообще жесть)В общем я ничего с интернета не скачивала в последнее время. На компе никаких левых пр…
                                          n
                                          nkly3 января 2025 г. 12:52
                                          Нужно запретить перемещение только некоторых итемов, остальные перемещать можно. Вопрос решен. Узнать QModelIndex элемента на который мы перетаскиваем другой элемент, можно с помощью функции indexAt(event->position().toPoint()) представления QTreeViev вызываемой в переопр…
                                          M
                                          Marsel17 августа 2023 г. 0:26
                                          OAuth2.0 через VK, получение email Спасибо большое за помощь и простите за то что отнял время своей невнимательностью.

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