2010-12-15 71 views
0

我一次執行多個函數時遇到問題。 具體來說,我有兩個類(MyRect和空格)。這個想法和太空入侵者很相似,但是我堅持着開始。在類MyRect中,我定義了兩個矩形:: body(船體)和bullet(船舶項目符號)。主類空間創建爲MyRect新對象,主體爲& &項目符號矩形。此外還有keyPress事件的定義。 問題是,當我發射子彈時,everythig會停止移動子彈,直到循環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