2016-12-06 17 views
0

我正在嘗試使河內問題的塔動畫。我目前的動畫格式依賴於移動每個木塊。一件作品的每個動作都需要動畫。我的解決問題的函數調用將移動相應片段的函數。如何在Javascript中按順序執行多個動畫,每個都有延遲

function hanoi(n, source, destination, buffer){ 
if (n == 1){ 
    var newBlock = source.stack.pop() 

    destination.stack.push(newBlock); 
    moveBlock(newBlock, destination.x - source.x + newBlock.x, 500 - 62 * (1 + destination.stack.length)); 
} else { 
    hanoi(n-1, source, buffer, destination); 

    var newBlock = source.stack.pop() 
    destination.stack.push(newBlock); 
    moveBlock(newBlock, destination.x - source.x + newBlock.x, 500 - 62 * (1 + destination.stack.length)); 

    hanoi(n-1, buffer, destination, source); 
} 
} 

moveBlock函數相當麻煩,因爲我有延遲動畫本身的問題。對於動畫動畫的三段,它會調用不同的功能。我這樣做是因爲我無法理解如何有效地在Javascript中加入一個驚人的延遲。

function moveBlock(block, x2, y2){ 
    var id = setInterval(moveUp, speed); 
    function moveUp() { 
     if (block.y <= 50){ 
      draw(); 
      clearInterval(id); 
      moveBlockOver(block, x2, y2); 
     } else { 
      block.y = block.y - 5; 
      draw(); 
     } 
    } 
} 
function moveBlockOver(block, x2, y2){ 
    var negative = -(block.x - x2)/(Math.abs(block.x - x2)); 
    var id = setInterval(moveOver, speed); 
    function moveOver() { 
     if (block.x == x2){ 
      draw(); 
      clearInterval(id); 
      moveBlockDown(block, x2, y2); 
     } else { 
      block.x = block.x + 5 * negative; 
      draw(); 
     } 
    } 
} 
function moveBlockDown(block, x2, y2){ 
    var id = setInterval(moveDown, speed); 
    function moveDown() { 
     if (block.y >= y2){ 
      draw(); 
      go = true; 
      clearInterval(id); 
     } else { 
      block.y = block.y + 5; 
      draw(); 
     } 
    } 
} 

我怎麼能更好地格式化我的代碼來解決這個問題?如果我可以在JavaScript代碼中加一個延遲,但顯然這是不可能的,那將會簡單得多。

+0

延遲並非不可能。 [setTimeout的()](https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout)。另外,我知道這不是答案,但我只想推薦[CreateJS](http://createjs.com)庫。 – Andrew

+0

什麼時候應該延遲發生? – guest271314

+0

每個塊的各個運動之間有一個延遲。在上升的過程中,每次移動5個像素之間的速度會有所延遲。在途中和途中一樣的事情。 – user1380248

回答

0

不要使用setTimeoutsetInterval使用​​

var playing = true; 
function update(timer) { // Main update loop 
    // your draw code 

    if(playing){ 
     requestAnimationFrame(update); // get next frame 
    } 
} 
requestAnimationFrame(update); // starts the animation 

做動畫創建返回true每個動畫的一些功能完成後

function anim1(){ 
    drawFoo(); // draw function 
    foo.x += 5; 
    return foo.x > 100; // returns true when foo.x > 100 
} 

function anim2(){ 
    drawFoo(); // draw function 
    foo.y += 5; 
    return foo.y > 100; // returns true when foo.y > 100 
} 

function anim3(){ 
    drawFoo(); // draw function 
    foo.x -= 5; 
    return foo.x < 0; // returns true when foo.x < 0 
} 

然後創建動畫功能的堆棧以便它們需要運行,並且var保存當前的動畫

// repeat 2 times 
var animStack = [anim1,anim2,anim3,anim1,anim2,anim3]; 
var currentAnim; 

然後在update循環

if(currentAnim === undefined){ // is there an animation 
    // no animation 
    if(animStack.length > 0){ // are there any animations on the stack 
     currentAnim = animStack.shift(); // yes get the first anim 
    }else{ 
     playing = false; // no animations to play so stop and exit 
     return; 
    } 
} 
if(currentAnim()){ // call the anim and check if returns true; 
    // animation ended so get the next animation function if there are any 
    if(animStack.length > 0){ 
     currentAnim = animStack.shift(); // get the next anim 
    }else{ 
     playing = false; // no more animations so stop 
     currentAnim = undefined; // ready for new animtion 
    } 
}   

的動畫功能將依次播放一個,直到完成。要添加新的動畫,只需將它們推到動態堆棧上並調用startAnimation函數

function startAnimation(){ // function restarts the anim safely 
    if(!playing){ // has the animation stopped 
     playing = true; // yes then restart 
     requestAnimationFrame(update)` 
    } 
    // if the animation is playing then no need to restart 
}