qt - use of qpropretyanimation desirably -
in program have built qpropertyanimation
, add item , pos()
property. override keypressevent
. , using of keys consist of j, f, z item go forward
,go back
, jump
.
according gravity when item jump should fall. purpose call down
function. item once jump don't fall. have problem: when first press j , f (forward , back) item animate desirably next times item go forward , go of scene.
i mean should animated example 40 pixel animated 800 pixel.
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(); }
you should not use resize
, setfixedsize
on view
because use in setcentralwidget
, size managed layout. should use setfixedsize
on main window instead.
animations asynchonous. example, when call up(); down()
, these functions executed without 1-second pause. also, starting animation when it's started has no effect.
usually animations used in such way when know need object move in next second. it's complicated receive directives user , change object's trajectory when animation performing.
here example showing correct use of animations task. object can receive 1 directive (forward, or jump) per second, , according animation performed in next second.
header:
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(); };
source:
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(); }
Comments
Post a Comment