2011-12-23 132 views
1

我試圖通過2D網格看到增強劑。我使用畫布編寫了一個可視化文件,每次我的代理人都會嘗試更新網格。我希望看到一個動畫,但直到代理完成所有這些動作,我纔看到什麼,我看到最後的狀態。如果我使用Google Chromes開發人員工具,那麼我可以看到各個步驟。我不認爲這是我的代碼快速運行的問題,因爲每一步都需要幾秒鐘。畫布元素不更新

我的實現如下,函數gridWorld()調用一次創建一個新對象,executeAction每次我想繪製時調用。如圖所示,我使用了ctx.save()ctx.restore(),但這只是試圖解決這個問題,似乎沒有任何區別。

感謝

var execute gridWorld = function(action) { 
    var canvas = document.getElementById("grid"); 
    this.ctx = canvas.getContext("2d"); 

    this.executeAction = function(action) { 
     this.ctx.save() 
     // ... Do reinforcement learning stuff 
     // For every cell in grid, do: 
     this.ctx.fillStyle = "rgb(244,0,0)" 
     this.ctx.fillRect(positionX, poisitonY, 10,10) 

     this.ctx.restore(); 
    } 
} 

回答

0

即使代碼需要很長的時間來執行,直到有代碼的實際斷裂瀏覽器將不會更新顯示。只要希望畫布更新,使用setTimeout()就會導致代碼執行中斷。

+0

謝謝,但我不確定如何使用此工作。在我的執行動作函數中,我用setTimeout替換了繪圖代碼(draw,15)。但是似乎draw函數在15毫秒後不會被調用,而是在主代碼執行完畢後(即與之前相同的問題),它們全部被調用。此外,繪圖代碼取決於代理的狀態,我怎麼能確定這個狀態如果被調用的順序不符? – zenna

+0

'[執行代碼繪製第一幀] [等待] [執行代碼繪製第二幀] [等待]等等......前一幀需要在繪製下一幀的函數上使用'setTimeout'。如果你的代碼不是通過框架設置的,那麼你需要改變它。 –

1

你不會看動畫,因爲它們發生得太快。你需要像下面的例子那樣分解它們。

Live Demo

如果我做了這樣的事情,例如

for(x = 0; x < 256; x++){ 
    player.x = x; 
    ctx.fillStyle = "#000"; 
    ctx.fillRect(0,0,256,256); 
    ctx.fillStyle = "#fff"; 
    ctx.fillRect(player.x,player.y,4,4); 
} 

你永遠只能看到球員在每一個函數被調用一次,董事會結束,你止跌」因爲循環運行速度太快,所以不會看到任何動畫。這就是爲什麼在我的現場演示中,我會以小幅增量進行調整,並且每15毫秒調用一次繪圖,以便您有機會真正看到畫布上放置了什麼。

+0

謝謝,但正如我在我的問題中所說,我不認爲這是我的代碼要快(因爲他們是重大的計算髮生在每個循環)。相反,我認爲主循環以某種方式阻止了屏幕的更新。我試圖用setTimeout解決這個問題,但沒有成功,正如我在上面的回答中所述。謝謝 – zenna

+0

@zenna爲了讓別人幫助你將不得不看到更多的代碼或例子。只是讓你知道,但是在循環中,你將永遠不會*看到畫布的更新,除非你打破它,在for循環中你將永遠不會*看到在for循環中發生的更新。 – Loktar