GameCorder.net

3.html5とjavascriptでゲームを作る準備

ゲームを作るには、メインループを作らないといけません。
なので、まずメインループから作りたいと思います。

ゲームループを実装する

ゲームループを実装する関数として、javascriptには
setInterval
setTimeOut
などの関数がありますが、グラフィックスを実装する場合は
requestAnimationFrame
がいいらしいので、それを利用して、ループを作成したいと思います。
↓参考記事
http://www.ibm.com/developerworks/jp/java/library/j-html5-game2/#download

main.js

/*
	グローバル変数
*/
var g_Canvas;
var g_Ctx;
var g_Scene;	// シーン
var g_bLoaded;	// ロード

/*
	fps
*/
var g_LastAnimationFrameTime = 0,
g_LastFpsUpdateTime = 0,
g_FpsElement;

/*
	定数
*/
var LOAD = 1;
/*
	onload
	
	最初に呼び出される関数
*/
onload = function () {
    // キャンバスに代入
    g_Canvas = document.getElementById('id_canvas1');          // JavaScript uses the id to find the <canvas> element:
    g_FpsElement = document.getElementById("fps");		// 読み込まれていない
    // cavasに対応していない
    if (!g_Canvas || !g_Canvas.getContext) {
        alert("html5に対応していないので、実行できません");
        return false;
    }

    g_Ctx = g_Canvas.getContext('2d');            // ctx?
    g_Ctx.fillStyle = "rgb(200,200,200)";		// 塗りつぶし
    
    g_Scene = LOAD;      // ロードシーンに移行
    g_bLoaded = false;
    LoadTex();           // texture load
    requestNextAnimationFrame(animate);		// loopスタート
    // キーの登録
    //window.addEventListener('keydown', KeyDown, true);     
    //window.addEventListener('keyup', KeyUp, true);      
};

/*
	LoadTex
	
	テクスチャのロード
*/
function LoadTex(){
	
}

function animate(now) { 
    var fps = calculateFps(now); 
    requestNextAnimationFrame(animate);
 } 
           
/*
	Reprinted from Core HTML5 Canvas
	オリジナルインターバル設定
*/
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);
      };
   }
)
();


/*
 	fpsの計算
*/
function calculateFps(now) {
   var fps = 1000 / (now - g_LastAnimationFrameTime);
   g_LastAnimationFrameTime = now;

   if (now - g_LastFpsUpdateTime > 1000) {
      g_LastFpsUpdateTime = now;
      g_FpsElement.innerHTML = fps.toFixed(0) + ' fps';
   }
   return fps; 
}
		

上の記事をまるまる使いました。
fpsのidを拾ってfpsを入力してくれているので、fpsが表示されます。
時々fpsが極端に下がることがありますが、ブラウザなので、それはしょうがないと思ってあきらめるしかなさそうです。

main.js解説

onload関数が最初に実行される関数で、その中に定義したrequestNextAnimationFrame関数が入っています。
その中にanimate関数を渡しているので、animate関数の中にゲームループを実装していけばいいことになります。
これで、ゲームループの実装は終わりです。