在这个程序中,我有一个继承QGraphicsObject的类。这个对象(马里奥)前进,回去跳。对于这份工作,我改变了马里奥的坐标。但我有一个问题。我希望它在与砖碰撞时停止。虽然我不使用QPropertyAnimation如何停止此项目。
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?
}
}
答案 0 :(得分:2)
我认为你应该修改你的算法。这里的主要问题是你在检查是否有砖之前移动马里奥。
你移动马里奥,你发出信号xChanged()或yChanged(),检查你是否在砖上?然后你必须回到以前的位置?
既然你知道放砖的地方,你可以做更多这样的事情:
void MainWindow::forward()
{
if(moveIsPossible(xDest, yDest))
{
_mario->setX(...);
[...]
}
在moveIsPossible(xDest,yDest)中,你放置了未来位置的元组(X,Y),如果你没有砖,没有墙,没有你想要的任何东西,它返回true,否则返回false。
看到你的代码,我只想提请你注意许多事情: