2014-07-02 43 views
0

在這個程序中,我有一個繼承QGraphicsObject的類。這個物體(馬里奧)前進,回去跳躍。爲了這個工作,我改變了馬里奧的座標。但我有一個問題。我希望它在與磚塊相撞時停止。雖然我不使用QPropertyAnimation如何停止這個項目。如何在不使用動畫的情況下停止QGraphicsObjcet的對象?

extern mario* _mario=new mario; 
MainWindow::MainWindow(QWidget *parent) : 
QMainWindow(parent) 
{ 
    size_of_plane_y=600; 
    size_of_plane_x=2000; 
    view=new QGraphicsView; 
    scene=new QGraphicsScene; 
    rec=new QGraphicsRectItem; 
    setCentralWidget(view); 
    view->setScene(scene); 
    scene->setSceneRect(0,0,size_of_plane_x,size_of_plane_y); 
    scene->addRect(scene->sceneRect()); 
    x_scene=0; 
    y_scene=0; 
    int tmpb=8*30+120+10*30+120; 
    int tmpb2=10*30+120+8*30+120; 
    int firstb=100; 
    int firstb2=100+8*30+120; 
    for(int i=0;i<3;i++) 
    { 
    _brick=new brick(0,firstb,size_of_plane_y-180); 
    scene->addItem(_brick); 
    _brick2=new brick2(0,firstb2,size_of_plane_y-180); 
    scene->addItem(_brick2); 
    firstb+=tmpb; 
    firstb2+=tmpb2; 
    } 
    timer1=new QTimer(this); 
    timer1->setInterval(500); 
    connect(timer1,SIGNAL(timeout()),this,SLOT(up())); 
}; 

void MainWindow::keyPressEvent(QKeyEvent *k) 
{ 
    switch (k->key()) 
    { 
    case Qt::Key_J: 
    { 
     forward(); 
     break; 
    } 
    case Qt::Key_Z: 
    { 
     timer1->start(); 
     break; 
    } 
    case Qt::Key_F: 
    { 
     back(); 
     break; 
    } 
    default: 
     break; 
    } 
} 

void MainWindow::forward() 
{ 
    if(ismovepossible(_mario->pos().x()+50,_mario->pos().y())==true) 
    { 
    _mario->setX(_mario->pos().x()+50); 
    scene->setSceneRect(x_scene+40,y_scene,size_of_plane_x,size_of_plane_y); 
    x_scene+=40; 
    }  
} 

void MainWindow::up() 
{ 
    static bool flag=0; 
    if(!flag) 
    { 
    if(ismovepossible(_mario->pos().x(),_mario->pos().y()-90)==true) 
    { 
     _mario->setY(_mario->pos().y()-90); 
     flag=1; 
    }  
    } 
    else 
    { 
    if(ismovepossible(_mario->pos().x(),_mario->pos().y()-90)==true) 
    { 
    _mario->setY(_mario->pos().y()+90); 
    timer1->stop(); 
    flag=0; 
    } 
    } 
} 

void MainWindow::back() 
{ 

    if(ismovepossible(_mario->pos().x()-50,_mario->pos().y())==true) 
    { 
    _mario->setX(_mario->pos().x()-50); 
    scene->setSceneRect(x_scene-50,y_scene,size_of_plane_x,size_of_plane_y); 
    x_scene-=50; 
    } 
} 
////////////////edit 
void MainWindow::projectile()//when user press Z and J simultaneity 
{ 
    static bool flag=0; 
    if(!flag) 
    { 
    if(ismovepossible(_mario->pos().x()+50,_mario->pos().y()-90)==true) 
    { 
    _mario->setY(_mario->pos().y()-90); 
    _mario->setX(_mario->pos().x()+50); 
    scene->setSceneRect(x_scene+50,y_scene,size_of_plane_x,size_of_plane_y); 
    x_scene-=50; 
    text->setPos(x_scene+200,10); 
    flag=1; 
    } 
    } 
    else 
    { 
    if(ismovepossible(_mario->pos().x(),_mario->pos().y()+90)==true) 
    { 
    _mario->setY(_mario->pos().y()+90); 
    timer2->stop(); 
    flag=0; 
    } 
    } 
} 
/////////////////////add function 
bool MainWindow::ismovepossible(int x, int y) 
{ 
    int dis_b=10*30+120+120; 
    int dis_b2=4*30+120+8*30+120;//8*30+120+120; 
    int firstb=100; 
    int endb=/*firstb*/100+8*30; 
    int firstb2=/*endb*/100+8*30+120; 
    int endb2=/*firstb2*/100+8*30+120+4*30; 
    int firstb3=/*endb2*/100+8*30+120+4*30+2*30; 
    int endb3=/*firstb3*/100+8*30+120+4*30+2*30+4*30; 
    int dis_b3=120+8*30+120+4*30+2*30; 
    if(y>size_of_plane_y-60 && y<=size_of_plane_y) 
    { 
    return false; 
    } 
    while(endb<size_of_plane_x) 
    { 
    if((y>size_of_plane_y-180 && y<size_of_plane_y-180+30)&&(x>firstb && x<endb)) 
    { 
    return false; 
    } 
    else 
    { 
    firstb+=dis_b; 
    endb+=firstb; 
    } 
    } 
    while(endb2<size_of_plane_x) 
    { 
    if((y>size_of_plane_y-180 && y<size_of_plane_y-180+30)&&(x>firstb2 && x<endb2)) 
    { 
     return false; 
    } 
    else 
    { 
    firstb2+=dis_b2; 
    endb2+=firstb2; 
    } 
    } 
    while(endb3<size_of_plane_x) 
    { 
    if((y>size_of_plane_y-180 && y<size_of_plane_y-180+30)&&(x>firstb3 && x<endb3)) 
    { 
     return false; 
    } 
    else 
    { 
    firstb3+=dis_b3; 
    endb3+=firstb3; 
    } 
    } 
    return true; 
} 
class brick : public QGraphicsObject 
{ 
    Q_OBJECT 
    public: 
    explicit brick(QGraphicsItem *parent = 0,int x=100,int y=600-180); 
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); 
    QRectF boundingRect()const; 
    public slots: 
    void collision(); 

    private: 
    int size_of_plane_y; 
    int start_x; 
    int start_y; 
    int size_brick; 
}; 

brick::brick(QGraphicsItem *parent, int x, int y) : QGraphicsObject(parent) 
{ 
    size_of_plane_y=600; 
    start_x=x; 
    start_y=y; 
    size_brick=30; 
    connect(_mario,SIGNAL(xChanged()),this,SLOT(collision())); 
    connect(_mario,SIGNAL(yChanged()),this,SLOT(collision())); 
} 

void brick::collision() 
{ 
    if(this->collidesWithItem(_mario)) 
    { 
    qDebug()<<"collision"; 
    //what write here for stopping super mario? 
    }  
} 

回答

2

我認爲你應該修改你的算法。這裏的主要問題是在檢查磚塊是否存在之前移動馬里奧。

你移動馬里奧,你發出信號xChanged()或yChanged(),檢查你是否在磚上?那麼你必須回到以前的位置?

既然你知道你把你​​的磚,你可以做更多的東西是這樣的:

void MainWindow::forward() 
{ 
    if(moveIsPossible(xDest, yDest)) 
    { 
     _mario->setX(...); 
     [...] 
} 

在moveIsPossible(xDest,yDest),你把未來位置的元組(X,Y)如果你沒有磚,沒有牆,沒有任何你想要的,它會返回true,否則返回false。

看到你的代碼,我只是想提醒你注意很多事情:

  • 嘗試使用const的變量把任何配置變量,如電路板尺寸,磚尺寸,等...
  • 嘗試爲特定功能創建特定的類。 forward(),back()等等。沒有在主窗口類中實現。
+0

如果我做你的建議解決了我的問題?我的意思是如果馬里奧站在磚頭?我的問題是如何在磚塊中站起來馬里奧。如果我使用動畫,我可以使用stop方法。但是現在我該怎麼做? – sarina

+0

我並沒有真正回答你的問題,但我認爲你正試圖以錯誤的方式解決問題。如果我明白了,你會移動馬里奧,然後檢查磚塊。我建議你在移動前檢查障礙物,這樣你就可以有不可能的情況,比如「磚塊上的馬里奧」。 – Martin

+0

我在我的問題中編輯我的代碼,但是當馬里奧移出他的範圍時,他會隱藏。哪裏是我的錯? – sarina

相關問題