segunda-feira, 11 de julho de 2011

Events and Animations

Hi Again !

This past week i've experimented with events and animations using the Qt Framework. Processing events with Qt is really simple and there isn't much to say as we will see. On the other hand there is a lot to say about the Qt's Animation Framework. It was confusing at first (the official example isn't exactly newbie friendly) but it is easy when you get used to it and it doesn't take long.


I was confused by the Qt nomenclature for events and event handlers. So here it is: SIGNAL = EVENT; SLOT = EVENT HANDLER.

This slot/signal is more (flexible) than plain callbacks and looks more like C# Delegates.

To associate the event to the event handler you use the connect method/function. There is a global function connect and a static method in the QObject class (inherited by almost all other classes).

This method/function receives the object that originated the event, the event you are tracking, the object that will handle it and which method is the event handler.

Here an example:

// Event + Event Handler
QObject::connect(lui, SIGNAL(accepted()), this, SLOT(init_game()));

lui is a dialog. the QDialog class emit and accepted event when you click the yes button. This snippet binds the init_game method of the current object (this) with the accepted signal (event) from lui.


There are 2 ways to work with animations. The very simple one and the complex yet powerful one. The major difference is that first one animates a single "entities" and is just a simple animation while the other can have multiple states (think of a state as a key frame), entities and animations going on.

The first snippet (1.1) creates an animation by using the QPropertyAnimation class which makes a property change smoothly. In this example it will change lui->pos() (A Qt Property is exactly like a C# property -- which c++ doesn't natively supports. Although it seems like (is) a function it is just an attribute with a getter/setter created for you.) from (0,0) to (200,200) in 750ms. The path that the component will follow was given by animPos->setEasingCurve(QEasingCurve::InOutQuart) (a 4th grade polynomial).

The following snippet (1.2) just add a second animation occurring simultaneously as the first. To do that we create another animation and add it to a QParallelAnimationGroup. This class will launch all Animations in paralalel and there is a QSequentialAnimationGroup if you want an animation in a sequential order.

Although last part(2) is a bit long it isn't complicated. Instead of setting the initial and final state like we did we will create a state machine and let it set the final state (and initial if you like. Animations that doesn't have an initial state we will use current value. State machines need an initial state).

I started it creating the state machine and 3 states and added 2 of those states (init and inPos) to the third (root). It isn't needed but shows that more complex state machines can be created. The following step describes how the component (lui) should be when each is reached.

After the animation group is completed we are ready to go. Instead of starting the animation directly i adopted the Qt tutorial suggestion to trigger it using an event. So QTimer was added to make serve as an animation countdown (100ms).

Next Topics

That was what i had in mind for this post but there is a few topics that i want to play with before actually coding a game. A few topics that might deserve to look at:
  1. Translations
  2. Scripting
  3. Fast UI Construction

Nenhum comentário:

Postar um comentário