Skip to content

Tripleplay Animator Guide

jsgmambo edited this page Aug 19, 2013 · 7 revisions

Understanding the Animator

The tripleplay.Animator should be used for scheduling all your animations. It’s thus a vital class to understand as every game likely has animations and other actions that need to be scheduled and reinventing the wheel is never a great idea. Its best to start with an example.

Having said that, there are currently limitations in how far the current implementation will take you. Read a discussion here of said limitations.

Understanding the examples

Lets start with AnimDemo. AnimDemo is a screen where you see a sphere going right then left at the top of the screen and other smaller spheres “dropping” at the bottom of the screen. You’ll notice that AnimDemo extends AnimScreen. AnimScreen contains a single instance of Animator. In general you’d only have one instance of Animator for your whole app. You would use this single instance for scheduling all your animations and time related activity. The Animator extends AnimBuilder. The documentation for AnimBuilder is misleading. Its used for registering parallel (not single) chains of animations.

??????? There is also a class called UIScreen for laying out widgets that do not contain animations. Then there is a class, UIAnimScreen that is used for Screens that contain both animations and ui-elements. Why does the structure of UIAnimScreen not extend UIScreen? Which means that tools for UIScreens are incompatible with tools for UIAnimScreens?Assume possible explanation for this is that most of the meat is kept in superclass: Screen? .???????

Below is a graphical representation of how the Animator instance is configured after AnimDemo.createIface() runs. Purple represents once off Actions that don’t require any amount of time to run. Blue represents Animations that have a duration. Gray is the user event. Yellow is an AnimGroup which allows animations to be added in parallel.

Animator Time

Note: It’s important to note that for the AnimGroups in the AnimDemo.java example, had an iterator been passed into the loop in the method dropBalls() , then none of the tweening would have happened in parallel. It’s due to the fact that each call in the loop starts with group. that the chaining happens in parallel.

Now lets look at what’s actually happening when you issue a set of commands. Consider the following code in AnimDemo.java:

anim.addAt(layer, circle, 50, 100).then().
  repeat(circle).tweenX(circle).to(width-150).in(1000).easeInOut().then().
  tweenX(circle).to(50).in(1000).easeInOut();
  • The addAt() registers an Animation.Action to take place when the animation starts. The action in question will add the circle ImageLayer to the GroupLayer layer and then the circle’s translation will be set to 50, 100 .
  • Note: The original animator is not returned by this function so understanding which object is returned and what you are stitching together is useful to keep track of. Instead, what is returned from addAt() is the Animation.Action on which we then call then() . Given that function chaining here is not on the original animator, what we will be doing from this point is stacking animations back to back that will wait for the previous to finish before the next begins.
  • then() creates a second temporary AnimBuilder (anim being the first) and returns it. Its function is merely to allow for a convenient way to chain new animations together. It will be garbage collected when the chain is complete.

Animator Path

We are assuming the last blue line is correct.

Notes on Animation

What is the purpose of Animation.apply()?. The purpose of apply is to update the contents of the particular animation for the current time.

It’s important to note that AnimBuilder and Animation are tightly coupled. AnimBuilder.addAt() returns an Animation.Action. What is an Action?. An Action is an Animation that when applied, does its action handler once and then finishes.

Why does apply(Animator, float) pass in an unused animator? We suspect this is because if you were to subclass Animation and needed to access the animator on apply(), this would then be overridable.

Additional Notes on Animator

There are three lists for animations:

_anims : Currently active animations

_nanims : Dormant animations yet to be initialized

_barriers (which have their own accumulation list)

(accum can point to _nanims list or _barriers)

Notes on Clock

If you want to use the Clock. The first thing you have to do is make sure it has the correct time. In order to do this, before you use the Clock in either the paint() or update(), you have to make sure its time is set correctly in either of those two methods by calling Clock.paint() in paint() and Clock.update() in update().

If you're not planning to simply pass on the Clock to something else and actually want to use it in your code, you do have to care about what information you can get back from the Clock using its fields or methods and why that information is useful.

How the Clock's internal fields get set, you really do not have to care about. The code in update() and paint() of Clock can be a little confusing. Remember, the Clock only sets the current time, but can query that time in different ways based on its constituent parts. The current time, as a float, is made up of the addition of two parts. The first part is the integer time in milliseconds since the start of the game to the last update(). The second part is the time difference in milliseconds, as a float, between the last update() and the current paint().