Kollisionserkennung mit Qt



  • hi, weiß vielleicht einer wie ich mit qt und c++ tick benutze?
    ich muss dafür sorgen dass die objekte sich am rand des aplikationsfensters abstoßen und sich in eine andere richtung bewegen.

    hier der code:

    [cs]

    ///////// ausschnitt aus geometric.hpp

    class MoveableObject
    {
    public:
    virtual void move()=0;
    };

    class GeometricObject:public ToString, public Paintable, public MoveableObject
    {
    public:

    double width; //GObj weite
    double height; //GObj hoehe
    Vertex* corner; //Eckpunkt=GObj Vektor
    double dx, dy; //Fuer move()

    GeometricObject(double width, double height, Vertex* corner); //Konstruktor fuer GeometricObject
    virtual bool hasWithin(Vertex* p);
    virtual bool touches(GeometricObject* that);
    virtual double area()=0; /* Abstrakt /
    virtual std::string toString();
    virtual void paintMe(QPainter
    p)=0;
    virtual void move();
    virtual ~GeometricObject();
    };

    class Rectangle:public GeometricObject
    {
    public:

    Rectangle(double width, double height, Vertex* corner); //Konstruktor fuer Rectangle
    virtual double area();
    virtual void paintMe(QPainter* p);
    virtual std::string toString();
    virtual void move();
    virtual ~Rectangle(){}
    };

    void Rectangle::move()
    {
    if (this->corner->y<300)
    {
    //this->corner->x=this->corner->x+4;
    this->corner->y=this->corner->y+1;
    this->width=this->width-1;
    this->height=this->height-1;
    }
    if (this->corner->x>=300) // bei 300 pixel
    {
    this->corner->x=this->corner->x-4; // rectangle wieder zurück bewegen
    this->corner->y=this->corner->y-1;
    }
    };

    // BOARD.HPP

    #ifndef BOARD_HPP_
    #define BOARD_HPP_

    #include <QWidget>
    #include <QTimer>
    #include <vector>
    #include "geometric.hpp"
    #include "paintable.hpp"

    class Board:public QWidget
    {
    Q_OBJECT
    public:

    QTimer timer;
    Board(std::vector<GeometricObject*>& geos);
    std::vector<GeometricObject*>& geos;

    QSize minimumSizeHint();
    QSize sizeHint() ;
    void paintEvent(QPaintEvent* event);
    static int showPaintable(std::vector<GeometricObject*>& geos,int argc,char **argv);

    public slots:
    virtual void tick();
    };

    #endif /*BOARD_HPP_*/

    // BOARD.CPP

    #include "board.hpp"
    #include "paintable.hpp"
    #include "geometric.hpp"
    #include <QtGui>

    Board::Board(std::vector<GeometricObject*>& geos):QWidget(0),geos(geos)
    {
    setBackgroundRole(QPalette::Base);
    connect(&timer,SIGNAL(timeout()), this, SLOT(tick()));
    timer.start(25);
    }

    QSize Board::minimumSizeHint()
    {
    return QSize(100, 100);
    }

    QSize Board::sizeHint()
    {
    return QSize(400, 300);
    }

    template <typename IT>
    void paintIt(IT begin,IT end, QPainter& painter)
    {
    for (;begin!=end;begin++) (*begin)->paintMe(&painter);
    }

    template <typename IT>
    void moveIt(IT begin,IT end)
    {
    for (;begin!=end;begin++) (*begin)->move();
    }

    int Board::showPaintable (std::vector<GeometricObject*>& geos,int argc,char *argv)
    {
    QApplication application(argc,argv);
    Board
    b = new Board(geos);
    b->show();
    return application.exec();
    }

    void Board::paintEvent(QPaintEvent 😉
    {
    QPen pen;
    QPainter painter(this);
    painter.setPen(pen);
    paintIt(geos.begin(),geos.end(),painter) ;
    }

    void Board::tick()
    {
    moveIt(geos.begin(),geos.end());
    this->repaint();
    }

    // MAIN.cpp

    #include "board.hpp"
    #include "geometric.hpp"
    #include "paintable.hpp"
    #include <iostream>
    #include <QFont>
    #include <QWidget>
    #include <QtGui>
    #include <QApplication>

    int main(int argc, char **argv)
    {

    std::vector<GeometricObject*> geos;
    geos.push_back(new Rectangle(170, 150, new Vertex(100,0)));
    geos.push_back(new Star(80, 30, 12, new Vertex(100,0)));
    geos.push_back(new Oval(70, 50, new Vertex(200,0)));

    return Board::showPaintable(geos, argc, argv);;

    }

    der fehler scheint bei move() zu liegen.



  • also ich habs so gemacht (ich geh mal schwer davon aus das du auch beim panitz bist):

    void GeometricObject::move(){
    this->corner->x+=delta_x;
    this->corner->y+=delta_y;
    }

    und dann für die berührung an den rändern z.b. für den rechten rand:

    void GeometricObject::swapRight(){
    if(this->corner->x>500)
    delta_x=fabs(direction_x);
    }

    wobei fabs ne funktion aus <cmath> is, die den absoluten double-wert zurückgibt.
    also grad vorzeichen umdreht

    dann in der moveIt im Board:

    template <typename IT>
    void moveIt(IT begin,IT end){
    for(;begin!=end;begin++){
    (*begin)->move();
    (*begin)->swap();
    }
    }

    das problem warums nit funtioniert is weil ja immer wieder die move aufgerufen wird, wo die delta_y und delta_x immer wieder auf den ursprungswert zurückgesetzt wird

    naja hat dir jetz wahrscheinlich au net viel geholfen


Anmelden zum Antworten