Использование qpropretyanimation желательно
В этой программе я построил QPropertyanimation
и добавить к нему мой товар и pos()
имущество. Я переопределяю KeyPressEvent
, И с использованием ключей, состоящих из J, F, Z пункт идут forward
,идти back
а также jump
,
В зависимости от силы тяжести, когда предмет прыжок должен упасть. Для этого я звоню down
функция. Но предмет только один раз прыгает, не упадет. У меня также есть еще одна проблема: когда при первом нажатии кнопки j и f (вперед и назад) желательно анимировать, но в следующий раз элемент переместится вперед и вернется ко всей сцене.
Я имею в виду, что он должен быть анимирован, например, 40 пикселей, но он оживляет 800 пикселей.
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
QPoint start;
QPoint end;
~MainWindow();
private:
QGraphicsView* view;
QGraphicsScene* scene;
void keyPressEvent(QKeyEvent* k);
MyQgraphicsObject* m;
QPropertyAnimation* pr;
QElapsedTimer* timer;
int f;
int u;
int b;
void forward();
void up();
void back();
void down();
};
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
view=new QGraphicsView;
scene=new QGraphicsScene;
m=new MyQgraphicsObject;
pr=new QPropertyAnimation(m,"pos");
view->setScene(scene);
view->resize(800,800);
view->setFixedSize(800,800);
setCentralWidget(view);
scene->addItem(m);
start= QPoint(0,0);
f=30;
u=-30;
b=-30;
}
void MainWindow::keyPressEvent(QKeyEvent *k)
{
switch (k->key()) {
case Qt::Key_J: {
forward();
break;
}
case Qt::Key_Z: {
up();
down();
break;
}
case Qt::Key_F: {
back();
break;
}
default:
break;
}
}
void MainWindow::forward()
{
end.setX(f);
pr->setEndValue(end);
pr->setDuration(1000);
pr->setEasingCurve(QEasingCurve::Linear);
pr->start();
f+=40;
}
void MainWindow::up()
{
end.setY(u);
pr->setEndValue(end);
pr->setDuration(1000);
pr->setEasingCurve(QEasingCurve::Linear);
pr->start();
u-=30;
pr->pause();
}
void MainWindow::back()
{
end.setX(b);
pr->setEndValue(end);
pr->setDuration(1000);
pr->setEasingCurve(QEasingCurve::Linear);
pr->start();
b-=40;
}
void MainWindow::down()
{
u+=30;
end.setY(u);
pr->setEndValue(end);
pr->setDuration(1000);
pr->setEasingCurve(QEasingCurve::Linear);
pr->start();
}
1 ответ
Вы не должны использовать resize
а также setFixedSize
на view
потому что вы используете его в setCentralWidget
и его размер будет управляться макетом. Вы должны использовать setFixedSize
вместо основного окна.
Анимации асинхронные. Например, когда вы звоните up(); down()
эти функции будут выполняться без паузы в 1 секунду. Кроме того, запуск анимации, когда она уже запущена, не имеет никакого эффекта.
Обычно анимация используется таким образом, когда вы точно знаете, куда вам нужно переместить объект в следующую секунду. Сложно получать директивы от пользователя и изменять траекторию объекта, когда анимация уже выполняется.
Вот пример, показывающий правильное использование анимации для этой задачи. Объект может получать одну директиву (вперед, назад или прыжок) в секунду, и соответствующая анимация будет выполняться в следующую секунду.
Заголовок:
class MainWindow : public QMainWindow {
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
QGraphicsView* view;
QGraphicsScene* scene;
void keyPressEvent(QKeyEvent* k);
QGraphicsObject* object;
QPropertyAnimation* animation;
QPointF pos;
double speed;
enum Command {
command_none, command_jump, command_forward, command_back
};
Command next_command;
private slots:
void timeout();
};
Источник:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
view = new QGraphicsView;
scene = new QGraphicsScene;
object = scene->addWidget(new QPushButton("test"));
object->setPos(0, -object->boundingRect().height());
animation = new QPropertyAnimation(object,"pos");
animation->setDuration(1000);
view->setScene(scene);
setFixedSize(800,800);
scene->addRect(-500, -200, 1000, 200);
setCentralWidget(view);
scene->addItem(object);
next_command = command_none;
speed = 100;
QTimer* timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(timeout()));
timer->start(1000);
}
MainWindow::~MainWindow() {}
void MainWindow::keyPressEvent(QKeyEvent *k)
{
switch (k->key()) {
case Qt::Key_J: {
next_command = command_forward;
break;
}
case Qt::Key_Z: {
next_command = command_jump;
break;
}
case Qt::Key_F: {
next_command = command_back;
break;
}
default:
break;
}
}
void MainWindow::timeout() {
//fall
if (pos.y() < 0) {
pos.setY(pos.y() + speed);
if (pos.y() >= 0) {
pos.setY(0);
}
}
//action
switch(next_command) {
case command_forward:
pos.setX(pos.x() + speed);
break;
case command_back:
pos.setX(pos.x() - speed);
break;
case command_jump:
if (pos.y() == 0) {
pos.setY(pos.y() - speed);
}
break;
default:
break;
}
next_command = command_none;
animation->stop();
animation->setEndValue(pos - QPointF(0, object->boundingRect().height()));
animation->start();
}