ЕС
Евгений СальниковМамыр 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, 10: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, 3: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, 3:21 Т.Ж.

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

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

          Попытался переопределить 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
                • Маусым 1, 2018, 10:54 Т.Ж.

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

                  ЕС
                  • Маусым 1, 2018, 11:15 Т.Ж.

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

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

                    Evgenii Legotckoi
                    • Маусым 1, 2018, 2:27 Т.Қ.

                    тааак...

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

                      ЕС
                      • Маусым 1, 2018, 2: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
                        • Маусым 1, 2018, 3:05 Т.Қ.

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

                          ЕС
                          • Маусым 1, 2018, 3: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
                            • Маусым 1, 2018, 6: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 не нужно. Это неправильно.
                              ЕС
                              • Маусым 2, 2018, 4: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
                                • Маусым 2, 2018, 5: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"));
                                }
                                  ЕС
                                  • Маусым 2, 2018, 7:07 Т.Ж.

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

                                    ЕС
                                    • Маусым 2, 2018, 8:30 Т.Ж.

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

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

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

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

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

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

                                          Пікірлер

                                          Тек рұқсаты бар пайдаланушылар ғана пікір қалдыра алады.
                                          Кіріңіз немесе Тіркеліңіз
                                          AD

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

                                          • Нәтиже:50ұпай,
                                          • Бағалау ұпайлары-4
                                          m
                                          • molni99
                                          • Қаз. 26, 2024, 1:37 Т.Ж.

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

                                          • Нәтиже:80ұпай,
                                          • Бағалау ұпайлары4
                                          m
                                          • molni99
                                          • Қаз. 26, 2024, 1:29 Т.Ж.

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

                                          • Нәтиже:20ұпай,
                                          • Бағалау ұпайлары-10
                                          Соңғы пікірлер
                                          ИМ
                                          Игорь МаксимовҚар. 22, 2024, 11:51 Т.Ж.
                                          Django - Оқулық 017. Теңшелген Django кіру беті Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
                                          Evgenii Legotckoi
                                          Evgenii LegotckoiҚаз. 31, 2024, 2:37 Т.Қ.
                                          Django - Сабақ 064. Python Markdown кеңейтімін қалай жазуға болады Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
                                          A
                                          ALO1ZEҚаз. 19, 2024, 8:19 Т.Ж.
                                          Qt Creator көмегімен fb3 файл оқу құралы Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
                                          ИМ
                                          Игорь МаксимовҚаз. 5, 2024, 7:51 Т.Ж.
                                          Django - Сабақ 064. Python Markdown кеңейтімін қалай жазуға болады Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
                                          d
                                          dblas5Шілде 5, 2024, 11:02 Т.Ж.
                                          QML - Сабақ 016. SQLite деректер қоры және онымен QML Qt-та жұмыс істеу Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
                                          Енді форумда талқылаңыз
                                          m
                                          moogoҚар. 22, 2024, 7:17 Т.Ж.
                                          Mosquito Spray System Effective Mosquito Systems for Backyard | Eco-Friendly Misting Control Device & Repellent Spray - Moogo ; Upgrade your backyard with our mosquito-repellent device! Our misters conce…
                                          Evgenii Legotckoi
                                          Evgenii LegotckoiМаусым 24, 2024, 3:11 Т.Қ.
                                          добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
                                          t
                                          tonypeachey1Қар. 15, 2024, 6:04 Т.Ж.
                                          google domain [url=https://google.com/]domain[/url] domain [http://www.example.com link title]
                                          NSProject
                                          NSProjectМаусым 4, 2022, 3:49 Т.Ж.
                                          Всё ещё разбираюсь с кешем. В следствии прочтения данной статьи. Я принял для себя решение сделать кеширование свойств менеджера модели LikeDislike. И так как установка evileg_core для меня не была возможна, ибо он писался…

                                          Бізді әлеуметтік желілерде бақылаңыз