I have a pong game that I made 6 months ago when I was much worse at programming. The only thing is it flickers like CRAZY, which ruins it for me.
Here is some code which is involved in the drawing and clearing of the canvas, so may be behind the flickering:
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 );
Do you see anything that can be done to this to reduce flicker? Thanks.
EDIT
Check out how i was redrawing each image every interval by creating a NEW image in its draw method:
//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;
}
};
};
EDIT So i did this:
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);
};
Which makes it draw all items nicely except the paddles and ball which do not draw at all
It is hard to say where exactly it flickers without looking at the whole solution, but I would blame
setInterval()
. The way to go is to userequestAnimationFrame
technique described here: http://www.html5canvastutorials.com/advanced/html5-canvas-animation-stage/ I was able to achieve very smooth animations by using this code template:In general,
setInterval()
is fairly bad, usesetTimeout()
after each re-draw, since interval might come at the worst timing possible.Note, depending on required browser versions support, you might want to drop setTimeout alltogether, as requestAnimationFrame is universally supported by now.
Update A simple fix for the image loading without using extra tools within the code would be this, although it might run some animation cycles until all images will be loaded: