2017-08-16 115 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