私は小さなHTML5ゲームをやっていて、マップの最初にスプライトをロードしながら、GetImageData()/すべての画像をループする/ PutImageData()で処理を行います。
これは私のPCでは素晴らしくうまく機能しますが、私の携帯電話ではひどく遅いです。
PC: 5-6 ms
iPhone 4: 300-600 ms
Android HTC Desire S: 2500-3000 ms
私はいくつかの非常に基本的なベンチマークを行ってきましたが、GetImageDataとPutImageDataはどちらも非常に高速に実行されます。時間がかかるのは、コンテンツのループです。
今、私は明らかに電話の速度が低下すると予想していますが、1000xは少し過剰に聞こえ、HTCでの読み込みには約4分かかるため、機能しません。また、ゲーム内の他のすべては非常に妥当な速度で動作します(主に画面が途方もなく小さいためですが、それでも携帯電話のJSでは驚くほどうまく動作します)
この処理で私が行っているのは、基本的にスプライトを特定のレベルまで「暗くする」ことです。すべてのピクセルをループして、値<1を掛けるだけです。これですべてです。
これは遅すぎるので...すべてのピクセルを1つずつループせずに、Canvas機能(合成、不透明度など)を使用して、同じことを行うためのより良い方法はありますか?
注:このレイヤーには、100%透明なピクセルと、100%不透明なピクセルがあります。どちらも100%不透明または100%透明のままにする必要があります。
私が考えていたことがうまくいかない:
1)不透明度の低い新しいキャンバスにスプライトをペイントする。スプライトを不透明に保ち、暗くする必要があるため、これは機能しません。
2)スプライトをペイントし、その上に半透明の黒い長方形をペイントします。これにより、それらは暗くなりますが、透明なピクセルは透明ではなくなります...
何か案は?
これは私が使用しているコードです。ひどくばかげたものが含まれている場合に備えて、次のようにします。
function DarkenCanvas(baseImage, ratio) {
var tmpCanvas = document.createElement("canvas");
tmpCanvas.width = baseImage.width;
tmpCanvas.height = baseImage.height;
var ctx = tmpCanvas.getContext("2d");
ctx.drawImage(baseImage, 0, 0);
var pixelData = ctx.getImageData(0, 0, tmpCanvas.width, tmpCanvas.height);
var length = pixelData.data.length;
for (var i = 0; i < length; i+= 4) {
pixelData.data[i] = pixelData.data[i] * ratio;
pixelData.data[i + 1] = pixelData.data[i + 1] * ratio;
pixelData.data[i + 2] = pixelData.data[i + 2] * ratio;
}
ctx.putImageData(pixelData, 0, 0);
return tmpCanvas
}
編集:これは私が画像でやろうとしていることの例です:
オリジナル:http:
//www.crystalgears.com/isoengine/sprites-ground.png暗くした:http ://www.crystalgears.com/isoengine /sprites-ground_darkened.png
ありがとう!
ダニエル