Squash and stretch is one of the fundamental principles of animation. Using it effectively will breathe new life into your characters allowing them to reach all the fluidity, excitement and bounciness you know they’re capable of. If you’re skeptical just check out this side by side comparison.
As you can see the one on the left is dry, boring and probably arthritic. Now as for the spritely little thing on the right, it would take a nuclear holocaust to crush this tenacious go-getter’s spirit.
Animating this effect by hand is great for many purposes but we’re making video games here. Sometimes we want characters to react to their environments in millions of different ways. Messing around with all those curves and keyframes could take years off a young animator’s life. Here comes procedural animation to the rescue, check it out:
Inspired by the goo balls of my favorite tower-building indie video game, stretchy objects give a whole new level of personality to physics simulations. The basic concept is:
- Find out how fast an object is going (its linear velocity)
- Use that information to scale up the y axis while scaling down the x axis. Hence the use of the term squash (scaling down) and stretch (scaling up). This way our sprites will keep the same volume.
var linearVelocity:b2Vec2 = _object.body.GetLinearVelocity(); var velX:Number = Math.abs(linearVelocity.x); var velY:Number = Math.abs(linearVelocity.y); var spriteTest:Sprite = _object.userData; //divide by intesity this means that the smaller the intensity //is the greater the squash effect var squash:Number = ((velY + velX) / _intensity); var xScale:Number = (squash / -2) + _originalScale; var yScale:Number = squash + _originalScale;
Now that we know the amount to scale our X and Y axis we need to point our sprite in the correct orientation. To find this orientation we need to get the direction our object is traveling in by finding the angle of the line connecting our X velocity and Y velocity.
var directionTraveling:Number = ((Math.atan2(linearVelocity.y, linearVelocity.x)) - (90 * (Math.PI / 180)));
To apply our newly calculated scale and direction correctly we will use a fancy transform matrix. Before your mind explodes I assure you it’s not as bad as it sounds. Here is the code:
//matrix transformation, basically we want to increase the sprites //Y scale while the sprite is pointed in the direction it is traveling _transformMatrix.identity(); _transformMatrix.rotate(_object.body.GetAngle()); //we do not want our objects to appear as if they //are pointed in the direction they are going that is //why we are rotating by a negative amount here _transformMatrix.rotate(directionTraveling * -1); _transformMatrix.scale(xScale, yScale); //and rotating back in a positive amount here after we apply our scaling _transformMatrix.rotate(directionTraveling); _transformMatrix.translate(spriteTest.x, spriteTest.y); spriteTest.transform.matrix = _transformMatrix;
Pretty sweet huh? You can download my StretchyObject class along with the rest of the code and the fla here
This class requires the use of QuickBox2D in order to work, so you have to follow the instructions here if you don’t already have it.
Very nice! I definitely a few uses for this. Thank you!
Thats really cool. I’m no expert but another – and perhaps more flexible – method is a soft body physics simulation. Or even a verlet constraint system.
I’ll be trying this for my 3D flash game. It’s in papervision, but the squashing/scaling effect should work just about the same. Great idea!
Sounds cool, I’d be interested in how this effect translates to 3D, post a link if you get something working.
Awesome, I was able to adapt your code for a flex-sdk compiled game I’m prototyping. Thanks for posting this!
I’m glad it was of use to you, if the games on the web post a link I’d love to see what you did with it.
hei…, really nice post here……, thx a lot for this nice tutorial…..,
Hey There. I discovered your blog using msn. That is a really neatly written article.
I’ll make sure to bookmark it and return to learn extra of your helpful information. Thank you for the post.
I will definitely return.
Hello blogger, i must say you have hi quality posts here.
Your website can go viral. You need initial traffic only.
How to get it? Search for; Mertiso’s tips go viral