このページの本文へ

WebSocket&Canvas パフォーマンス最適化のコツ (3/4)

2011年07月21日 13時00分更新

文●ハン☆スタ制作委員会/マインドフリー株式会社

  • この記事をはてなブックマークに追加
本文印刷

Canvasを使ったボールとバット、グラウンドの描画

 ゲーム画面の背景となるグラウンドの画像と、バット/ボールのアニメーションはCanvasを使って描画しています。バットやボールのアニメーションは1フレームごとにCanvasを再描画していますが、Canvasのすべての領域を再描画するとそれだけで非常に負荷の高い処理になります。そこで、変更のあった部分だけを再描画するようにします。

 ボールの移動処理では、移動前のボールの領域を背景の画像で描画してボールを削除し、移動後のボールをcontext.arc()で円を描いて表示しています。以下がボールの描画部分を抜粋したソースコードです。


(function(){
  //描画用のキャンバス
  var viewCanvas = document.getElementById('canvas');
  //グラウンドのimg
  var groundImg = document.getElementById('groundImg');
  var viewCtx = viewCanvas.getContext('2d');
  viewCtx.drawImage(groundImg,0,0);
  var ball = {x:0,y:0,v:3,radian:Math.PI/2};
  (function(){
    var nextx = ball.x + Math.cos(ball.radian) * ball.v;
    var nexty = ball.y + Math.sin(ball.radian) * ball.v;
    //移動前のボールの領域を背景の画像で塗りつぶす
    viewCtx.drawImage(groundImg,
      _ball.x-4,_ball.y-4,8,8,
      _ball.x-4,_ball.y-4,8,8);
    //ボールの移動
    _ball.x = nextx;
    _ball.y = nexty;
    //ボールの描画
    viewCtx.fillStyle = 'rgb(255,255,255)';
    viewCtx.beginPath();
    viewCtx.arc(_ball.x|0,_ball.y|0,3,0,Math.PI*2,true);
    viewCtx.fill();
    setTimeout(arguments.callee,34);
  })();
})();


 バットのアニメーションはボールのように移動せず、その場でスウィングするアニメーションです。あらかじめ、アニメーションのフレーム分だけバットの画像を並べておき、1フレームごとに描画する位置を指定して描画しています。

 以下は、バットのアニメーション処理のコードです。


(function(){
  var batImg = document.getElementById('batImg');
  var _bat = {x:225,y:240,isSwing:true,frame:0,widht:batImg.width/5,height:batImg.height};
  (function(){
    if(!_bat.isSwing()){
      //バットの領域を背景で塗りつぶす
      viewCtx.drawImage(groundImg,
        _bat.x,_bat.y,_bat.width,_bat.height,
        _bat.x,_bat.y,_bat.width,_bat.height);
      //現在のフレームの位置の画像で描画する
      viewCtx.drawImage(batImg,
        _bat.frame*_bat.width,0,_bat.width,_bat.height,
        _bat.x,_bat.y,_bat.width,_bat.height);
      _bat.frame ++;
      if(_bat.frame > 4){
        _bat.isSwing = true;
        _bat.frame = 0;
      }
    }
    setTimeout(arguments.callee,34);
  })();
  //画面をタッチしたときに_bat.isSwingをfalseにする
  document.getElementById('eventLayer')
  .addEventListener('touchstart', function(e) {
    if(_bat.isSwing){
      _bat.isSwing = false;
    }
  });
})();


この連載の記事

一覧へ
Web Professionalトップページバナー

この記事の編集者は以下の記事をオススメしています

ASCII.jp会員サービス 週刊Web Professional登録

Webディレクター江口明日香が行く