2013-11-27 5 views
0

Я строю простую 2D-игру как попытку изучить холст. Символ может работать вокруг виртуальной среды, а переменная с именем yOffset контролирует смещение от верхней части экрана. У меня также есть глобальная переменная, называемая run, которая устанавливает true или false на основании того, работает ли символ (не показано здесь). Моя цель состоит в том, чтобы заставить bob вверх и вниз, пока он работает, и все приведенные ниже коды порождают множество setInterval() s. Правильно ли это сделать мой персонаж, или я должен делать это по-другому? Если да, то как?Как создать запущенную анимацию на холсте HTML5?

$(document).keydown(function(e) { 
     if(e.which == 97) { 
      running = true; 
      run(); 
     } else if(e.which == 100) { 
      running = true; 
      run(); 
     } else if(e.which == 119) { 
      running = true; 
      run(); 
     } else if(e.which == 115) { 
      running = true; 
      run(); 
     } 
     }); 

(да, если персонаж останавливается, бегущая переменная будет идти к ложным [не показана] - Я уже убедился, что работает переменная работает хорошо)

runTimer = 0; 
function run() { 
    if(runTimer == 0 && running) { 
     runTimer = 1; 
     yOffset = 80; 
     setTimeout(function() { 
      yOffset = 120; 
     }, 150); 
     setTimeout(function() { if (running) { runTimer = 0;run(); } }, 300); 
    } 
} 

Если вы нужна дополнительная информация, версия, в которой я сейчас работаю, доступна here.

ответ

1

Я думаю, вы можете упростить свой код, и на самом деле вы должны в весьма вероятном случае, когда вы хотите добавить некоторые другие символы.

Чтобы разрешить повторное использование анимации, лучше отделить анимацию (== различные шаги, которые должен пройти ваш персонаж) и состояние анимации (== на каком этапе ваш персонаж будет сейчас).

Я написал здесь некоторые элементы анимационной системы.
Итак, я определяю, что такое шаг анимации, целая анимация (которая до сих пор является только массивом шага анимации) и Animator (который содержит состояние, можно увидеть его как «читателя» анимации).

После того, как вы определили анимацию и аниматоры и запустили аниматоры, вам просто нужно вызвать тик (время) для перемещения анимации и offset(), чтобы прочитать смещение, что намного проще, чем борьба с пучок setIntervals.

http://jsfiddle.net/xWwFf/

// -------------------- 
function AnimationStep(duration, offset) { 
    this.duration = duration; 
    this.offset = offset; 
    // you might add : image index, rotation, .... 
} 

// -------------------- 
function Animation(animationSteps) { 
    this.steps = animationSteps; // Array of AnimationStep 
} 

// define a read-only length property 
Object.defineProperty(Animation.prototype, 'length', { 
    get: function() { 
     return this.steps.length 
    } 
}); 

// -------------------- 
function Animator() { 
    this.currentAnimation = null; 
    this.step = -1; 
    this.running = false; 
    this.remainingTime = 0; // remaining time in current step; 
} 

Animator.prototype.startAnim = function (newAnim, firstStep) { 
    this.currentAnimation = newAnim; 
    this.step = firstStep || 0; 
    this.remainingTime = newAnim.steps[this.step].duration; 
    this.running = true; 
} 

Animator.prototype.tick = function (dt) { 
    // do nothing if no animation ongoing. 
    if (!this.running) return; 
    this.remainingTime -= dt; 
    // 'eat' as many frames as required to have a >0 remaining time 
    while (this.remainingTime <= 0) { 
     this.step++; 
     if (this.step == this.currentAnimation.length) this.step = 0; 
     this.remainingTime += this.currentAnimation.steps[this.step].duration; 
    } 
}; 

Animator.prototype.offset = function() { 
    return this.currentAnimation.steps[this.step].offset; 
} 

// ______________________________ 
// example 

var bounceAnim = []; 
bounceAnim.push(new AnimationStep(200, 10)); 
bounceAnim.push(new AnimationStep(180, 20)); 
bounceAnim.push(new AnimationStep(150, 30)); 
bounceAnim.push(new AnimationStep(300, 40)); 
bounceAnim.push(new AnimationStep(320, 45)); 
bounceAnim.push(new AnimationStep(200, 40)); 
bounceAnim.push(new AnimationStep(120, 30)); 
bounceAnim.push(new AnimationStep(100, 20)); 

var anim1 = new Animation(bounceAnim); 

var animator1 = new Animator(); 
var animator2 = new Animator(); 

animator1.startAnim(anim1); 
animator2.startAnim(anim1, 3); 

// in action : 
var ctx = document.getElementById('cv').getContext('2d'); 

function drawScene() { 
    ctx.fillStyle = 'hsl(200,60%, 65%)'; 
    ctx.fillRect(0, 0, 600, 200); 
    ctx.fillStyle = 'hsl(90,60%,75%)'; 
    ctx.fillRect(0, 200, 600, 200); 
    ctx.fillStyle = 'hsl(10,60%,75%)'; 
    ctx.fillRect(200, 200 + animator1.offset(), 22, 22); 
    ctx.fillStyle = 'hsl(40,60%,75%)'; 
    ctx.fillRect(400, 200 + animator2.offset(), 22, 22); 
    animator1.tick(20); 
    animator2.tick(20); 
} 

setInterval(drawScene, 20); 
Смежные вопросы