Политика конфиденциальностиКонтактыО сайтеОтзывыGitHubDonate
© EVILEG 2015-2018
Рекомендует хостинг
TIMEWEB
ЕС
29 мая 2018 г. 16: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. Уже всю голову сломал как еще можно это сделать.
Возврат 10% от суммы заказа отеля на Booking
Возврат 10% от суммы заказа отеля на Booking
Предлагаем ссылку с 10% возвратом от суммы заказа при бронировании отеля через Booking
20
ЕС

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

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

Добрый день!

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

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

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

новый класс 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
0

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

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

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


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

написал так

в 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()
{

}
пока что по крайней мере нет ошибок
0
ЕС

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

0

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

0
ЕС

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

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

0

тааак...

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

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

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

0
ЕС

есть 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
{

}

 

ну и сцена где я все добавляю, там у меня много классов которые я пока еще ни от кого не наследую
0

Вот так должно выглядеть наследование для класса 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 не нужно. Это неправильно.
0
ЕС

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

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)
^
0

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

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

0
ЕС

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

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

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

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

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

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

1

Комментарии

Только авторизованные пользователи могут публиковать комментарии.
Пожалуйста, авторизуйтесь или зарегистрируйтесь
IT
25 марта 2019 г. 17:32
Ilya The Engineer

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

  • Результат:5баллов,
  • Очки рейтинга-10
G
25 марта 2019 г. 8:34
GAG

C++ - Тест 002. Константы

  • Результат:41баллов,
  • Очки рейтинга-8
G
25 марта 2019 г. 8:25
GAG

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

  • Результат:66баллов,
  • Очки рейтинга-1
Последние комментарии
22 марта 2019 г. 12:32
Евгений Легоцкой

Ну может бибилотеки не те положили? У вас сборка для MinGW, а либы для MSVC.
ВН
22 марта 2019 г. 11:08
Волчонок Над-Пропастью

Из кьюта приложение не хочет запускаться, аварийно завершается, но каких-либо ошибок не выдаёт. Оно открывается, после нажатия "старт" зависает и завершается. Если не из кьюта запускать дебаг ...
21 марта 2019 г. 15:49
Евгений Легоцкой

серьезно? Эта ошибка 404 уже даже не относится к данному вопросу. В каких-то urls в вашем проекте. Вопросы, которые не относятся непосредственно к статье, задавайте, пожалуйста на...
АБ
21 марта 2019 г. 15:00
Артем Бел

а это где? сейчас ошибка в debag такая: Page not found (404)Request Method: GETRequest URL: http://amadowshop.site/accounts/profile/
21 марта 2019 г. 12:47
Евгений Легоцкой

не вижу здесь проблемы, поменяйте url для callback в приложения oauth в социальных сетях https://amadowshop.site/auth/verify/complete/facebook/
Сейчас обсуждают на форуме
U
25 марта 2019 г. 12:43
Unreal_man

Как сделать чтоб при клике на ячейку(ос андроид) ее сразу можно было редактировать?QGuiApplication::inputMethod()->show(); показывает клавиатуру, а вот что до этого прописать чтоб текст в ...
m
24 марта 2019 г. 10:36
monevich

Отвечу на свой же вопрос, может кому то это пригодится. Да, можно в функции main использовать такую конструкцию. При запуске программы из Qt передаю свой аргумент в параметрах командной строк...
22 марта 2019 г. 12:29
Дмитрий

Да, мьютекс добавил, но в том потоке, где сигнал вызывается.
ВН
22 марта 2019 г. 9:04
Волчонок Над-Пропастью

Да, на эту проблему! Зато у меня теперь новая, ругается на подключение QMediaPlayer, пишет, что не находит подобного файла или библиотеки. Пока не нашла как исправить, только вариант с переуст...
22 марта 2019 г. 8:58
Михаиллл

4) это , похоже, для создания видоизмененных страниц, для анимации. 3,5) добавить фвйл/qt/ui.qml
Присоединяйтесь к нам в социальных сетях

Для зарегистрированных пользователей на сайте присутствует минимальное количество рекламы