12oct2013

Flash Animation Pain

Apparently I’m still struggling like a base villain with Flash animation principles. Before I go into it I’ll note the solution and very basic principle I learned so I won’t need to plow through a goddamn epic to figure it out again when I’ve forgotten it:

Symbols (eg. MovieClips, etc) are containers for objects and other Symbols and stuff. Symbols can be animated/tweened, but base objects cannot. When you convert something to a symbol, then open it and try to animate it, you can’t because you’re inside a Symbol trying to animate an object; can’t be done. You need to convert that object into yet another Symbol in order to do the simple shit you had in mind.

It’s a bit like the homunculus problem – if your consciousness is like a little man inside your head telling you what to do, who’s inside his head? Etc etc, we get it, that’s great, we get it. In other words, it’s a mess.

I wanted a spinning ninja star. So I bumbled my way through the basic design and creation of a four-pointed star, heroically using not-object-drawing mode (unheroically forgetting what that’s called at the time of this writing) so I can easily combine the body and edge together and pull out the hole. I thought I was so clever. Took me a while to get the gradients thing figured out. Also ran into a problem where I drew the interior of the star then tried to modify the gradient (specifically: the shade of grey on one end by setting the brightness) but each time I set it Flash would set the value back to the original value but change the way the gradient looked anyway. Didn’t spend any time looking up why the F that would happen, since the answer would likely make me mad, like why can’t they just make something that works, or if that’s how it’s supposed to work at least make it look like that’s how it’s supposed to work, see I’m a little angry about it anyway, dammit Adobe can’t you hire at least one competent UI/UX person? But that’s not what I’m here to talk with you about today.

I got the basic thing down, converted it to a Symbol with a MovieClip base and wrote stub classes for it. Then I figured I would animate it, so I opened it up and tried to create a tween and was rewarded with this message:  ”The selected item cannot be tweened. You must convert this to a symbol in order to tween. Do you want to convert and create a tween?” With the options “OK” and “Cancel” which every two year old knows are not the proper set of answers to that question, goddamn it that’s fucking basic shit isn’t it? Sorry, sorry. A google search found the answer. In case that page goes away, here’s the relevant quotes:

… each movieclip is like a scene. They have their own timelines. Motion tweens can be applied to objects, not simple shapes. So when you enter inside first clip, you now select the shape inside it. Thats why it asks to make it a clip again

and

… you may only tween a symbol. … This is just how they designed flash. Flash only knows how to tween “symbols”.

… when you double click [a created] symbol in the library, you go “into” the symbol. Inside there you’re right back where you started, looking at the image you imported, which is not a symbol. Again, you cannot tween that image,  you must again convert it to a symbol before flash can tween it.

If you intend on making encapsulated animations like you seem to be, yes, you will end up with 2 symbols (or more). One that contains the overall animation, and another symbol for each asset inside it. You then toss your container symbol on the timeline as you did and you will see the animation, as you’ve found out.

Why are quotes in this wordpress theme so goddamn big?

Anyway there’s the solution: convert the interior stuff to a symbol, an instance of which is then inside your container symbol, then animate the interior. Which kinda sucks, cuz now there’ll be two ninja star symbols hanging around inside the library which is non-obvious and confusing.

It actually raises another more important question, which is somewhat related to object oriented design: where should that animation happen? Does the world/stage control the spinning of the ninja star, or is that inherent to the star itself? I think it’s a pretty easy answer in this case – having the stage spin the star is laughably cumbersome – but it could presage more difficult design questions in the future.

Time spent on this simple crap: about the length of the special edition of Ghost – Infestissumam (1 hour)

More Learning by Badly Doing

Here are the proper steps, learned the hard way, for animating a rotating object.

  1. Insert -> Motion Tween
  2. Set the tween to the proper length (I chose 40 frames, which in 60fps means 2/3s)
  3. Select the first frame of the tween, which means first deselecting the whole tween which is non-obviously selected and non-trivially deselected.
  4. In the properties panel, under rotation, choose a direction
  5. There should be a keyframe at the final frame of the animation. It should be identical to the first frame. This is bad; when we loop, there will be two identical frames in the sequence, which may not be noticeable but why not do things right?
  6. Select the next-to-last keyframe. Insert a keyframe there. The object should be almost fully rotated.
  7. Select the final keyframe. Right click -> Remove Frames. It should loop correctly

Note that the animation is now 39 frames long. So that’s maybe undesirable. But the solution isn’t to stretch the tween, because the distance from the final frame to the start point will then be slightly longer than every other frame, but to start out with 41 frames in the first place. Would have been nice to put that information in the proper steps, right?

Source for some of this info, though it may have annoying advertising.

After all that I have a spinning ninja star (which, aren’t they a pop invention and historically inaccurate? Whatever), although it’s all wrong, because the gradient, which is a simulated lighting effect, rotates along with the star, which is pretty ignorant. What’s the right solution? An overlay on top of the star? Bah, doesn’t matter now; it’s something to handle when we’re trying to do animation for real. Should probably have more of a hand-drawn look anyway.

Tidbits

Overriding functions: you must use the override keyword to override non-private functions. The declaration must match exactly; no, you won’t get any help from the compiler.

toString(): the documentation I found was outdated; you need to use the override keyword:

public override function toString():String { ... }

The ConstruKction of Shite

I just did something that’s… weird… man, and I don’t know how I feel about it. So PlayerCharacters and Enemies will need to be able to talk to the game engine (class Engine, which is the main class of whole #!), because they’ll need to interact with the world, Ninjas will throw stars, etc. So you could pass a reference in when you construct them, which is probably how I would structure it in Java, which works but like who wants to do all that work. So I tried having a static instance of Engine within Engine itself, and setting it at Engine construction time, then having a static function getEngine() that returns that static instance, or null before construction, but when is that ever going to happen, like, what could possibly go wrong. Kind of like singleton pattern, but… weird. And… it works. But it shouldn’t, right? Because shouldn’t you not be able to set your reference in the constructor, because it hasn’t been constructed yet? I would have done it the traditional way, by constructing it at first call to getEngine(), but that’s impossible because Flash instantiates it itself. So… weird, right? But it seems to work. It bears further investigation.

(1.5 hours later) Okay, I have some some answers, and my understanding is now Good Enough™ to go on. The first reason it was weirding me out is Java-based – you don’t want to go passing this around until the object is fully constructed. Could be Dangerous. In this case, I think that’s mostly okay, since all we’re doing is grabbing the reference, which in the limited testing I’ve done seems to check out. The other reason is it’s like a violation of OO. If you make things statically accessible, then really you’re just moving one step closer to procedural programming, and you’re only using classes as namespaces, so why bother with OO in the first place. Steve Yegge wrote a big attack on the Singleton pattern which makes this argument quite strongly. I don’t totally agree with it (which has the side effect of making me feel inadequate as a programmer incidentally – his rhetoric amounts to “if you disagree with me you have no chance of working for me; if you agree with me I’ll hire you”), as you just need one case where you’ll only ever need a single instance of an object (eg off the top of my head, a game engine) to make singleton a valid choice. So I think his case is overstated, and he seems to admit to that to in the classic “these statements not intended to be factual” parenthetical manner at the end of his post but what the fuck this isn’t supposed to be a review of a fucking Yegge blog post.

I found some answers on StackOverflow that indicated a static instance set in the constructor is valid, so that’s good enough for me for the moment. So it ain’t pretty, but it looks like it’ll work. Anyway, long story long, that’s how we’re doing it and it’s off to bed for me.

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>