0

我在一次执行多个功能时遇到问题。具体来说,我有两个类(MyRect 和空间)。这个想法类似于太空入侵者,但我坚持在一开始。在 MyRect 类中,我定义了两个矩形 :: body(船体)和子弹(船子弹)。在主类空间中,将船创建为带有 body && 子弹矩形的 MyRect 新对象。还有 keyPress 事件的定义。问题是,当我发射子弹时,一切都停止了子弹的移动,直到循环 MyRect::fireBullet(int x, int y) 完成,我无法在此事件期间移动船。显然,我犯了一些基本错误,所以如果有人愿意澄清这一点。

这是示例代码::

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

我的矩形.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);

}
}

空间.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); 

};

空间.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;
    }

} 

}

主文件

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

感谢您的回答。

4

1 回答 1

1

你有一个架构问题。您正在做的是在其fireBullet方法中循环移动子弹。当该循环运行时,程序的其余部分不会运行,因为单个线程一次只能做一件事。

解决方案是重构代码,以便每次调用某种更新方法时屏幕上的所有内容都会更新一帧动画。基本上,你只需要保留足够的状态,你在哪里,你移动的速度,在消失之前你可以走多远,这样你就可以每帧​​移动所需的量。

您要更改的另一件事是让 keyPressEvent 更新宇宙飞船的状态以了解它应该向哪个方向移动,以便它可以在其常规paintEvent 上移动。为此,您可以使用QTimer

于 2010-12-15T16:11:24.470 回答