2012-07-06 3 views
1

Canvas를 사용하여 만든 게임에서 여러 개의 애니메이션을 만들려고합니다 (단순한 탁구 게임 임). 이것은 첫 번째 게임이며 나는 캔버스에 익숙하지 않지만 몇 가지 실험을하기 전에 캔버스의 작동 방식에 대해 잘 알고 있습니다.HTML5 Canvas 게임에서 여러 setInterval

먼저 게임 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)에, 나는 여기에서 문제는 내가 flag 변수를 재설정하고 있지 않다 될 수있는이 기능 라인 (151)에 전화 한 : 나는 여기에 코드를 붙여 있어요 하지만 그 일을 시도하고 이상한 결과를 얻었습니다. 당신은 밖으로 확인할 수 있습니다 here.

flag 변수를 재설정하면 무한한 입자의 문제가 해결되지만 이제 공이 패와 충돌 할 때만 애니메이션으로 나타나게됩니다. 그래서, 나는 이제 어떤 해결책이 없어요.

+0

이 질문은 여기에서 해결되었습니다. http://gamedev.stackexchange.com/questions/31764/multiple-setinterval-in-a-html5-canvas-game – Kushagra

답변

0

여기에 2 가지 문제점이 있습니다.

귀하의 주요 단기 문제는 setinterval의 사용이 잘못 되었기 때문에 첫 번째 매개 변수는 기능입니다. 당신이 간격을 시작하면

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

이 두 번째

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

해야, 그것은 영원히 실행 - 당신이에 대한 모든 충돌 이벤트를 원하지 않는다 이렇게 백그라운드 타이머를 실행해라.

업데이트 할 파티클 배열을 가지고 프레임 당 한 번이 목록을 업데이트하십시오. 새 입자를 만들 때 추가합니다.