fpsとはfpsを描画する(プログラムでマリオを作る)
fpsはframe per secondの略で一秒間に何回処理を実行しているかを示すものになります。
一般的に60回実行するのが基本で、50回前後処理が実行されていれば、ヌルヌル動いているように見えます。
動きの少ないゲームでは、30程度でも見た目に影響がないようでです。
今回は、この実際に実行されているfpsを画面に描画してみます。
音声解説
今回は、fpsを表示したいと思います。
fpsはframe per secondの略で、
1秒間に何回処理を実行するのかを表します。
それでは、コードを書いていきます。
まず、htmlファイルを変更します。
fpsを表示するための要素を追加します。
<div id=“fps”></div>
続いて、main.jsを編集します。
fpsで使用するグローバル変数を定義します。
// fps
var g_LastAnimationFrameTime = 0;
var g_LastFpsUpdateTime = 0;
var g_FpsElement;
要素を取得します。
g_FpsElement = document.getElementById("fps");
fpsを描画するための関数を書きます。
// fps
calculateFps(now);
/*
fpsの計算と描画
*/
function calculateFps(now) {
// 1秒間に何回実行されているか
var fps = 1000 / (now - g_LastAnimationFrameTime);
g_LastAnimationFrameTime = now;
// 1秒経過
if (now - g_LastFpsUpdateTime > 1000) {
g_LastFpsUpdateTime = now;
// 要素にfps値を代入する
g_FpsElement.innerHTML = fps.toFixed(0) + ' fps';
}
}
fps.toFixed(0)はjavascriptの標準関数でこの場合は、小数点以下を消すために実行しています。
今回書いたソース
main.js
var g_Canvas;
var g_Ctx;
// fps
var g_LastAnimationFrameTime = 0;
var g_LastFpsUpdateTime = 0;
var g_FpsElement;
/**
onload
最初に呼び出される関数
*/
onload = function () {
// キャンバスに代入
g_Canvas = document.getElementById('id_canvas');
g_FpsElement = document.getElementById("fps");
// cavasに対応していない
if (!g_Canvas || !g_Canvas.getContext) {
alert("html5に対応していないので、実行できません");
return false;
}
g_Ctx = g_Canvas.getContext('2d'); // cox
requestNextAnimationFrame(animate); // loopスタート
};
function animate(now) {
// fps
calculateFps(now);
// 描画
Draw();
requestNextAnimationFrame(animate);
}
/*
60fps毎に処理を実行
*/
window.requestNextAnimationFrame =
(function () {
var originalWebkitRequestAnimationFrame = undefined,
wrapper = undefined,
callback = undefined,
geckoVersion = 0,
userAgent = navigator.userAgent,
index = 0,
self = this;
// Workaround for Chrome 10 bug where Chrome
// does not pass the time to the animation function
if (window.webkitRequestAnimationFrame) {
// Define the wrapper
wrapper = function (time) {
if (time === undefined) {
time = +new Date();
}
self.callback(time);
};
// Make the switch
originalWebkitRequestAnimationFrame = window.webkitRequestAnimationFrame;
window.webkitRequestAnimationFrame = function (callback, element) {
self.callback = callback;
// Browser calls the wrapper and wrapper calls the callback
originalWebkitRequestAnimationFrame(wrapper, element);
}
}
// Workaround for Gecko 2.0, which has a bug in
// mozRequestAnimationFrame() that restricts animations
// to 30-40 fps.
if (window.mozRequestAnimationFrame) {
// Check the Gecko version. Gecko is used by browsers
// other than Firefox. Gecko 2.0 corresponds to
// Firefox 4.0.
index = userAgent.indexOf('rv:');
if (userAgent.indexOf('Gecko') != -1) {
geckoVersion = userAgent.substr(index + 3, 3);
if (geckoVersion === '2.0') {
// Forces the return statement to fall through
// to the setTimeout() function.
window.mozRequestAnimationFrame = undefined;
}
}
}
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function (callback, element) {
var start,
finish;
window.setTimeout( function () {
start = +new Date();
callback(start);
finish = +new Date();
self.timeout = 1000 / 60 - (finish - start);
}, self.timeout);
};
}
)
();
/*
Draw
描画
*/
function Draw(){
g_Ctx.fillStyle = "rgb(255,0,0)"; // 赤に設定
g_Ctx.fillRect(0,0,640,480); // 塗りつぶす
}
/*
fpsの計算
*/
function calculateFps(now) {
// 1秒間に何回実行されているか
var fps = 1000 / (now - g_LastAnimationFrameTime);
g_LastAnimationFrameTime = now;
// 1秒経過
if (now - g_LastFpsUpdateTime > 1000) {
g_LastFpsUpdateTime = now;
// 要素にfps値を代入する
g_FpsElement.innerHTML = fps.toFixed(0) + ' fps';
}
}
index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="main.css">
<script lang="JavaScript" src=main.js></script>
</head>
<body>
<div id="fps"></div>
<div id="canvas_wrapper">
<canvas id="id_canvas" width="640" height="480"></canvas>
</div>
</body>
</html>