the fake one
|
 |
Join Date: Mar 2003
Location: San Francisco
Posts: 10,718
|
|
func_tween and func_easing
If you've used jQuery for simple animations, you know it's easy to make simple tweens look nice by using the variety of available easing options.
Whenever I try to do some nice effect in Graal, I end up writing the tweening code from scratch for that particular case, which is ridiculous.
Tweening is pretty easy, but to make it look nice, you need some form of easing. Animations that start and stop abruptly look bad; it's usually better for there to be some kind of slow stop, fast start, or even bouncing  .
I ported the wonderful jQuery easing plugin (BSD license) to GScript.
I present to you: func_tween and func_easing.
func_tween is just a couple functions that makes it easy to change the property of an object over time. You can use any object; images, GUIs, players, NPCs, etc.
To use it, all you do is this:
PHP Code:
temp.callback = function() { player.chat = "Done!"; };
this.tween(Ball, "y", GraalControl.height - Ball.height, 40, temp.easing, temp.callback);
The parameters of tween are: - object - the object to tween
- property - the property to tween
- targetValue - the target value at the end of the animation
- frames - the number of frames the animation should last (20 frames per second)
- easing - the name of the easing function to use (optional, defaults to "swing")
- callback - a callback function, called when finished (optional)
You can use any easing available from the easing plugin, plus "linear" (normal, abrupt start and stop), and "swing" (the default, soft stop).
You can see all of the available easings, and try them out, on this site (probably requires a non-ancient browser).
Here's what they look like in game. The video is pretty choppy (sorry), but it looks very smooth in game.
My favorite is probably at 1:38.
Here's the two classes you'll need:
func_tween
PHP Code:
function onCreated() { this.join("func_easing"); }
//#CLIENTSIDE function tween(temp.obj, temp.property, temp.targetValue, temp.frames, temp.easing, temp.callback) { if (temp.easing == null) { // default easing temp.easing = "swing"; } temp.startValue = temp.obj.(@ temp.property) + 0; this.onTweenStep(temp.obj, temp.property, temp.startValue, temp.targetValue, temp.frames, temp.frames, temp.easing, temp.callback); }
function onTweenStep(temp.obj, temp.property, temp.startValue, temp.targetValue, temp.framesRemaining, temp.totalFrames, temp.easing, temp.callback) { if (temp.framesRemaining <= 0) { temp.obj.(@ temp.property) = temp.targetValue; if (temp.callback != null) { temp.callback(temp.obj); } return; } temp.n = (temp.totalFrames - temp.framesRemaining); temp.state = temp.n / temp.totalFrames; temp.pos = this.ease(temp.easing, temp.state, temp.n, 0, 1, temp.totalFrames); temp.obj.(@ temp.property) = temp.startValue + ((temp.targetValue - temp.startValue) * temp.pos); this.scheduleEvent(0.05, "onTweenStep", temp.obj, temp.property, temp.startValue, temp.targetValue, temp.framesRemaining - 1, temp.totalFrames, temp.easing, temp.callback); }
func_easing
PHP Code:
/* This is essentially a port of the jQuery easing plugin to GScript jQuery easing plugin: http://gsgd.co.uk/sandbox/jquery/easing/ */
//#CLIENTSIDE function easeInQuad(x, t, b, c, d) { return c * (t /= d) * t + b; };
function easeOutQuad(x, t, b, c, d) { return -c * (t /= d) * (t - 2) + b; };
function easeInOutQuad(x, t, b, c, d) { if ((t /= d / 2) < 1) return c / 2 * t * t + b; return -c / 2 * ((--t) * (t - 2) - 1) + b; };
function easeInCubic(x, t, b, c, d) { return c * (t /= d) * t * t + b; };
function easeOutCubic(x, t, b, c, d) { return c * ((t = t / d - 1) * t * t + 1) + b; };
function easeInOutCubic(x, t, b, c, d) { if ((t /= d / 2) < 1) return c / 2 * t * t * t + b; return c / 2 * ((t -= 2) * t * t + 2) + b; };
function easeInQuart(x, t, b, c, d) { return c * (t /= d) * t * t * t + b; };
function easeOutQuart(x, t, b, c, d) { return -c * ((t = t / d - 1) * t * t * t - 1) + b; };
function easeInOutQuart(x, t, b, c, d) { if ((t /= d / 2) < 1) return c / 2 * t * t * t * t + b; return -c / 2 * ((t -= 2) * t * t * t - 2) + b; };
function easeInQuint(x, t, b, c, d) { return c * (t /= d) * t * t * t * t + b; };
function easeOutQuint(x, t, b, c, d) { return c * ((t = t / d - 1) * t * t * t * t + 1) + b; };
function easeInOutQuint(x, t, b, c, d) { if ((t /= d / 2) < 1) return c / 2 * t * t * t * t * t + b; return c / 2 * ((t -= 2) * t * t * t * t + 2) + b; };
function easeInSine(x, t, b, c, d) { return -c * cos(t / d * (pi / 2)) + c + b; };
function easeOutSine(x, t, b, c, d) { return c * sin(t / d * (pi / 2)) + b; };
function easeInOutSine(x, t, b, c, d) { return -c / 2 * (cos(pi * t / d) - 1) + b; };
function easeInExpo(x, t, b, c, d) { return (t == 0) ? b : c * 2 ^ (10 * (t / d - 1)) + b; };
function easeOutExpo(x, t, b, c, d) { return (t == d) ? b + c : c * (- (2 ^ (-10 * t / d)) + 1) + b; };
function easeInOutExpo(x, t, b, c, d) { if (t == 0) return b; if (t == d) return b + c; if ((t /= d / 2) < 1) return c / 2 * 2 ^ (10 * (t - 1)) + b; return c / 2 * (- (2 ^ (-10 * --t)) + 2) + b; };
function easeInCirc(x, t, b, c, d) { return -c * ((1 - (t /= d) * t) ^ 0.5 - 1) + b; };
function easeOutCirc(x, t, b, c, d) { return c * (1 - (t = t / d - 1) * t) ^ 0.5 + b; };
function easeInOutCirc(x, t, b, c, d) { if ((t /= d / 2) < 1) return -c / 2 * ((1 - t * t) ^ 0.5 - 1) + b; return c / 2 * ((1 - (t -= 2) * t) ^ 0.5 + 1) + b; };
function easeInElastic(x, t, b, c, d) { s = 1.70158; p = 0; a = c; if (t == 0) return b; if ((t /= d) == 1) return b + c; if (!p) p = d * .3; if (a < abs(c)) { a = c; s = p / 4; } else s = p / (2 * pi) * arcsin(c / a); return -(a * 2 ^ (10 * (t -= 1)) * sin((t * d - s) * (2 * pi) / p)) + b; };
function easeOutElastic(x, t, b, c, d) { s = 1.70158; p = 0; a = c; if (t == 0) return b; if ((t /= d) == 1) return b + c; if (!p) p = d * .3; if (a < abs(c)) { a = c; s = p / 4; } else s = p / (2 * pi) * arcsin(c / a); return a * 2 ^ (-10 * t) * sin((t * d - s) * (2 * pi) / p) + c + b; };
function easeInOutElastic(x, t, b, c, d) { s = 1.70158; p = 0; a = c; if (t == 0) return b; if ((t /= d / 2) == 2) return b + c; if (!p) p = d * (.3 * 1.5); if (a < abs(c)) { a = c; s = p / 4; } else s = p / (2 * pi) * arcsin(c / a); if (t < 1) return -.5 * (a * 2 ^ (10 * (t -= 1)) * sin((t * d - s) * (2 * pi) / p)) + b; return a * 2 ^ (-10 * (t -= 1)) * sin((t * d - s) * (2 * pi) / p) * .5 + c + b; };
function easeInBack(x, t, b, c, d, s) { if (s.type() == (- 1)) s = 1.70158; return c * (t /= d) * t * ((s + 1) * t - s) + b; };
function easeOutBack(x, t, b, c, d, s) { if (s.type() == (- 1)) s = 1.70158; return c * ((t = t / d - 1) * t * ((s + 1) * t + s) + 1) + b; };
function easeInOutBack(x, t, b, c, d, s) { if (s.type() == (- 1)) s = 1.70158; if ((t /= d / 2) < 1) return c / 2 * (t * t * (((s *= (1.525)) + 1) * t - s)) + b; return c / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2) + b; };
function easeInBounce(x, t, b, c, d) { return c - this.easeOutBounce(x, d - t, 0, c, d) + b; };
function easeOutBounce(x, t, b, c, d) { if ((t /= d) < (1 / 2.75)) { return c * (7.5625 * t * t) + b; } else if (t < (2 / 2.75)) { return c * (7.5625 * (t -= (1.5 / 2.75)) * t + .75) + b; } else if (t < (2.5 / 2.75)) { return c * (7.5625 * (t -= (2.25 / 2.75)) * t + .9375) + b; } else { return c * (7.5625 * (t -= (2.625 / 2.75)) * t + .984375) + b; } };
function easeInOutBounce(x, t, b, c, d) { if (t < d / 2) return this.easeInBounce(x, t * 2, 0, c, d) * .5 + b; return this.easeOutBounce(x, t * 2 - d, 0, c, d) * .5 + c * .5 + b; };
// basic ones function easeLinear(x) { return x; }
function easeSwing(x) { return (- cos(x * pi) / 2) + 0.5; }
// helper function ease(temp.easing, x, t, b, c, d) { return this.(@ "ease" @ temp.easing)(x, t, b, c, d); }
Hopefully someone finds use out of this  . |
Last edited by cbk1994; 05-31-2012 at 09:28 AM..
Reason: links approved
|