2017-08-16 232 views
0

我正在使用HTML5 Canvas和JavaScript創建這個簡單的動畫,我遇到了閃爍對象的問題。 我試圖在互聯網上找到解決方案之前,我問過這個問題,所有我發現基本上是:html canvas動畫閃爍

  • 避免加載新的形象,對象在每個新幀
  • 使用requestAnimationFrame()

我想我已經完成了這一切,閃爍仍在發生。 (藍色矩形(障礙物)在我的情況

的作品是減少像素的方法,負責移動對象,這裏的數唯一的解決辦法:

obstacle.prototype.moveObstacle = function(){ 
this.x -=3 
} 

但動畫太慢。 有周圍沒有任何辦法

的jsfiddle:https://jsfiddle.net/wojmjaq6/

代碼:

var cnv = document.getElementById("gameField"); 
var ctx = cnv.getContext("2d"); 
var speedY = 1 
var obst1 = new obstacle(cnv.width + 50); 
var myBird = new bird(100, 1); 

function bird(x, y) { 
    this.x = x; 
    this.y = y; 
    this.gravity = 0.3 
    this.gravitySpeed = 0 
} 

bird.prototype.drawbird = function() { 
    ctx.fillStyle = "red" 
    ctx.fillRect(this.x, this.y, 20, 20); 
} 

bird.prototype.animate = function() { 
    this.gravitySpeed += this.gravity 
    this.y += speedY + this.gravitySpeed 
} 

function obstacle(x) { 
    this.x = x; 
    this.y = 0; 
    this.obstLen = Math.floor(Math.random() * 400) 
} 

obstacle.prototype.drawobstacle = function() { 
    ctx.fillStyle = "blue"; 
    ctx.fillRect(this.x, this.y, 15, this.obstLen) 
    ctx.fillRect(this.x, cnv.height, 15, -(cnv.height - this.obstLen - 100)) 
} 

obstacle.prototype.moveObstacle = function() { 
    this.x -= 3 
} 



function myFun() { 
    ctx.clearRect(0, 0, cnv.width, cnv.height); 
    myBird.animate(); 
    myBird.drawbird(); 
    obst1.moveObstacle(); 
    obst1.drawobstacle(); 

    if (obst1.x < 0) { 
    obst1 = new obstacle(cnv.width + 50); 
    } 
    window.requestAnimationFrame(myFun) 
}; 

function test() { 

    if (myBird.gravity > 0) { 
    myBird.gravity = -1 
    } else { 
    myBird.gravity = 0.3 
    } 
} 


document.getElementById("gameField").onmousedown = test 
document.getElementById("gameField").onmouseup = test 

window.requestAnimationFrame(myFun) 
+0

我沒有看到任何閃爍。 MacBook Air上的Safari和Chrome(2014年初)。 –

+0

同樣在這裏,看起來不錯 – Eric

+0

它可能只是一個「弱」電腦的問題?因爲我已經在Chrome,Firefox和IE上測試過它,並且它們都在閃爍。 – Pawel

回答

2

我確實看到一些與藍色障礙的口吃 - 動畫不平滑。

基於原始requestAnimationFrame循環更改障礙物的x位置不一定會導致流暢的操作,因爲requestAnimationFrame只是請求瀏覽器在可能時重新繪製。

調用requestAnimationFrame之間的時間可能會有所不同,具體取決於動畫所在設備的功率以及每幀需要執行多少操作。不能保證requestAnimationFrame會給你60 FPS。

解決方案是將對象位置的變化與實際繪製分離,或者將幀間流逝的時間因素分解,並基於此計算出新的位置以提供平滑的動畫。

通常在我的畫布動畫中,我只使用像GreenSock的動畫平臺(GSAP)https://greensock.com/get-started-js這樣的庫,它可以隨時間動畫化任何數值屬性,然後我只需要爲繪圖部分編寫代碼。

雖然涉及到一些複雜性,但可以在自己的requestAnimationFrame中計算基於時間的動畫。這看起來像它http://www.javascriptkit.com/javatutors/requestanimationframe.shtml

乾杯一個很好的教程, DOUG

+1

我同意這一點。如果使用requestAnimationFrame對動畫屬性進行動畫處理會導致垃圾收集引起震動,則不會考慮時間。我通常也會使用GSAP來處理這個問題。 – 2pha