изменить зону столкновения QGraphicPixmapItem [дубликат]

Интерфейс подобен контракту, в котором вы хотите, чтобы ваш класс реализации реализовал методы, написанные в контракте (интерфейс). Поскольку Java не предоставляет множественное наследование, программирование для интерфейса является хорошим способом достижения цели множественного наследования. Если у вас есть класс A, который уже расширяет какой-либо другой класс B, но вы хотите, чтобы класс A также следовал определенным рекомендациям или реализовывал определенный контракт, тогда вы можете сделать это путем программирования стратегии интерфейса.

3
задан dtech 11 August 2015 в 13:21
поделиться

2 ответа

QPainterPath QGraphicsItem::shape() const

Возвращает форму этого элемента как QPainterPath в локальных координатах. Форма используется для многих вещей, включая обнаружение столкновений, тесты ударов и для функций QGraphicsScene :: items ().

Реализация по умолчанию вызывает boundingRect (), чтобы вернуть простую прямоугольную форму, но подклассы могут переопределите эту функцию, чтобы вернуть более точную форму для непрямоугольных элементов.

Для обнаружения мелкого столкновения вам необходимо использовать:

bool QGraphicsItem::collidesWithItem(const QGraphicsItem * other, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape) const

, которые вы также можете переопределить, потому что проверка на столкновение между кругами быстрее, чем проверка painterpaths для пересечения.

Я сам этого не использовал, но, похоже, функция, которую вы используете, даст вам «грубое обнаружение», поэтому вы должны вручную проверить, действительно ли кто-то из них пересекается с мелкозернистым методом. Это экономит производительность, вы используете грубую проверку, чтобы изолировать потенциальных кандидатов на столкновение, а затем проверять только те элементы, используя более медленный метод. В вашем случае это не удобство, потому что тест столкновения с кругом будет таким же быстрым, если не быстрее, чем тест с ограничивающей коробкой, но именно так разработан Qt. В идеале вы должны будете передать свою собственную функцию обнаружения столкновений на collidingItems().

Также последнее, но не менее важное: после того, как вы получите список collidingItems, вы можете легко проверить наличие столкновений по кругу на месте, без использования shape() и collidesWithItem() ... Это фактически избавит вас от некоторого времени процессора от необходимости лишних виртуальных функций, плюс время для их повторного использования ...

Таким образом, вы можете использовать что-то например:

inline bool circCollide(QGraphicsItem * item, QList<QGraphicsItem *> items) {
    QPointF c1 = item->boundingRect().center();
    foreach (QGraphicsItem * t, items) {
        qreal distance = QLineF(c1, t->boundingRect().center()).length();
        qreal radii = (item->boundingRect().width() + t->boundingRect().width()) / 2;
        if ( distance <= radii ) return true; 
    }
    return false;
}

... и сделать это на месте:

if (circCollide(this, collidingItems())) ... we have a collision
6
ответ дан dtech 19 August 2018 в 02:44
поделиться
  • 1
    Хорошо, я изменил код следующим образом, но он все еще, кажется, сталкивается, когда это не должно. Дополнительные входы? void Ball :: paint (QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget) {// QRectF circ = boundingRect (); QBrush Brush (Qt :: серый); QPainterPath path0; path0.addPath (форма ()); // basic Collision Detection if (scene () - & gt; collidingItems (this) .isEmpty ()) painter- & gt; drawPath (shape ()); } также есть лучший способ вернуться к вам, чем это? – Tomathor 11 August 2015 в 15:03
  • 2
    Я делаю то, что не может добавить его жестким из-за ограничения характера. QPainterPath Ball :: shape () {QPainterPath path; path.addEllipse (boundingRect ()); Обратный путь; } void Ball :: paint – Tomathor 11 August 2015 в 15:19
  • 3
    @Tomathor см. Ответ edit – dtech 11 August 2015 в 15:32

Прочитайте документацию! Просто выкопайте документацию базового класса и его предков. См. QGraphicsItem :: содержит и shape

Еще одна вещь. Существует класс QGraphicsEllipseItem , поэтому большая часть необходимых вам функций должна быть там покрыта.

2
ответ дан Marek R 19 August 2018 в 02:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: