In my last post I described the advantages of incorporating animations into Windows applications and gave an overview of the platform support for creating them. In this post I will dive a little deeper into how to achieve some simple animation effects with a native windows application and the Animation Manager.
First, I needed an idea: something that would at least be mildly interesting and would also provide just enough complexity to illustrate some of the animation concepts and how to implement them. I remembered back to the days of the Atari 2600 and one of my favorite games, Human Cannonball. While the sample I ended up creating is far from a full featured game, it does cover what is necessary to simulate a projectile in motion.
First off, here is an outline of how to use the Animation Manager interfaces to accomplish the effect.
The sample can be downloaded here.
There are two primary classes implemented in the sample that perform the bulk of the work: CMainWindow and CProjectileAnimation.
Before describing the details of those two objects I’ll provide an overview of the sample’s design philosophy. First, I typically use a factory create pattern. This means that the objects I define generally have a static method to factory instances. In addition, I prefer to encapsulate the public methods of classes in well-defined contracts. For this I rely on IUnknown derived interfaces. The advantages of this approach are that it requires some up-front thinking about what the contractual requirements are between components and also it uses reference counting semantics, making it easy to manage the lifetime of objects (once the patterns are committed to memory). The disadvantage is that it can sometimes make code look a bit more complicated than it needs to, especially to someone unfamiliar with the pattern. Also, it requires some boilerplate style implementation of QI/AddRef/Release.
CMainWindow is a simple wrapper over a Win32 HWND. It is responsible for creating the device independent and device dependent animation objects. The device independent objects are created during initialization and kept for the lifetime of the application. These include:
In addition to the device independent objects, there are a few device dependent ones managed by CMainWindow. These are created on demand in the render pass (WM_PAINT) and discarded when requested by the animation manager. These include:
Launching a projectile is accomplished by pressing the spacebar. CMainWindow will launch a projectile along a fixed curve for every press. It maintains an array of active projectiles, which are all updated during the render pass. When a render pass is complete, CMainWindow relies on the animation manager to determine whether another render pass is necessary, and invalidates itself until the animation manager is done with the storyboards for all outstanding projectiles.
CMainWindow also registers itself as an IUIAnimationManagerEventHandler. This allows it to listen for state changes in the animation manager which kick off the invalidation/render cycle.
CProjectileAnimation is a fairly simple class that encapsulates the logic for creating the storyboard necessary to achieve the projectile effect. For initialization, it requires an IServiceProvider to probe for the various animation services it needs to create the storyboard. Those services are cached by CMainWindow (described above as the device independent objects), which implements IServiceProvider to service those requests.
CProjectileAnimation relies on an implementation of IUIAnimationInterpolator provided by CGravityInterpolator to create the horizontal component of the storyboard. This simple implementation uses a fixed initial velocity and acceleration. The interpolator is used by the animation system to provide incremental values of velocity and position based on time offset from the beginning of the storyboard.
While at first glance it may seem like a lot of work to achieve a fairly trivial animation, I encourage you to download and dissect this sample. I think once you take a look at how I’ve put things together it will be clear that it is really not all that complex, and that there is a lot of functionality and flexibility offered by the Animation Manager.
I am so thrilled that I bought this product. I have always wanted to learn Latin and but didn't have the time to sign up for a course. www.rosettastonecom.com I had tried others- for Italian and Japanese, which had been only minimally effective and quickly forgotten after the 4 months. I have been using this product for about 6 weeks and already I am almost finished and feel like I have really learned. I have accomplished such a basic grasp of the language and practicing is actually fun that I want to do it. I could not have done this without Rosetta Stone.