Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jQuery - Event/animation timeline

How would I go about telling certain events/animations to fire at a certain time?

I'm trying to make an animated fight scene between a few characters, so what would be the best way to script out their actions like who attacks next and so on?

Here is my sandbox where you can see the 2 left dummies move towards the dummy on the right: http://vilegaming.com/sandbox.x

How would I make the right dummy attack one of the dummies on the left after they attacked him?

I think what I'm really looking for is how would I setup a schedule of events based on time because not all attacks/animations will be right after each other.

like image 572
nkspartan Avatar asked Aug 26 '09 20:08

nkspartan


2 Answers

Given the complex animation behavior you're looking for, I would definately limit rampant callbacks and timeouts.

I would do something like this:

// first define the atomic animation effects

function first_figure_moves_towards_second_figure() {
    // animation calls
}

function first_figure_attacks() {
    // animation calls
}

function second_figure_blocks_attack() {
    // animation calls
}


var animation_script = [
    {
         at_time: 30 * 1000, // 30 seconds
         animation: first_figure_moves_towards_second_figure
    },
    {
         at_time: 31 * 1000, // 31 seconds
         animation: first_figure_attacks
    },
    {
         at_time: 32 * 1000, // 32 seconds
         animation: second_figure_blocks_attack
    }
];

Then have a master function with control of the animation script, like this:

var current_time = 0;

function animate_next() {
    var next = animation_script.shift(),
        time_between = next.at_time - current_time;
    setTimeout(function () {
        current_time = next.at_time;
        next.animation();
        animate_next();
    }, time_between);
}

With this you can define your animations free from a jumble of callbacks, timeouts and intervals - and instead focus on the animation script and the atomic animation building blocks.

Edit after comments:

Note that the names of the functions in the animation script (eg. first_figure_attacks) are function references - stored for later execution. Adding parameters will make them function calls - executing them immediately.

You can use anonymous functions to add parameters like this:

var animation_script = [
    {
        at_time: 5 * 1000,
        animation: function () { doAttack('left', '#char1', '#char2', 2000); }
    }
];

or maybe more aesthetically pleasing, you can wrap doAttack to return a function reference, like this:

function doAttack(side, c1x, c2x, speed) {
    // animation calls
}

function attackAnimation(side, c1x, c2x, speed) {
    return function () {
        doAttack(side, c1x, c2x, speed);
    };
}

var animation_script = [
    {
        at_time: 5 * 1000,
        animation: attackAnimation('left', '#char1', '#char2', 2000)
    }
];
like image 64
Magnar Avatar answered Oct 17 '22 16:10

Magnar


Look into a combination of callbacks and setTimeout. Basically after one attack has finished you can invoke a callback which would invoke a function to fire after x milliseconds.But keep in mind that you only have a single thread to play with therefore timings will be approximate depending on what else is playing out.

For more complex sequences you will need to build some form of event queue (essentially an array that you push and pop event objects) The event object you add to the array can define an event, its timeout, a callback and a callback timeout.

//invoke attack
attack( callbackEvent );

function attack( callbackFn ){

   //attack code

   //invoke callback
   callbackFn && callbackFn()
}

function callbackEvent(){

   //next attack in 5 seconds
   window.setTimeout( function(){
         attack(callbackEvent);
   }, 5000);

}
like image 45
redsquare Avatar answered Oct 17 '22 15:10

redsquare