2016-06-25 16 views
0

私はHTMLとJavascriptでキャンバス上にゲームを作成していました。私は何らかの華麗な鳥のゲームを作ってみたかったのですが、キーを押すと、プレイヤーのアニメーションが本当に吃音に見えます。見てみましょう: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); 

更新機能は1秒間に最大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); 

をキャンセルするために使用することができますIDを返すようにあなたが実際より1フレームに1回よりもrequestAnimationFrameのを呼び出すことができます。すべてのリクエストが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 

が優れている:時々、あなたがそれを必要としないし、ちょうど使用することができますが、この値は、更新機能に渡され、フレームレートに依存計算に使用することができます。以前の答えはここに、いくつかの情報が欠けている基本的な使い方の例を注釈を付けていると完全な詳細については

関連する問題