我正在使用 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)
最佳答案
我确实看到蓝色障碍物有些卡顿 - 动画不流畅。
基于原始 requestAnimationFrame 循环更改障碍物的 x 位置不一定会导致顺利操作,因为 requestAnimationFrame 只是请求浏览器在可以的情况下重新绘制。
调用 requestAnimationFrame 之间的时间可能会有所不同,具体取决于动画所在设备的功率以及每帧的处理量。无法保证 requestAnimationFrame 将为您提供 60 FPS。
解决方案是将对象位置的变化与它们的实际绘制分离,或者将帧之间耗时作为因素,并根据该时间计算新位置以提供平滑的动画。
通常在我的 Canvas 动画中,我只使用像 GreenSock 的动画平台 (GSAP) https://greensock.com/get-started-js 这样的库。它可以随着时间的推移对任何数字属性进行动画处理,然后我只需为绘图部分编写代码。
可以在您自己的 requestAnimationFrame 中计算基于时间的动画,尽管涉及一些复杂性。这看起来是一个很好的教程 http://www.javascriptkit.com/javatutors/requestanimationframe.shtml
干杯, bean bean
关于javascript - html Canvas 动画闪烁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45716911/