# Multiple setInterval in a HTML5 Canvas game

I'm trying to achieve multiple animations in a game that I am creating using Canvas (it is a simple ping-pong game). This is my first game and I am new to canvas but have created a few experiments before so I have a good knowledge about how canvas work.

First, take a look at the game here. The problem is, when the ball hits the paddle, I want a burst of n particles at the point of contact but that doesn't came right. Even if I set the particles number to 1, they just keep coming from the point of contact and then hides automatically after some time.

Also, I want to have the burst on every collision but it occurs on first collision only. I am pasting the code here:

//Initialize canvas
var canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d"),
W = window.innerWidth,
H = window.innerHeight,
particles = [],
ball = {},
mouse = {},
points = 0,
fps = 60,
particlesCount = 50,
flag = 0,
particlePos = {};

//Set it's height and width to full screen
canvas.width = W;
canvas.height = H;

//Function to paint canvas
function paintCanvas() {
ctx.globalCompositeOperation = "source-over";
ctx.fillStyle = "black";
ctx.fillRect(0, 0, W, H);
}

//Height and width
this.h = 10;
this.w = 100;

this.x = W/2 - this.w/2;
this.y = (pos == "top") ? 0 : H - this.h;

}

//Push two paddles into the paddles array

//Setting up the parameters of ball
ball = {
x: 2,
y: 2,
r: 5,
c: "white",
vx: 4,
vy: 8,
draw: function() {
ctx.beginPath();
ctx.fillStyle = this.c;
ctx.arc(this.x, this.y, this.r, 0, Math.PI*2, false);
ctx.fill();
}
};

//Function for creating particles
function createParticles(x, y) {
this.x = x || 0;
this.y = y || 0;

this.vx = -1.5 + Math.random()*3;
this.vy = -1.5 + Math.random()*3;
}

//Draw everything on canvas
function draw() {
paintCanvas();
for(var i = 0; i < paddles.length; i++) {

ctx.fillStyle = "white";
ctx.fillRect(p.x, p.y, p.w, p.h);
}

ball.draw();
update();
}

//Mouse Position track
function trackPosition(e) {
mouse.x = e.pageX;
mouse.y = e.pageY;
}

//function to increase speed after every 5 points
function increaseSpd() {
if(points % 4 == 0) {
ball.vx += (ball.vx < 0) ? -1 : 1;
ball.vy += (ball.vy < 0) ? -2 : 2;
}
}

//function to update positions
function update() {

//Move the paddles on mouse move
if(mouse.x && mouse.y) {
for(var i = 1; i < paddles.length; i++) {
p.x = mouse.x - p.w/2;
}
}

//Move the ball
ball.x += ball.vx;
ball.y += ball.vy;

if(ball.y >= p1.y - p1.h) {
if(ball.x >= p1.x && ball.x <= (p1.x - 2) + (p1.w + 2)){
ball.vy = -ball.vy;
points++;
increaseSpd();

particlePos.x = ball.x,
particlePos.y = ball.y;
flag = 1;
}
}

else if(ball.y <= p2.y + 2*p2.h) {
if(ball.x >= p2.x && ball.x <= (p2.x - 2) + (p2.w + 2)){
ball.vy = -ball.vy;
points++;
increaseSpd();

particlePos.x = ball.x,
particlePos.y = ball.y;
flag = 1;
}
}

//Collide with walls
if(ball.x >= W || ball.x <= 0)
ball.vx = -ball.vx;

if(ball.y > H || ball.y < 0) {
clearInterval(int);
}

if(flag == 1) {
setInterval(emitParticles(particlePos.x, particlePos.y), 1000/fps);
}

}

function emitParticles(x, y) {

for(var k = 0; k < particlesCount; k++) {
particles.push(new createParticles(x, y));
}

counter = particles.length;

for(var j = 0; j < particles.length; j++) {
par = particles[j];

ctx.beginPath();
ctx.fillStyle = "white";
ctx.arc(par.x, par.y, par.radius, 0, Math.PI*2, false);
ctx.fill();

par.x += par.vx;
par.y += par.vy;

if(par.radius < 0) {
counter--;
if(counter < 0) particles = [];
}

}
}

var int = setInterval(draw, 1000/fps);


Now, my function for emitting particles is on line 156, and I have called this function on line 151. The problem here can be because of I am not resetting the flag variable but I tried doing that and got more weird results. You can check that out here.

By resetting the flag variable, the problem of infinite particles gets resolved but now they only animate and appear when the ball collides with the paddles. So, I am now out of any solution.

• Hey, you might wanna check out this engine I'm making: vidyadev.com/wiki/Irenic. It's still in development stage, though, but it would help you a lot. – jcora Jul 7 '12 at 0:17

This for next loop is italising the particle every frame, this needs to be outside the function

function emitParticles(x, y) {

for(var k = 0; k < particlesCount; k++) {
particles.push(new createParticles(x, y));
}


You need to wrap an if statement around this otherwise an exception error occurs

 if (par.radius > 0) {
ctx.arc(par.x, par.y, par.radius, 0, Math.PI*2, false);
}


You don't need do it like this.

if(flag == 1) {
setInterval(emitParticles(particlePos.x, particlePos.y), 1000/fps);
}


if(flag == 1) {
// initalise particles here, see first comment above
}
emitParticles();


Reason for this is that you will not time your interval with the main loop which is clearing the screen which prevents you from seeing the 'sparks'

Finally, probably harmless, but to be safe, change the comma to a semi-colon here

particlePos.x = ball.x,


You can see the above changes working here

I don't see why you are putting it into a separate animation. Why not just have a main game loop and 'inject' the code into the loop? Then you can have a ParticleManager class that can handle the magnitude of created particles, etc.

I think the fact that you are putting it in a separate animation is causing issues, but is not necessarily the problem.