Политика конфиденциальностиКонтактыО сайтеОтзывы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. Уже всю голову сломал как еще можно это сделать.
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

Ответы

Только авторизованные пользователи могут отвечать на форуме.
Пожалуйста, авторизуйтесь или зарегистрируйтесь
ДД
13 декабря 2018 г. 16:24
Дмитрий Дубовик

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

  • Результат:66баллов,
  • Очки рейтинга-1
13 декабря 2018 г. 16:04
Metelev

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

  • Результат:47баллов,
  • Очки рейтинга-6
YC
12 декабря 2018 г. 18:49
Yaroslav Chernetskyi

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

  • Результат:31баллов,
  • Очки рейтинга-10
Последние комментарии
V
15 декабря 2018 г. 2:06
Vlad15007

Спасибо большое!Очень помогли!
11 декабря 2018 г. 21:01
Евгений Легоцкой

Не знаю, какой-там конкретно эффект и если честно не хочется fl studio ради того, чтобы посмотреть устанавливать, но из того, что увидел в интернете. Предполагаю, что то, что вы хотите с...
V
11 декабря 2018 г. 19:25
Vlad15007

Подскажите пожалуйста ( я новичок совсем)Можно ли организовать спрайт без этого окошка (как в fl studio fruity dance)?
11 декабря 2018 г. 15:06
Евгений Легоцкой

Что интересно, если написать так from <application_name>.<module_name> import <filename> ,то PyCharm сносит крышу, если разрабатываешь в рамках проекта приложение, ко...
11 декабря 2018 г. 14:52
Илья Чичак

Тут мне тоже есть что сказать=) Сами разрабы советуют импортировать следующим образом: from <application_name> import <module_name> Стоит избегать from . import &l...;
Сейчас обсуждают на форуме
ИМ
18 декабря 2018 г. 15:29
Игорь Максимов

Доброго времени суток. Имеется модель для видео-контента (Movie), а конкретно привязана сейчас к одной модели(Compilation). Появилась необходимость добавить еще одну модель (Category) и связа...
R
18 декабря 2018 г. 12:25
RED_Spider

именно так, проблема в кодировке, а именно в отсутствии шрифтов на сервере, для меня вопрос решился в CentOS 7yum install curl cabextract xorg-x11-font-utils fontconfig всем спасибо за ...
U
18 декабря 2018 г. 10:39
Unreal_man

А вот этот коннект здесь и вовсе не нужен connect(ui->ok3, &QPushButton::clicked, this, &Widget::addToText); А как же без него? ============================== ...
m
17 декабря 2018 г. 19:03
melnik10

Спасибо, попробую!
R
16 декабря 2018 г. 14:41
RED_Spider

перевірено все працює http://doc.qt.io/qt-5/appicon.html Setting the Application Icon on Windows First, create an ICO format bitmap file that contains the icon image. This ca...
Присоединяйтесь к нам в социальных сетях

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