html画布动画闪烁

时间:2017-08-16 14:54:39

标签: javascript html5-canvas

我正在使用HTML5 Canvas和JavaScript创建这个简单的动画,我遇到了闪烁对象的问题。 在我问这个问题之前,我试图在互联网上找到解决方案,我发现的基本上都是:

  • 避免在每个新框架中加载新图像,对象
  • 使用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)

1 个答案:

答案 0 :(得分:3)

我看到蓝色障碍物出现了一些口吃 - 动画不顺畅。

基于原始requestAnimationFrame循环更改障碍物的x位置不一定会导致平滑操作,因为requestAnimationFrame只是请求浏览器重新绘制时间。

对requestAnimationFrame的调用之间的时间可能会有所不同,具体取决于动画所在设备的功率以及每帧的执行量。我们无法保证requestAnimationFrame会为您提供60 FPS。

解决方案是将对象位置的变化与它们的实际绘制分离,或者将它们计算出帧之间的经过时间,并根据该位置计算新位置以给出平滑的动画。

通常在我的画布动画中我只使用像GreenSock的动画平台(GSAP)https://greensock.com/get-started-js这样的库,它可以随时间动画任何数字属性,然后我只需要为绘图部分编写代码。

可以在您自己的requestAnimationFrame中计算基于时间的动画,但涉及到一些复杂性。这看起来像是一个很好的教程http://www.javascriptkit.com/javatutors/requestanimationframe.shtml

干杯, 道格