我有一个乒乓球游戏,是 6 个月前制作的,当时我的编程能力很差。唯一的问题是它像疯狂一样闪烁,这对我来说毁了它。
这里是一些涉及 Canvas 绘制和清除的代码,因此可能是闪烁的原因:
canvas: document.getElementById( "canvas" ),
// Get our 2D context for drawing
ctx: canvas.getContext( "2d" ),
// Frames-per-second
FPS: 30,
draw: function() {
if (preGameContent.isStartScreen === false && endOfGame.isEndOfGame === false) {
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
this.Banana1.draw();
this.Banana2.draw();
this.Banana3.draw();
this.displayScore();
this.player1Paddle.draw();
this.player2Paddle.draw();
this.ball.draw();
}
}
update: function() {
if (preGameContent.isStartScreen === false && endOfGame.isEndOfGame === false) {
this.player1Paddle.updatePaddle();
this.player2Paddle.updatePaddle();
this.ball.updateBall();
if (this.ball.x < 0) {
if (this.is2PlayerGame === true) {
this.pointScored.startNextSet("player2");
this.setUp("right");
}
else {
this.pointScored.startNextSet("computer");
this.setUp("right");
}
}
if (this.ball.x + this.ball.width > this.canvas.width) {
gameController.pointScored.startNextSet("player1");
this.setUp("left");
}
}
}
tick: function() {
if (preGameContent.isStartScreen === false
&& endOfGame.isEndOfGame === false) {
gameController.draw();
gameController.update();
}
}
setInterval( gameController.tick, 1000 / gameController.FPS );
您认为可以采取什么措施来减少闪烁吗?谢谢。
编辑
看看我如何通过在绘制方法中创建一个新图像来每个时间间隔重绘每个图像:
//This class is to construct anything with an image
//vx and vy are for the velocity along the x and y axis
function Item(xStartPos, yStartPos, vx, vy, width, height, imgSrc) {
this.x = xStartPos;
this.y = yStartPos;
this.vx = vx;
this.vy = vy;
this.width = width;
this.height = height;
this.imgSrc = imgSrc;
//this function draws the image to the canvas
this.draw = function() {
var self = this;
var img = new Image();
img.src = self.imgSrc;
img.onload = function(){
gameController.ctx.drawImage(img, self.x, self.y);
};
};
//this function updates the position of the object on the canvas
this.update = function() {
// Divide velocity by gameController.FPS before adding it
// onto the position.
this.x += this.vx / gameController.FPS;
this.y += this.vy / gameController.FPS;
// wall collision detection
//stop the object from going through the top and bottom walls,
//but not the side walls, so the ball can go through them
if ( (this.y) < 0 ) {
this.y = 0;
}
if ( (this.y + this.height) > gameController.canvas.height) {
this.y = gameController.canvas.height - this.height;
}
};
};
编辑 所以我这样做了:
function Item(xStartPos, yStartPos, vx, vy, width, height, imgSrc) {
this.x = xStartPos;
this.y = yStartPos;
this.vx = vx;
this.vy = vy;
this.width = width;
this.height = height;
this.img = new Image();
this.imgSrc = imgSrc;
this.img.src = imgSrc;
//this.loaded = false;
//img.onload = function() { this.loaded = true; }
//this function draws the image to the canvas
this.draw = function() {
//if (this.loaded)
gameController.ctx.drawImage(this.img, this.x, this.y);
};
这使得它可以很好地绘制所有项目,除了根本不绘制的 Racket 和球
最佳答案
如果不查看整个解决方案,很难说它到底在哪里闪烁,但我会责怪 setInterval()
。解决方法是使用此处描述的 requestAnimationFrame
技术:http://www.html5canvastutorials.com/advanced/html5-canvas-animation-stage/
通过使用此代码模板,我能够实现非常流畅的动画:
window.requestAnimFrame = (function(callback) {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame ||
function(callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
function animate() {
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
// update
// clear
context.clearRect(0, 0, canvas.width, canvas.height);
// draw stuff
// request new frame
requestAnimFrame(function() {
animate();
});
}
animate();
一般来说,setInterval()
相当糟糕,每次重新绘制后都使用 setTimeout()
,因为间隔可能会在最坏的时机出现。
请注意,根据所需的浏览器版本支持,您可能希望完全删除 setTimeout,因为 requestAnimationFrame 目前已得到普遍支持。
更新 无需在代码中使用额外工具即可对图像加载进行简单修复,尽管它可能会运行一些动画循环,直到加载所有图像:
function Item(.. imgSrc) {
...
this.img = new Image();
this.imgSrc = imgSrc;
var self = this;
this.loaded = false;
img.onload = function() { self.loaded = true; }
//this function draws the image to the canvas
this.draw = function() {
if (this.loaded)
gameController.ctx.drawImage(this.img, this.x, this.y);
};
关于javascript - 绘制函数导致闪烁 - Javascript,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20533930/