Kollisionen mit QGraphicsItem darstellen



  • Hallo liebes Forum.
    Ich möchte zu Lernzwecken Bälle bzw. Kugeln in einer QGraphicScene kollidieren lassen. An den Wänden und untereinander. Leider werden die Kugeln nach einer Kollision an einer falschen stelle in die Scene gesetzt. D.h., wenn Sie eine Wand berührt prallt die Kugel dort nicht ab, sondern erscheint mittem im Feld oder auch außerhalb.

    Ich habe ball.h von QGraphicItem abgeleitet:

    #ifndef BALL_H
    #define BALL_H
    
    #include <QGraphicsItem>
    #include <QGraphicsScene>
    #include <QPainter>
    
    class Ball : public QGraphicsItem
    {
    public:
        Ball();
        QRectF boundingRect() const;
        QPainterPath shape() const;
        void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
    
    protected:
        void advance(int step);
    
    private:
        void collision();
        int xPos, yPos;
        qreal angle, speed;
    };
    
    #endif // BALL_H
    

    Und die ball.cpp:

    #include "ball.h"
    #include <QDebug>
    
    Ball::Ball()
    {
        angle = 45;
        speed = 5;
        setRotation(angle);
    }
    
    QRectF Ball::boundingRect() const
    {
        return QRectF(0, 0, 20, 20);
    }
    
    QPainterPath Ball::shape() const
    {
        QPainterPath path;
        path.addEllipse(boundingRect());
        return path;
    }
    
    void Ball::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
    {
        painter->setBrush(scene()->collidingItems(this).isEmpty() ? Qt::red : Qt::blue);
        painter->drawEllipse(boundingRect());
    }
    
    void Ball::advance(int step)
    {
        if (!step) {
            return;
        }
        if (!scene()->collidingItems(this).isEmpty()) {
            collision();
        }
        setPos(mapToScene(0, speed)); //Hier vermute ich den Fehler.
        qDebug() << "Angle: " << angle << "Position: " << pos();
    }
    
    void Ball::collision()
    {
        angle *= -1; //Um den richtigen Kollisionswinkel zu erhalten, den Winkel und Speed invertieren.
        speed *= -1;
        setRotation(angle);
    }
    

    Ich vermute den Fehler in Zeile 37. Ich bin mir nicht genau im Klaren wie mapToParent() oder mapToScene() etc. genau funktioniert.

    Für Ratschläge bin ich dankbar.

    Vielen Dank
    eddi0815



  • pro tip: schau in die Doku, wenn dir eine Funktion nicht klar ist. Auswendig weiß ich jetzt auch nicht, was die machen. Aber wenn du den Fehler schon soweit eingegrenzt hast, kannst ja einfach mal verschidene Möglichkeiten ausprobieren. Oder an der Stelle reindebuggen und die Werte anschauen. Und natürlich in die Doku schauen 😉


Anmelden zum Antworten