0

私は、canvas要素を多用するHTML5ゲームに取り組んでいます。メインのcanvas要素を更新する継続的なイベントループがあり、定期的に大きな変更を加える必要があります。基本的に、キャラクターが動き回ると、背景が更新されます。これが発生すると一時停止が目立つので、非同期機能で操作を実行しようとしましたが、まったく同じパフォーマンスヒットを取得しているようです。非同期関数で非表示のキャンバスに対してすべての操作を実行し、それらが完了したときにイベントループの後半でメインキャンバスにコピーしようとしましたが、パフォーマンスは向上しませんでした。

私が話している振る舞いを複製しているように見えるこの無意味な小さなプログラムを書きました。非同期関数であっても、canvas要素を拘束すると、プログラムの残りの部分に影響を与えるように見えます。

var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var ImDat=ctx.createImageData(1000,1000);
var ticker = 0;

ImDat.setPixel=function(x,y,c){
   var i=(x+y*this.width)*4;
   this.data[i]=c.R;
   this.data[i+1]=c.G;
   this.data[i+2]=c.B;
   this.data[i+3]=c.A;
}

var bigOperation = function() {
   for (var i = 0; i < 20; i++) {
      lilOperation();
   }
   console.log(new Date + 'big op done');
}

var lilOperation = function() {
   for (var i = 0; i < canvas.width; i++) {
      for (var j = 0; j < canvas.height; j++) {
         ImDat.setPixel(i, j, { R: Math.random() * 256, G: Math.random() * 256, B: Math.random() * 256, A: 256 });
      }
   }
   ctx.putImageData(ImDat, 0, 0);
}

var eventLoop = function() {
   if (ticker == 50) {
      ticker = 0;
      console.log(new Date + 'big op start'); 
      window.setTimeout(bigOperation, 1);                     
   } else {
      ticker++;
   }
      lilOperation();
      console.log(new Date + 'normal loop');  
}

window.setInterval(eventLoop, 10);

したがって、bigOperation関数が呼び出されるまで、一貫した時間間隔がログに記録され、その時点でイベントループが一時停止します。私はかなりくだらないシステムでこれに取り組んでいるので、効果を得るためにbigOperationの反復回数を増やす必要があるかもしれないことに注意してください。

ありがとう!

4

1 に答える 1

1

setTimeoutを使用しても、関数呼び出しが完了するまで実行はすべてをロックしますが、これはJavascriptの性質にすぎません。これは、物事をかなり単純化するので、実際には呪いよりも祝福です。

Javascriptのシングルスレッドの性質のために、「Webワーカー」と呼ばれるものが発明されました。これはブラウザの比較的新しい機能ですが、メインスレッドをロックせずに個別に実行されるタスクを実行できます。Modernaブラウザーでは、Webワーカーを使用してキャンバスタスクを実行できます

これで、ゲームについて何も知らなくても、実行に非常に長い時間がかかる重い関数を呼び出すことなく、達成したいこと(背景グラフィックの更新、キャラクターの移動など)が可能になるはずです。ピクセルごとの操作をたくさん実行していますか?もしそうなら、それらは他の手段で行うことはできませんか?Webワーカーの使用を検討する前に、実際にコードの最適化を検討し始めます。

于 2012-10-06T23:20:43.780 に答える