2012-08-13 4 views
15

여기 어쩌면 총 대뇌가 될지도 모릅니다. setInterval()의 구문은 매우 명확합니다. 매 x 밀리 초마다 작업하십시오. 가장 좋은 번역 방법은 requestAnimationFrame()입니다.HTML Canvas Interval 대 RequestAnimationFrame

나는 약 300 개의 객체를 가지고 있으며 각각은 일정한 간격 (매 8, 6, 2, 초마다)으로 애니메이션 시퀀스를 수행하기로되어 있습니까? 초당 최대 60 회 호출되는 requestAnimationFrame()을 사용하면 어떻게하면이 작업을 가장 잘 수행 할 수 있습니까? 아마도 쉬운 대답 일 것입니다. 단지 저의 삶에 대해 알아낼 수 없습니다.

답변

10

requestAnimationFrame은 꽤 낮은 수준이며, 이미 말한대로 작동합니다. 대략 60fps로 호출됩니다 (브라우저가 속도를 따라갈 수 있다고 가정). 따라서 일반적으로 게임 루프가있는 게임 엔진과 마찬가지로 그 위에 뭔가를 만들어야합니다. 내 게임 엔진에서

,이 (paraphased/단순화 여기)이 있습니다

window.requestAnimationFrame(this._doFrame); 

... 

_doFrame: function(timestamp) { 
    var delta = timestamp - (this._lastTimestamp || timestamp); 

    for(var i = 0, len = this.elements.length; i < len; ++i) { 
     this.elements[i].update(delta); 
    } 

    this._lastTimestamp = timestamp; 

    // I used underscore.js's 'bindAll' to make _doFrame always 
    // get called against my game engine object 
    window.requestAnimationFrame(this._doFrame); 
} 

그런 다음 내 게임 엔진의 각 요소는 자신을 업데이트하는 방법을 알고있다.
update: function(delta) { 
    this.elapsed += delta; 

    // has 8 seconds passed? 
    if(this.elapsed >= 8000) { 
      this.elapsed -= 8000; // reset the elapsed counter 
      this.doMyUpdate(); // whatever it should be 
    } 
} 

requestAnimationFrame 오히려 낮은 수준이다와 함께 캔버스 API, 그들은

있습니다 : 귀하의 경우 업데이트해야 각 요소에서 각 2, 6은 8 초 경과 된 시간을 추적하고 그에 따라 업데이트해야합니다 애니메이션 및 게임 엔진과 같은 것들을위한 빌딩 블록. 가능하다면 나는 cocos2d-js와 같은 기존의 것을 사용하려고합니다.

+0

감사합니다! 이게 내가 한 일이야. 조금 더 파헤 치면 다음과 같은 사실이 드러났습니다. https://gist.github.com/1002116 이것은 본질적으로 가지고있는 것입니다. 내 실수는 하나의 메인 루프와 각 객체의 루프 내에서 작동하도록하려는 것입니다. –

10

requestAnimationFrame을 특정 FPS에 강제로 적용하려면 한 번에 둘 다 사용할 수 있습니다!

var fps = 15; 
function draw() { 
    setTimeout(function() { 
     requestAnimationFrame(draw); 
     // Drawing code goes here 
    }, 1000/fps); 
} 

세상에서 가장 혼란 스럽지만 이상한 것은 아닙니다.

또한 마지막 호출 이후의 시간 차이에 따라 업데이트 할 필요가 개체를 그리는 순서가 아닌 FPS로하지만, 경과 시간 requestAnimationFrame을 사용할 수 있습니다

:

var time; 
function draw() { 
    requestAnimationFrame(draw); 
    var now = new Date().getTime(), 
     dt = now - (time || now); 

    time = now; 

    // Drawing code goes here... for example updating an 'x' position: 
    this.x += 10 * dt; // Increase 'x' by 10 units per millisecond 
} 

이 두 조각이 this fine article 출신을, 추가 세부 정보가 들어 있습니다.

그런데 좋은 질문입니다! 나는 이것에 대해서도 대답 한 것을 본 적이 없다고 생각한다. (그리고 나는 너무 많이 여기에있다.)

+0

도 고마워요! 두 번째 발췌 문장은 내가 본 후에 가깝다. 내가 첫 번째 답변에 대한 의견에 언급했듯이 이것은 내가 한 것처럼 보입니다. https://gist.github.com/1002116 –

+0

두 답변 모두 정말 좋았습니다 - 정말로 감사드립니다! –

+0

requestAnimationFrame은 인수로 타임 스탬프를 보냅니다. 내 경험으로 새로운 Date 객체를 만드는 것은 제공된 타임 스탬프를 사용하는 것보다 훨씬 비쌉니다. –