2010-12-15 6 views
0

複数の関数を同時に実行する際に問題があります。 具体的には、2つのクラス(MyRectとspace)があります。アイデアは宇宙侵略者に似ていますが、私は最初に立ち往生しました。クラスMyRectで私は2つの矩形::ボディ(船体)と弾(船弾)を定義しました。メインクラス空間では本体がMyRectオブジェクトとして出荷されます& & bullet rectangle.Alsoには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メソッドのループで弾を動かすことです。そのループは実行中ですが、プログラムの残りの部分はありません。なぜなら、単一スレッドは一度に1つのことしか実行できないからです。

解決策は、コードをリファクタリングして、何らかの更新メソッドを呼び出すたびに、1フレーム分のアニメーションで画面上のすべてのアニメーションを更新することです。基本的には、十分な状態、あなたがいる場所、動きの速さ、消えるまでの距離、各フレームごとに必要な量だけ移動できるようにする必要があります。

変更するもう1つの方法は、keyPressEventに宇宙船の状態を知らせるように宇宙船の状態を更新させて、通常のpaintEvent上を移動できるようにすることです。そのためには、QTimer

関連する問題