Попробуйте , Неопьянение для свободного разместило управление исходным кодом SVN.
Учитывая сложное поведение анимации, которое вы ищете, я бы определенно ограничил безудержные обратные вызовы и тайм-ауты.
Я бы сделал что-то вроде этого:
// 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
}
];
Затем есть главная функция с контролем сценария анимации, например:
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);
}
С его помощью вы можете определить свою анимацию без беспорядка обратных вызовов, тайм-аутов и интервалов - и вместо этого сосредоточиться на сценарии анимации и элементарных блоках анимации.
Обратите внимание, что имена функций в сценарии анимации (например, first_figure_attacks
) являются ссылками на функции, которые сохраняются для последующего выполнения. Добавление параметров приведет к их вызову функций - их немедленному выполнению.
Вы можете использовать анонимные функции для добавления таких параметров:
var animation_script = [
{
at_time: 5 * 1000,
animation: function () { doAttack('left', '#char1', '#char2', 2000); }
}
];
или, может быть, более эстетично, вы можете обернуть doAttack, чтобы вернуть ссылку на функцию, например:
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)
}
];
Изучите комбинацию обратных вызовов и setTimeout. В основном после завершения одной атаки вы можете вызвать обратный вызов, который вызовет функцию, которая сработает через x миллисекунд. Но имейте в виду, что у вас есть только один поток для игры, поэтому время будет приблизительным, в зависимости от того, что еще разыгрывается.
Для более сложных последовательностей вам потребуется создать некоторую форму очереди событий (по сути, массив, который вы нажимаете и выталкиваете объекты событий). Объект события, который вы добавляете в массив, может определять событие, его тайм-аут, обратный вызов и тайм-аут обратного вызова. .
//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);
}