2016-06-25 6 views
0

그래서 HTML과 자바 스크립트로 게임을 만들었습니다. 나는 일종의 플래 세이 버드 쉐어 게임을 만들고 싶었지만 키를 누르면 플레이어의 애니메이션이 정말 망가져 보입니다. 보세요 :HTML5 캔버스의 부드러운 애니메이션

body { 
 
    overflow: hidden; 
 
}
<!DOCTYPE html> 
 
<html> 
 
<head> 
 
    <link rel="stylesheet" href="Style.css"/> 
 
</head> 
 
<body onload="startgame()"> 
 
    <canvas id="canvas"></canvas> 
 
<script> 
 
    canvas.height=window.innerHeight; 
 
    canvas.width=window.innerWidth; 
 

 
function startgame() { 
 
    var c = document.getElementById("canvas"); 
 
    var ctx = c.getContext("2d"); 
 
    
 
    var x = 900; 
 
    var y = 300; 
 
    var w = 25; 
 
    var h = 500; 
 
    var yperson = 20; 
 
    var xperson = 200; 
 
    
 
    document.addEventListener("keydown", function() { 
 
     yperson -= 150; 
 
    }); 
 
    
 
    function updateperson() { 
 
     yperson = yperson; 
 
    } 
 
    
 
    setInterval(createobject, 10); 
 
    function createobject() { 
 
     ctx.clearRect(0, 0, canvas.width, canvas.height); 
 
     
 
     x -= 1; 
 
     yperson += 0.5; 
 
     yperson *= 1.003; 
 
     
 
     ctx.fillStyle = "#009999"; 
 
     ctx.fillRect(x,y,w,h); 
 
     
 
     ctx.fillStyle = "black"; 
 
     ctx.fillRect(xperson,yperson,30,30); 
 
     
 
     if (x <= 50) { 
 
      if (yperson < 280 && xperson === x-30) { 
 
       x -= 1; 
 
      } else if (yperson > 280){ 
 
       x += 1; 
 
      } 
 
     } 
 
     
 
     
 
    } 
 
} 
 
</script> 
 
</body> 
 
</html>

내가 그것을 부드러운 애니메이션 업을 갖고 싶어. 어떤 사람들은 requestanimationframe으로 끝내야한다고 말하는 것을 보았지만 그것을 사용하는 방법을 모른다.

미리 감사드립니다.

// DEFINE OBJECTS UP HERE 

var update = function(modifier) { 
    // update all the object properties 
    // multiply values that depend on time (like speeds) by modifier 
}; 
var render = function() { 
    // draw everything 
}; 
var main = function() { 
    var now = Date.now(); 
    var change = now - then; 

    update(change/1000); // update based on frame rate, change in milliseconds/second 
    render(); 
    then = now; 
    requestAnimationFrame(main); 
}; 

// ADD EVENT LISTENERS HERE 

requestAnimationFrame = window.requestAnimationFrame 
       || window.webkitRequestAnimationFrame 
       || window.msRequestAnimationFrame 
       || window.mozRequestAnimationFrame; 
// ABOVE CODE GIVES CROSS-BROWSER COMPATIBILITY 

    var then = Date.now(); 
    main(); 

requestAnimationFrame 프레임 속도에 따라 루프를 실행하는 브라우저를 알려줍니다

+0

나에게 잘 보이지만 예'requestAnimationFrame'은 디스플레이를 업데이트하는 방법 때문에 약간 부드럽게 보일 것입니다. –

+0

알아. @SpencerWieczorek하지만 키를 누르면 사람이 애니메이션없이 빠르게 올라갑니다. –

+0

위치를 150 픽셀만큼 위로 이동하는 것입니다. 애니메이션을 원하면 위쪽으로 힘을 가하고 상향으로 직접 변환하지 않으려합니다. 이 경우 중간에 애니메이션이 없습니다. –

답변

0

requestAnimationFrame

MDN window.requestAnimationFrame를 참조하십시오.

// A flag to indicate that the animation is over 
var stop = false; // when true the animation will stop 

// define main loop update 
// the callback that is the main loop 
// the browser treats this function as special in terms of display items including 
// the canvas, and all DOM items. 
// It will ensure that any changes you make to the page are synced to the display 
function update(time){ // time is the time since load in millisecond 1/1000th 
         // time is high precision and gives the time down to 
         // microseconds (1/1,000,000) as fraction 0.001 is one microsecond 

    // you can stop the animation by simply not calling the request 
    // so if the flag stop is true stop the animation 
    if(!stop){ 
     requestAnimationFrame(update); // request the next frame 
    } 
} 

requestAnimationFrame(update); // request the very first frame 
// or you can start it with a direct call. But you will have to add the time 
update(0); 

업데이트 기능은 초당 최대 60 회 호출됩니다. 코드가 계속 유지되지 않으면 (즉, 렌더링하는 데 1/60 초 이상 걸리면) 업데이트 기능은 다음 프레임을 기다리며 프레임 속도를 1/30로 효과적으로 줄입니다. 렌더가 느린 경우 프레임 건너 뛰기가 계속됩니다.

프레임 속도를 제어 할 수 없으므로 다음을 수행하여 필요한 프레임 속도로 애니메이션 속도를 낮 춥니 다.

const FRAMES_PER_SECOND = 30; // Valid values are 60,30,20,15,10 
// set the mim time to render the next frame 
const FRAME_MIN_TIME = (1000/60) * (60/FRAMES_PER_SECOND) - (1000/60) * 0.5; 
var lastFrameTime = 0; // the last frame time 
function update(time){ 
    if(time-lastFrameTime < FRAME_MIN_TIME){ //skip the frame if the call is to early 
     requestAnimationFrame(update); 
     return; // return as there is nothing to do 
    } 
    lastFrameTime = time; // remember the time of the rendered frame 
    // render the frame 
    requestAnimationFrame(update); 
} 

포커스를 다른 탭으로 변경하면 포커스가 탭으로 반환 될 때까지 브라우저는 더 이상 요청을 호출하지 않습니다. 다른 타이머 이벤트처럼

는 통화 requestAnimationFrame 콜백 이벤트

var id = requestAnimationFrame(update); 
// to cancel 
cancelAnimationFrame(id); 

당신은 실제로 프레임 당 한 번 이상 requestAnimationFrame를 호출 할 수 있습니다를 취소하는 데 사용할 수있는 ID를 반환합니다. 모든 요청이 1/60 초 이내에 렌더링 될 수있는 한 모든 요청은 동시에 동기화되어 디스플레이에 표시됩니다. 그러나 렌더링 시간이 너무 길면 동기화되지 않을 수 있으므로주의해야합니다.

RequestAnimationFrame은 이중 버퍼링 변경으로 인해 깜박임 (렌더링이 완료되지 않은 경우 캔버스 표시)을 방지합니다.디스플레이 하드웨어와 동기화되고 전단을 방지합니다 (디스플레이가 프레임의 중간에서 업데이트되고 디스플레이의 상단이 이전 프레임을 표시하고 새 프레임의 하단을 표시 할 때 발생 함). 브라우저에 따라 더 많은 이점이 있습니다.

0

이 내 게임을 설정하는 방법입니다. 개인적으로, 나는 그것이 어떻게 작동하는지 이해하지 못한다. 비록 여기있는 누군가가 더 많이 알면 매우 흥미로울 것이지만. setInterval을 사용하면 루프 실행 속도를 설정할 수 있지만 최적의 속도는 브라우저에 따라 다릅니다. "then"및 "now"변수는 루프의 마지막 실행 이후 경과 한 시간을 결정하기위한 것입니다. 이제 다음 사용하고 있지만

var update = function() { 
     //STUFF 
}; 

// if using that variation just ignore then and now and call: 
update(); 
//in your main 

낫다 : 때때로 당신이 그것을 필요가 없습니다 그냥 사용할 수 있지만이 값은 업데이트 함수에 전달하고 프레임 속도에 따라 계산에 사용 할 수 있습니다. 이전의 대답은 여기에 몇 가지 정보를 부족 기본적인 사용의 예를 주석되기 때문에 자세한 내용은