Kollisionserkennung mit QGraphicsPixmapItem. best practice

Alles rund um die Programmierung mit Qt
Antworten
Meho
Beiträge: 16
Registriert: 24. September 2013 16:41

Kollisionserkennung mit QGraphicsPixmapItem. best practice

Beitrag von Meho »

Hallo an alle,

ich bastel gerade an einem kleinen Spiel mit QT und habe gleich zwei Frage zu QGraphicsPixmapItem und Kollissionserkennung.

Ich habe eine Grafik für die Spielerfigur die aus optischen Gründen größer gestalltet ist. Teile dieser Grafik sollen andere überdecken ohne das dies als Kollision erkannt wird. Dazu wollte ich das BoundingRect anpassen.
Leider komm ich damit nicht zurande und ich bin mir gar nicht sicher, ob das der richtige Weg ist. In der Funktion
collidingItems() wird nach

Code: Alles auswählen

mode = Qt::IntersectsItemShape
gesucht. Also es wird der Schnittpunkt mit "Shape" gesucht.
Wie sollte ich vorgehen, wenn ich die "Hitbox" kleiner haben möchte als die "Textur"?

Dann habe ich noch das Problem, dass die zurückgegeben Liste, von Kollidierenden Objekten, aus QGraphicsItem besteht und ich so nicht auf die von mir programmierten funktionen zugreifen kann. (Meine ObjektKlasse: class Block: public QGraphicsPixmapItem)

Meine Bisherige Kollisionserkennung:

Code: Alles auswählen

QList<QGraphicsItem*> colliding_items = collidingItems();
    for(int i=0, n = colliding_items.size(); i<n; i++ ){

        // coliding with an block
        if(typeid(*(colliding_items[i])) == typeid(Block)){

       // Wie greife ich auf meine Objekte zu, kann man da was casten  :?: Wol eher nicht!?
       }
   }

Daher meine Frage:
Ist mein bisheriger Weg zielführend oder sollte ich lieber ein eigene Kollisionserkennung basteln?
Danke für euer Feedback!

Gruß Meho
RHBaum
Beiträge: 1436
Registriert: 17. Juni 2005 09:58

Re: Kollisionserkennung mit QGraphicsPixmapItem. best practi

Beitrag von RHBaum »

Ist mein bisheriger Weg zielführend oder sollte ich lieber ein eigene Kollisionserkennung basteln?
Bounding Rect zu manipulieren ist sicher technisch möglich, obs sinnvoll ist, keine Ahnung. Kenn mich mit dem 2D Qt graphic Zeugs ned so aus.
Aber schnell geschaut ....
QGraphicsView uses this to determine whether the item requires redrawing.
Wenn das manipulierst koennte es sein, das QT beim Darstellen und Neuzeichnen bissi durecheinander kommt.

Generell würd ich eher Kollision und Darstellung trennen ... also für dein abstractes Item ne Darstellung(QGraphicsXYZItem) und Daten für die Kollision vorhalten (Aggregation = Member)
So wirst viel flexibler .... du kannst recht fix Dinge unsichtbar machen (nicht darstellen) trotz eingeschalteter kollision .... sowie die Kollision abschalten ...
Dann habe ich noch das Problem, dass die zurückgegeben Liste, von Kollidierenden Objekten
Und bevor jetzt auf die idee mit casten kommst .....

Deine Klassen sollten generischer / abstrakter sein konkrete Darstellungsklassen.
So das du ne eigene Hirarchie bekommst neben der Hirarchie der Klassen fuer die Darstellung.
Logik und darstellung trennen !

Deine Eiegene Hirarchie hilft Dir dann auch ne sauberes Vererbungs-Design zu basteln .... der Unterscheid QGraphicsItem / QGraphicsPixmapItem ist ja ne reine Darstellungproblematik.
Und macht es dir sowieso schwer dich da mit ner eigenen abstraktion dazwischenzuklemmen.
Deshalb lieber eigene Hirarchie und die Graphicitems als member da halten bzw drauf verweisen ... dann musst auch nicht downcasten ...

Ciao ....
Meho
Beiträge: 16
Registriert: 24. September 2013 16:41

Re: Kollisionserkennung mit QGraphicsPixmapItem. best practi

Beitrag von Meho »

Hallo RHBaum,

danke für deine Antwort!
RHBaum hat geschrieben:
QGraphicsView uses this to determine whether the item requires redrawing.
Wenn das manipulierst koennte es sein, das QT beim Darstellen und Neuzeichnen bissi durecheinander kommt.
Das habe ich in der Doku auch gelesen und bin mir unsicher geworden. Ich wollte nicht lange fummeln für etwas was mir dann gar nichts nützt. Daher auch die Frage!

Danke für deine weiteren Hinweise ich weis zwar nicht, ob ich dich 100% verstanden habe, aber auf eine sauberer Trennung kann ich auf jeden Fall mehr achten.
[/quote]

Gruß Meho
Meho
Beiträge: 16
Registriert: 24. September 2013 16:41

Re: Kollisionserkennung mit QGraphicsPixmapItem. best practi

Beitrag von Meho »

Soo,
mal ein update von meiner Seite:

Wenn man den Bereich für die Kollisionserkennung (Hitbox) anpassen, aber nicht das Bild (Textur) in seinen Abmaßen veränder möchte, muss man die "Shape" des QGraphicsPixmapItem-Objektes anpassen.
Dazu implementiert man einfach die Funktion shape(). Diese gibt ein Objekt vom Typ QPainterPath zurück.
Dieses kann in der Funktion, nach Bedarf, angepasst werden, sogar in eine Kugel oder ein anders geformtes Polygon.

Beispiel:
in player.h:

Code: Alles auswählen

QPainterPath shape() const;
in player.cpp

Code: Alles auswählen

QPainterPath Player::shape() const
{
    QPainterPath path;
        // hier setze ich ein 64 breites und 65 hohes Viereck auf die x=3 und y=25 position des Bildes.
        path.addRect(3,25,64,65);
        return path;
}
Siehe auch QT Doku, unter QPainterPath QGraphicsItem::shape() const!
http://doc.qt.io/qt-5/qgraphicsitem.html#shape

Für die Kollisionserkennung werde ich sicherlich eine Liste mit Objekten nehmen und diese einzeln vergleichen. Dabei versuche ich die Funktion "collidesWithItem()" zu nutzen. Wenn das nicht geht melde ich mich nochmal.
Ansonsten wären meine Fragen beantwortet.

THX und Bye Meho
Antworten