8

私は小さな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

ありがとう!
ダニエル

4

2 に答える 2

11

Phrogzは正しい考えを持っています。本当に、「source-atop」globalCompositeOperationを使用して、全体に半透明(または比率透明)の黒をペイントしたいだけです。

このように:http://jsfiddle.net/F4cNg/

このような洗練された暗くすることについては実際に良い質問がありましたが、作者はそれを削除しました。これは本当に残念です。洗練された形でも、描かれたものにダークマスクを作ることは確かに可能です。それらはあなたを助けないかもしれませんが、完全を期すために、そしていくつかの部分が明るく保たれている「暗いキャンバス」のもの(除外ゾーン)を探している人のために、これは次のように「xor」globalCompositeOperationで行うことができます:

http://jsfiddle.net/k6Xwy/1/

于 2011-12-10T04:14:02.627 に答える
11

このパフォーマンスのヒントを見たことがありますか?: http: //ajaxian.com/archives/canvas-image-data-optimization-tip

彼らは、パフォーマンスを向上させるためにDOMへの呼び出しを減らすことについて話します。

したがって、このヒントに基づいて、次のことを試してみてください。

var pixel = ctx.getImageData(0, 0, tmpCanvas.width, tmpCanvas.height);
    pixelData=pixel.data; // detach the pixel array from DOM
    var length = pixelData.length;
    for (var i = 0; i < length; i+= 4) {
        pixelData[i] = pixelData[i] * ratio;
        pixelData[i + 1] = pixelData[i + 1] * ratio;
        pixelData[i + 2] = pixelData[i + 2] * ratio;
    }

.data呼び出しにより、速度が低下する可能性があります。

于 2012-10-06T02:20:26.410 に答える