2010-12-15 4 views
0

У меня проблема с выполнением нескольких функций сразу. Конкретный, у меня есть два класса (MyRect и пробел). Идея похожа на космических захватчиков, но я застрял в начале. В классе MyRect я определил два прямоугольника: тело (тело корабля) и пулю (пуля корабля). В основном пространстве класса создается корабль как новый объект MyRect с телом & & bullet rectangles.Also есть определение событий keyPress. Проблема в том, что когда я запускаю пулю, каждый тигр останавливает перемещение пули и до тех пор, пока не закончится цикл MyRect :: fireBullet (int x, int y), я не могу перемещать корабль во время этого события. Очевидно, что я делаю некоторые фундаментальные ошибки, поэтому, если кто-то готов разъяснить это.Как сделать параллельные события в C++ (конкретный Qt 4.6)

здесь приведен пример кода ::

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(); 
} 

Спасибо за ответы.

ответ

1

У вас есть архитектурная проблема. То, что вы делаете, - это перемещение пули в цикл в методе fireBullet. Пока этот цикл работает, остальная часть программы отсутствует, поскольку один поток может делать только одно за раз.

Решение состоит в том, чтобы реорганизовать ваш код, чтобы все на экране обновлялось с помощью анимации с одним фреймом каждый раз, когда вы вызываете какой-то метод обновления. В принципе, вам просто нужно сохранить достаточное состояние, где бы вы ни находились, насколько быстро вы двигаетесь, насколько далеко вы можете уйти, прежде чем исчезнуть, чтобы вы могли перемещаться на нужную сумму в каждом кадре.

Другое дело, что вы измените это, чтобы keyPressEvent обновил состояние космического корабля, чтобы узнать, как он должен двигаться, чтобы он мог перемещаться по его регулярному paintEvent. Для этого вы можете использовать QTimer