Tweening in Flex AS3 – sans MXML
On Sunday night I decided to start working a new game called Blaster Mines that is a direct descendant of my 4K Game Contest Entry, Mine-X 4K. I originally thought that I would limit this one to under 100K, or some other artificial limit, but I am going to instead give myself a deadline of April 30th to finish the game and move on. I will post my game design document (like I did for Agent Pixel 6502) when I get more ideas down on paper, but for now I decided to just make a title screen (I know, I am full of AMBITION). I played some MAME games over the weekend and noticed that many classic arcade games have very simple, effective title screens with one unique or special element. I decided to have my title graphic enter the screen from the top and tween drop in place and do a bounce of some sort (I did that with RetroBlaster, but on the timeline by hand). I know, this is nothing special and I figured that I would be done with it in 5 minutes. Actually, if I had decided to just can it in Flash CS3 and import the SWF into my project, it would have been complete in about 10 minutes, but you know me, I have to make things difficult…
fl.transitions package
Since I am developing completely in the Flex AS3 frame work (Flash Develop) sans the MXML (for now), I have some limited options available for pre-canned menu effects. I looked back at some CS3 projects I had done last year and in those I used the fl.transitions set of classes. So, my first attempt was to import those classes into my Flex AS3 project and start tweening away. No luck, as that package is part of the Flash distribution (noted the fl as the root node in the package structure, I guess). I was told that I could just import the package from my CS3 class path, but for some reason I couldn’t find that package on my Mac install of CS3. Honestly, I didn’t look very hard because while researching as I found the Flex mx.effects package and a wonderfully name library called “easing”.
mx.effects package
This one looked like a winner for a while. I read through the online docs (pretty slim on useful examples by the way) and hit a couple sites via Google searches, but found virtually no information on how to use this package effectively in plain old AS3 (without MXML). After making some attempts to put my embedded BitmapDataAsset png title screen inside a MXML Canvas via pure AS3 and getting a dreaded runtime exception about BitmapDataAsset not being a descendant of the UI Component class, it started to dawn on me that in some cases that much of the mx package is useful for pre-rendered MXML screens and not really useful for pure AS3 created screens. Now, this might not be the case, but after fiddling with getting a basic easing in tween for about 3 hours (with no results), I deleted the whole mess and looked elsewhere.
TweenLite and TweenMax|
I had heard about the lightweight GreenSock Tween libraries for a while now, but had not used them. I was impressed with the breadth of the feature set and the ease of use. Most methods are static class methods and the AS3 versions do their own Garbage Collection! AWESOME, I mean this guy knows his stuff. I downloaded TweenLite, played with it some and it was obvious to me that I had a winner on my hands. BUT, knowing me, it would never be that easy. Why? Because I am a classic tinkerer and I love to know how things work and to try and do them myself (probably a reason why I have not used the brilliant PixelBlitz engine much either). So, after searching the GreenSock site for some docs I found the license for the tween code…it referenced the Robert Penner tween code. Now, some of you might not know that Penner is my idol. I picked up his brilliant Programming Machromedia Flash-MX book on a whim 5 or 6 years ago and it COMPLETELY changed how I used AS1/Flash MX. He created his own event broadcaster classes, and his own tween library…A HA, that’s where I had seen a tween library in book form before (it’s like 6 degrees of separation, Jeff’s senility version). So dusted off my copy of his book and started work on my own simplified AS3 Tween library.
Penner’s Magic
I haven’t actually got very far on my library, having only played with some of Penner’s exponential slide ease-in code (He provides AS1/AS2 versions at that link and the chapter from his book) But, my logo graphic does fall from the top of the screen and eases into position as of this moment. I plan to add in a bounce effect, but for now, here is the code that I am using . By the way, use TweenLite if you want to just do a Tween, I am going to attempt to explain a little of Robert’s code and my version because it interests me, not because it is the fastest way to get this job done.
The idea is to move the object toward the final screen location and have it appear to gradually slow to a resting point.
The Psuedocode would look a little like this:
On Each Frame Tick |
I don’t think Robert even likes this equation as he goes in depth into many more easing equations, but I decided to give it a whirl and see what I came up with. The first few tries had my logo drop pretty much into place the first frame with in a couple seconds. That was because by frame 2, it had dropped 1/2 it’s height, and then by frame 2 it was 75% of the way there. I am running 40 FPS, so it was virtually invisible to the naked eye. It didn’t look very good. I read on and his next section of the book deals with time-based easing which makes the effect much better. So, did I move on too? Nope (well kind of actually), I wanted to make this one look at least somewhat cool (for fun?). I added in a frame delay so the easing movement doesn’t happen so quickly and then I changed the distance to be change by 1/8 every frame rather than 1/2. Also, I added in code so if the distance is less than 1, it just sets it at 1 and them moves on with my state machine.
public function transitionIn(updateType:int):void { //trace("transition in"); //need tween code here //start standard exponential slide if (!_transitionInStarted) { _titlescreenBitmapSource.x = 100; _titlescreenBitmapSource.y = -800; addChild(_titlescreenBitmapSource); _transitionInStarted = true; _transitionInCount = 0; }else { _transitionInCount++; if (_transitionInCount > _transitionInDelay) { _transitionInCount = 0; var distance:Number = 0 - _titlescreenBitmapSource.y; trace ("distance=" + distance); _titlescreenBitmapSource.y += distance / 8; if (distance < 1) { _titlescreenBitmapSource.y = 0; switchScreenState(STATE_SCREEN_MAINDISPLAY); _transitionInStarted = false; } } } } |
So, no rocket science here, but it does the trick temporarily until I can dig further into Robert’s code and see what magic he has up his sleeve. My plan is to add a simple tween library to my Generalized Flex Game Control page of classes. We’ll see if I get that far or just go back to TweenLite (like I should).