ЕС
Евгений Сальников29 травня 2018 р. 12:55

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

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
ЕС
  • 29 травня 2018 р. 22:01

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

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 р. 03:05
    • (відредаговано)

    Добрый день!

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

    Если не понятно, то вечером постараюсь накидать пример кода, сейчас немного некогда.
      ЕС
      • 30 травня 2018 р. 12:39

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

      новый класс 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 р. 03:21

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

        Он объявлен в классе QGraphicsItem и не имеет реализации, поэтому его нужно также переопределить и дать своб реализацию.
          ЕС
          • 31 травня 2018 р. 06:00

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


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

            написал так

            в 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()
            {
            
            }
            
            пока что по крайней мере нет ошибок
              ЕС
              • 31 травня 2018 р. 12:26

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

                Evgenii Legotckoi
                • 01 червня 2018 р. 10:54

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

                  ЕС
                  • 01 червня 2018 р. 11:15

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

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

                    Evgenii Legotckoi
                    • 01 червня 2018 р. 14:27

                    тааак...

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

                      ЕС
                      • 01 червня 2018 р. 14:31
                      TestLand *mi = new TestLand (it->pos().x(),it->pos().y(),30,30);
                                  addItem(mi);
                      вот тут ругается на добавление
                       
                      ошибка: 'QGraphicsItem' is an ambiguous base of 'TestLand' addItem(mi);
                      ^
                        Evgenii Legotckoi
                        • 01 червня 2018 р. 15:05

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

                          ЕС
                          • 01 червня 2018 р. 15:12

                          есть 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
                            • 01 червня 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 не нужно. Это неправильно.
                              ЕС
                              • 02 червня 2018 р. 04:46

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

                              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)
                              ^
                                Evgenii Legotckoi
                                • 02 червня 2018 р. 05:02

                                Эх... ну правильно, у вас же конструктора такого у 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"));
                                }
                                  ЕС
                                  • 02 червня 2018 р. 07:07

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

                                    ЕС
                                    • 02 червня 2018 р. 08:30

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

                                    Что нибудь наподобие такого
                                    1. QList<QGraphicsItem *> foundItems = scene()->items(QPolygonF()
                                    2. << mapToScene(0, 0)
                                    3. << mapToScene(-20, -20)
                                    4. << mapToScene(20, -20));
                                    Только для collidingitem?
                                      Evgenii Legotckoi
                                      • 02 червня 2018 р. 10:26

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

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

                                      P/S/ Используйте, пожалуйста, для вставки кода специальное диалоговое окно, это кнопочка на панели инструментов со значками <>
                                        ЕС
                                        • 02 червня 2018 р. 10:36

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

                                          Коментарі

                                          Only authorized users can post comments.
                                          Please, Log in or Sign up
                                          AD

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

                                          • Результат:50бали,
                                          • Рейтинг балів-4
                                          m
                                          • molni99
                                          • 26 жовтня 2024 р. 01:37

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

                                          • Результат:80бали,
                                          • Рейтинг балів4
                                          m
                                          • molni99
                                          • 26 жовтня 2024 р. 01:29

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

                                          • Результат:20бали,
                                          • Рейтинг балів-10
                                          Останні коментарі
                                          ИМ
                                          Игорь Максимов22 листопада 2024 р. 11:51
                                          Django - Підручник 017. Налаштуйте сторінку входу до Django Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
                                          Evgenii Legotckoi
                                          Evgenii Legotckoi31 жовтня 2024 р. 14:37
                                          Django - Урок 064. Як написати розширення для Python Markdown Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
                                          A
                                          ALO1ZE19 жовтня 2024 р. 08:19
                                          Читалка файлів fb3 на Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
                                          ИМ
                                          Игорь Максимов05 жовтня 2024 р. 07:51
                                          Django - Урок 064. Як написати розширення для Python Markdown Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
                                          d
                                          dblas505 липня 2024 р. 11:02
                                          QML - Урок 016. База даних SQLite та робота з нею в QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
                                          Тепер обговоріть на форумі
                                          Evgenii Legotckoi
                                          Evgenii Legotckoi24 червня 2024 р. 15:11
                                          добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
                                          t
                                          tonypeachey115 листопада 2024 р. 06:04
                                          google domain [url=https://google.com/]domain[/url] domain [http://www.example.com link title]
                                          NSProject
                                          NSProject04 червня 2022 р. 03:49
                                          Всё ещё разбираюсь с кешем. В следствии прочтения данной статьи. Я принял для себя решение сделать кеширование свойств менеджера модели LikeDislike. И так как установка evileg_core для меня не была возможна, ибо он писался…
                                          9
                                          9Anonim25 жовтня 2024 р. 09:10
                                          Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…

                                          Слідкуйте за нами в соціальних мережах