2010-12-15 3 views
0

J'ai un problème avec l'exécution de plusieurs fonctions à la fois. Spécifique, j'ai deux classes (MyRect et espace). L'Idée est similaire aux envahisseurs de l'espace mais je suis restée au début. Dans la classe MyRect, j'ai défini deux rectangles: body (corps du bateau) et bullet (ship bullet). Dans l'espace de classe principal est créé navire comme objet MyRect new avec corps & & bullet rectangles.Il existe également une définition pour les événements keypress. Le problème est que quand je tire la balle, everythig arrête le déplacement excetp de la balle et jusqu'à ce que la boucle MyRect :: fireBullet (int x, int y) soit faite, je ne peux pas déplacer le bateau pendant cet événement. est prêt à clarifier cela.comment faire des événements parallèles en C++ (Qt 4.6 spécifique)

ici est un exemple de code ::

MyRect.h

#include <QWidget> 
#include <QRect> 
#include <QMainWindow> 
#include <QPainter> 
#include <QLabel> 
#include <ctime> 
#include <QtGui/QMainWindow> 

class space; 

class MyRect : public QObject { 

Q_OBJECT 

public: 
MyRect(int in_x, int in_y, int in_w, int in_h, QWidget* parent) 
    { 
     itsx = in_x; 
     itsy = in_y; 
     itsw = in_w; 
     itsh = in_h; 

     body = new QRect(itsx, itsy, itsw, itsh); 
     bullet = new QRect(itsx+41, itsy-15, itsw/8, itsh/2); 
     itsParent = parent; 
    } 
~MyRect() {} 

void move(int x ,int y); 

public slots: 
    void fireBullet(int x, int y); 

private: 
int itsx; 
int itsy; 
int itsw; 
int itsh; 
QWidget* itsParent; 
QRect* body; 
QRect* bullet; 
friend class space; 
}; 

MyRect.cpp

#include "MyRect.h" 

void wait(float seconds) 
{ 
    clock_t endwait; 
    endwait = clock() + seconds * CLOCKS_PER_SEC ; 
    while (clock() < endwait) {} 
} 

void MyRect::move(int x, int y) 
{ 
body->moveTo(x,y); 
bullet->moveTo(x+35, y-15); 


} 

void MyRect::fireBullet(int x, int y) 
{ 
y = y-15; 
for(int i=0 ; i<200 ; i++) 
{ 
    bullet->moveTo(x+41, y--); 
    itsParent->repaint(); 
    wait(0.001); 

} 
} 

space.h

#include <QKeyEvent> 
    #include <QMouseEvent> 
    #include "MyRect.h" 

class space : public QMainWindow 
{ 
Q_OBJECT 

public: 
    space(QWidget *parent = 0); 
    ~space(){} 


protected: 
    void paintEvent(QPaintEvent *event); 
    void keyPressEvent(QKeyEvent* event); 

private: 
private: 
int x; 
int y; 
int w; 
int h; 
MyRect* ship; 

signals: 
void fireBullet(int x, int y); 

}; 

space.cpp

#include "space.h" 
#include <QApplication> 



space::space(QWidget *parent) 
    : QMainWindow(parent) 
{ 
x = 170; 
y = 250; 
w = 90; 
h = 25; 

ship = new MyRect(x,y,w,h, this); 
connect(this, SIGNAL(fireBullet(int,int)), ship, SLOT(fireBullet(int,int))); 


} 


void space::paintEvent(QPaintEvent *event) 
{ 

    QPen pen(Qt::black, 2, Qt::SolidLine); 
    QColor hourColor(0, 255, 0); 


    QPainter painter(this); 

    painter.setBrush(hourColor); 
    painter.setPen(pen); 
    painter.drawRect(*(ship->body)); 
painter.drawRect(*(ship->bullet)); 



} 



void space::keyPressEvent(QKeyEvent* event) 
{ 

switch(event->key()) { 

    case Qt::Key_D : 
    { 
     x = x+10; 
     ship->move(x,y); 
     this->update(); 
     break; 
    } 
    case Qt::Key_A : 
    { 
     x = x-10; 
     ship->move(x,y); 
     this->update(); 
     break; 
    } 
    case Qt::Key_M : 
    { 
     emit fireBullet(x,y); 


     break; 
    } 

} 

}

main.cpp

#include "space.h" 
#include <QDesktopWidget> 
#include <QApplication> 



int main(int argc, char *argv[]) 
{ 
    QApplication app(argc, argv); 

    space window; 

    window.setWindowTitle("Lines"); 
    window.resize(500,500); 
    window.show(); 

    return app.exec(); 
} 

Merci pour les réponses.

Répondre

1

Vous avez un problème d'architecture. Ce que vous faites est de déplacer la balle dans une boucle dans sa méthode fireBullet. Tant que cette boucle est en cours d'exécution, le reste du programme ne l'est pas, car un seul thread ne peut faire qu'une seule chose à la fois.

La solution consiste à refactoriser votre code de sorte que tout ce qui est à l'écran soit mis à jour par une animation d'une image à chaque fois que vous appelez une méthode de mise à jour. Fondamentalement, vous avez juste besoin de conserver assez d'état, où vous êtes, à quelle vitesse vous vous déplacez, jusqu'où vous pouvez aller avant de disparaître, de sorte que vous pouvez vous déplacer de la quantité désirée chaque image. Une autre chose que vous changeriez est que keyPressEvent devrait mettre à jour l'état du vaisseau spatial pour savoir de quelle façon il devrait être déplacé, afin qu'il puisse se déplacer sur son paintEvent normal. Pour cela, vous pouvez utiliser un QTimer

Questions connexes