HTML5 Canvas游戏中的多个setInterval

时间:2012-07-06 13:53:15

标签: javascript html5 canvas html5-canvas

我正在尝试在使用Canvas创建的游戏中实现多个动画(这是一个简单的乒乓球游戏)。这是我的第一个游戏,我是画布的新手,但之前已经创建了一些实验,因此我对画布的工作方式有了很好的了解。

首先,看一下游戏here。 问题是,当球击中球拍时,我想在接触点发出一阵n粒子,但这种情况并不正确。即使我将粒子数设置为1,它们也只是从接触点开始,然后在一段时间后自动隐藏。

另外,我想在每次碰撞时都有爆发,但它只在第一次碰撞时发生。我在这里粘贴代码:

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

canvas.addEventListener("mousemove", trackPosition, true);

//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);
}

//Create two paddles
function createPaddle(pos) {
    //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
paddles.push(new createPaddle("bottom"));
paddles.push(new createPaddle("top"));

//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.radius = 0.8;

    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++) {
        p = paddles[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 = paddles[i];
            p.x = mouse.x - p.w/2;
        }       
    }

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

    //Collision with paddles
    p1 = paddles[1];
    p2 = paddles[2];

    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;

        par.radius -= 0.02; 

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

    } 
}

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

现在,我的发射粒子的功能在第156行,我在第151行调用了这个函数。这里的问题可能是因为我没有重置flag变量但是我试过这样做了更奇怪的结果。你可以查看here

通过重置flag变量,无限粒子的问题得到解决,但现在它们只有当球与桨碰撞时才会出现动画并出现。所以,我现在没有任何解决方案。

1 个答案:

答案 0 :(得分:0)

我在这里可以看到2个问题。

你的主要短期问题是你使用setinterval是不正确的,它的第一个参数是一个函数。

&#13;
&#13;
setInterval(emitParticles(particlePos.x, particlePos.y), 1000/fps);
&#13;
&#13;
&#13;

应该是

&#13;
&#13;
setInterval(function() {
    emitParticles(particlePos.x, particlePos.y);
}, 1000/fps);
&#13;
&#13;
&#13;

其次,一旦你开始一个间隔它就会永远运行 - 你不希望每个碰撞事件都留下像这样运行的后台计时器。

要更新粒子数组,并按帧更新此列表一次。制作新粒子时,请将其他粒子推入其中。

相关问题