© 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. Уже всю голову сломал как еще можно это сделать.

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

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

Добрый день!

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

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

Для Django рекомендую VDS-хостинг TIMEWEB

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

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

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

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

Для Django рекомендую VDS-хостинг TIMEWEB

Попытался переопределить 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() в базовом классе. Пробовали сделать, как в той статье?

Для Django рекомендую VDS-хостинг TIMEWEB

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

При использовании 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)
{
}
Исправьте это, а там скажете, какие ещё ошибки посыпятся. Но так конструктор будет правильный.

Для Django рекомендую VDS-хостинг TIMEWEB

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

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

Для Django рекомендую VDS-хостинг TIMEWEB

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

}

 

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

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

Для Django рекомендую VDS-хостинг TIMEWEB

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

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"));
}

Для Django рекомендую VDS-хостинг TIMEWEB

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

Еще один вопрос, можно ли использовать 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/ Используйте, пожалуйста, для вставки кода специальное диалоговое окно, это кнопочка на панели инструментов со значками <>

Для Django рекомендую VDS-хостинг TIMEWEB

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

Ответы

Только авторизованные пользователи могут отвечать на форуме.
Пожалуйста, Авторизуйтесь или Зарегистрируйтесь
24 сентября 2018 г. 17:42
edorofeeva

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

  • Результат 100баллов,
  • Очки рейтинга10
24 сентября 2018 г. 17:37
edorofeeva

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

  • Результат 66баллов,
  • Очки рейтинга-1
23 сентября 2018 г. 14:38
No Names

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

  • Результат 60баллов,
  • Очки рейтинга-1
Последние комментарии
25 сентября 2018 г. 15:24
pasagir

Qt/C++ - Урок 006. QSqlQueryModel - Таблицы в Qt с помощью SQL-запросов

Это запись метода которая работает параллельно с БД, данные из парсера поступают в БД и в наш метод одновременно
25 сентября 2018 г. 14:56
pasagir

Qt/C++ - Урок 006. QSqlQueryModel - Таблицы в Qt с помощью SQL-запросов

Как можно динамически отображать данные в таблице? На COM-порт непрерывно приходят данные, я их принимаю сохраняю в БД, а после остановка приема/передачи данные отображаются в таблице. В табли...
25 сентября 2018 г. 10:43
Евгений Легоцкой

Qt/C++ - Урок 017. QGraphicsScene или как работать с графикой в Qt

Прямо так не написано. Хотя соглашусь, что в качестве улучшения вызов данного метода здесь к месту.
25 сентября 2018 г. 10:37
reef425

Qt/C++ - Урок 017. QGraphicsScene или как работать с графикой в Qt

В статье написано, что таймер сработает один раз. Но это не так. Было бы хорошо добавить timer->setSingleShot(true); После инициализации таймера.
24 сентября 2018 г. 15:09
Евгений Легоцкой

Qt Linux - Урок 001. Автозапуск Qt приложения под Linux

А вот здесь у меня есть пример использования supervisor. https://evileg.com/ru/post/3/ Вся статья вам там не интересна, интересен только шаг с настройкой supervisor. Он получается ...
Сейчас обсуждают на форуме
25 сентября 2018 г. 15:57
Евгений_Канусовский@1981

Чтение файлов в python

Вот код: import sys from re import matchfrom vira import *from PyQt5 import QtCore, QtGui, QtWidgetsfrom PyQt5.QtWidgets import (QDialog, QFileDialog, QMessageBox, QLineEdit, QProgr...
25 сентября 2018 г. 13:51
DmitrySD

Трансляция видео с помощью VLC по RTP

Спасибо! Данная команда не дала результата. В итоге сделал трансляцию через ffmpeg. ffmpeg.exe -f gdigrab -framerate 30 -i desktop -vcodec libx264 -preset:v veryfast -b:v 4000k -f...
25 сентября 2018 г. 13:39
Arrow

Настройка Qt Creator для Android

Конечно отпишусь.
25 сентября 2018 г. 12:22
avovana

Автозапуск и авторестарт Qt Gui Application в Linux

Не получается... Решил пробовать скрипт, выполняемый при загрузке. В скрипте вечный цикл по старту программы.
Присоединяйтесь к нам в социальных сетях