2015-06-24 123 views
0

鼓機測序假設我有以下代碼:涉及jQuery的

var blinker = function(element){ 
    if(stopped){ 
    return; 
    } else { 
    var sampleMapping = {'0': 'bass.wav', 
       '1': 'clap(2).wav', 
       '2': 'hihat(4).wav', 
       '3': 'tom(9).wav', 
       '4': 'hihat.wav', 
       '5': 'ArpEC1.wav'} 

    if (element.attr('value') === 'hit'){ 
    var sample = element.attr('id'); 
    instrument(sample); 
    } 
    element.fadeOut(200); 
    element.fadeIn(200); 
    } 
    } 

    var sequencerRun = function(){  
    var currentTime = 0; 
    var starting = 200; 
    var startTime = 0; 
    for(var k = 0; k < 16; k++){ 
     $(".instrument td .beat" + k).each(function(){ 
     setTimeout(blinker, currentTime,$(this)); 
     }) 
     currentTime += starting; 
    } 
    } 

    var timerId, setInt; 

    var runSeq = function(){ 
    setInt = setInterval(sequencerRun,3200); 
    } 

    $('.play').click(function(){ 
    stopped = false 
    sequencerRun(); 
    runSeq(); 
    }) 

    $('.stop').click(function(){ 
    clearInterval(setInt); 
    stopped = true; 
    }) 

我已經書面方式代碼,以開展我的鼓機音序器運行。可以看到我的應用程序的部署版本here

所以我所做的是使用tableHTML結構創建了一個矩陣。單擊播放時,SequencerRun被調用並運行一次。第一次運行後,setInterval會小心調用所有sequencerRun,直到用戶單擊停止。這些點擊事件偵聽器中有一個標誌,我將回到這裏。

該測序的核心是sequencerRun。對於矩陣中與節拍相對應的每一列,我正在計劃檢查該列,以查看是否有任何元素被選中用於未來播放。 sequencerRun只負責安排。更明確地說:

setTimeout(blinker,0, $(this)) is the same as check the first column right away 
setTimeout(blinker,0, $(this)) is the same as check the second column at time 200 
setTimeout(blinker,0, $(this)) is the same as check the third column at time 400 
.... 
setTimeout(blinker,0, $(this)) is the same as check the sixteenth column at time 3200 

現在什麼blinker做的是檢查是否停止,我創建了原來的標誌是真還是假。當點擊停止,這意味着沒有執行列檢查並且沒有任何操作。如果錯誤,則執行鼓機的正常過程。

現在是這個問題。如果您轉到部署的應用程序版本,該標記會引入一個令人討厭的錯誤。這個錯誤是,如果你按播放序列器啓動,但如果再次點擊播放另一個運行開始,這不是一個鼓機應該如何工作。 Essentialy我想看到的是如果我按下play,其他sequencerRun應該開始,如果我再按一次播放。另外如果你點擊播放,停止播放,我會得到相同的副作用。我認爲我的主要問題是sequencerRun安排將來會立即跳動,並且我的標記不準確。任何人有任何想法如何解決這個問題?

回答

1

只是使.play單擊處理程序中使用您的stopped變量:

$('.play').click(function(){ 
    if (stopped) { 
     stopped = false 
     sequencerRun(); 
     runSeq(); 
    } 
}); 

如果stopped標誌是假的,再次點擊播放什麼也不做。要在點擊停止時停止排隊的其他序列,您需要清除已設置的超時。首先,一定要保持一個手柄,他們每個人:

var sequenceTimeouts = []; 
var sequencerRun = function(){  
    var currentTime = 0; 
    var starting = 200; 
    var startTime = 0; 
    //reset array 
    sequenceTimeouts = []; 
    for(var k = 0; k < 16; k++){ 
     $(".instrument td .beat" + k).each(function(){ 
      //push each timeout into the array 
      sequenceTimeouts.push(setTimeout(blinker, currentTime,$(this))); 
     }) 
     currentTime += starting; 
    } 
} 

然後你的止損點擊處理程序中,明確每個那些:

$.each(sequenceTimeouts, function(i, timeout) { 
    clearTimeout(timeout); 
}); 
+0

真棒。這適用於點擊多次播放。更大的問題是點擊播放,停止播放。當您第三次點擊遊戲時,第一次運行仍在運行,因爲它已計劃進行檢查並且標誌已更改,所以最終得到2次運行。如何在停止點擊時終止第一個音序器運行? – theamateurdataanalyst

+0

@theamateurdataanalyst編輯我的答案,假設我已經正確理解你:) –

+0

你我的朋友是一個天才。 – theamateurdataanalyst