0

ピクセル単位の地形であるマップがあります。これらのピクセルを個別に描画すると、レンダリングに多くの時間がかかります。

したがって、私の考えは、ピクセルが変更されたときに 100x100 の画像のブロックでそれらを描画し、それらの画像をレンダリングすることです。

「チャンク」のピクセルは、インデックス = x+y*幅の形式で 1D 配列に格納されます。

var img = game.c.createImageData(CHUNK_SIZE,CHUNK_SIZE);
for (var i=0;i<chunk.map.length;i++){
    var p = chunk.map[i];

    if (p){
        img.data[i*4] = 255;
        img.data[i*4+1] = 0;
        img.data[i*4+2] = 0;
        img.data[i*4+3] = 255;
    }else{
        img.data[i*4] = 0;
        img.data[i*4+1] = 0;
        img.data[i*4+2] = 0;
        img.data[i*4+3] = 0;
    }
}
this.render.push({x:chunk.x,y:chunk.y,img:img});

描く:

for (var i=0;i<this.map.render.length;i++){
        var img = this.map.render[i];
        if (img.x*CHUNK_SIZE > this.player.x - (this.ce.width/2)){
            if (img.y*CHUNK_SIZE > this.player.y -(this.ce.height/2)){
                if ((img.x*CHUNK_SIZE)+CHUNK_SIZE < this.player.x + (this.ce.width/2)){
                    if ((img.y*CHUNK_SIZE)+CHUNK_SIZE < this.player.y + (this.ce.height/2)){
                        console.log("Rendering chunk...");
                        this.c.putImageData(img.img,(img.x*CHUNK_SIZE)-this.player.x,(img.y*CHUNK_SIZE)-this.player.y); 
                    }
                }   
            }                   
        }
    }

ただし、正しくレンダリングされません。ボックスには透明なピクセルがいくつか含まれているため、空のグラデーションが必要な場合にキャンバスが透明になります。

キャンバスに穴を開けずに、そこにあったもの(空のグラデーション)が透明になるように画像を書きたい

4

1 に答える 1

1

を使用しputImageDataているときは、その領域 (アルファ チャネルを含む) のすべてのピクセルを置き換えるだけで、混合は行われません。

より良いアプローチは、チャンクをオフスクリーン キャンバス (または画像/スプライト) として保存し、それを使用drawImageしてメイン キャンバスに描画することです。

これにより、既存のピクセルが保持されるだけでなく (コンポジット モードが変更された場合は、コンポジット モードによって異なります)、 を使用するよりも高速になりputImageDataます。

それでも使用putImageDataを主張する必要がある場合は、最初getImageDataに既存のコンテンツに対して a を実行する必要があります。次に、すべてのピクセルを繰り返し処理し、チャンクのピクセルを、アルファ値に従ってメイン キャンバスから取得したデータと混合し、最終的に結果を配置します。それをキャンバスに戻します。これは非常にコストのかかる操作です。

于 2013-09-23T18:44:02.057 に答える