2016-09-22 12 views
1

大きなp5.jsスケッチを開発していたときに困惑した問題が発生しました。だから、私はそれをこの(恥知らずにはまばらな)スケッチに煮詰めました。p5.jsの半透明領域の下に積極的に描画

このp5.jsスケッチは、各フレームにいくつかのランダムなサイズの色付きの点を描画します。キャンバスの中央には、ビューアとドットの間にあるように見える半透明の青色の塗りつぶされた矩形があります。それは問題である半透明の青い部分です。スケッチは機能しますが、私は半透明を実現するためのよりよい方法があると考えています。

var cells; 
 
var cellsz = 10; 
 
var wid, hgt; 
 

 
function setup() 
 
{ 
 
    wid = floor(windowWidth/cellsz); 
 
    hgt = floor(windowHeight/cellsz); 
 
    createCanvas(windowWidth, windowHeight); 
 
    frameRate(15); 
 

 
    cells = new Array(wid); 
 

 
    for (x = 0; x < wid; x++) { 
 
    cells[x] = new Array(hgt); 
 
    for (y = 0; y < hgt; y++) { 
 
     cells[x][y] = false; 
 
    } 
 
    } 
 
} 
 

 
function cell_draw(c) 
 
{ 
 
    strokeWeight(1); 
 
    stroke(c.r, c.g, c.b); 
 
    fill(c.r, c.g, c.b); 
 
    ellipse(c.x, c.y, c.w, c.w); 
 
} 
 

 
function cell_new() 
 
{ 
 
    var x = int(floor(random(wid))); 
 
    var y = int(floor(random(hgt))); 
 

 
    var c = { 
 
    x: x * cellsz, 
 
    y: y * cellsz, 
 
    w: random(cellsz * 2), 
 
    r: floor(random(256)), 
 
    g: floor(random(256)), 
 
    b: floor(random(256)) 
 
    }; 
 

 
    cells[x][y] = c; 
 
    cell_draw(c); 
 
} 
 

 
// draw a translucent blue filled rectangle in the center of the window 
 
function overlay() 
 
{ 
 
    strokeWeight(1); 
 
    stroke(0, 0, 255, 75); 
 
    fill(0, 0, 255, 75); 
 
    var w = windowWidth/4; 
 
    var h = windowHeight/4; 
 
    rect(w, h, w * 2, h * 2); 
 
} 
 

 
// erase what's in the center of the window, then redraw the underlying cells 
 
function underlay() 
 
{ 
 
    strokeWeight(1); 
 
    stroke(255); 
 
    fill(255); 
 
    var w = windowWidth/4; 
 
    var h = windowHeight/4; 
 
    rect(w, h, w * 2, h * 2); 
 

 
    var x0 = floor((w/cellsz) - 2); 
 
    var y0 = floor((h/cellsz) - 2); 
 
    var x1 = floor(x0 + 3 + ((w * 2)/cellsz)); 
 
    var y1 = ceil(y0 + 3 + ((h * 2)/cellsz)); 
 

 
    for (x = x0; x <= x1; x++) { 
 
    for (y = y0; y <= y1; y++) { 
 
     if (cells[x][y]) { 
 
     cell_draw(cells[x][y]); 
 
     } 
 
    } 
 
    } 
 
} 
 

 
function draw() 
 
{ 
 
    underlay(); 
 

 
    for (i = 0; i < 5; i++) { 
 
    cell_new(); 
 
    } 
 

 
    overlay(); 
 
}
body {padding: 0; margin: 0;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.0/p5.js"></script>

コードの背後にある基本的な考え方は、キャンバスが固定サイズcellsに量子化されることです。各セルは、0個または1個のドットオブジェクト(位置、直径、および色)を保持します。それぞれの新しいランダムドットが選択されると、それが適切なセルに保存されます。これは、キャンバスにあるものの論理メモリとして機能します。しかし、それは完璧ではありませんが、ドットが描かれる順序を処理しないので、私たちはすべてここにいるのです。

私は半透明領域の基本的な問題で苦労しました。当初は、処理方法のようにフレーム全体を再描画していました...しかし、あまりにも多くのオブジェクトがありました。それは各フレームを描くには余りにも長い時間がかかりました。結局、私は半透明の四角形の下の領域を吹き飛ばし、影響を受けたオブジェクトだけを再描画し、上に新しい半透明の四角形を配置しました。

私がここで適用できるテクニックは、パフォーマンスが向上したり、コードの使用量が少なくなったり、どちらかが気になるのですか?

答えて

2

あなたのアプローチはかなり妥当ですが、基本的にはバッファイメージを使用して2D配列の代わりにアンダーレイを保存することで簡略化できます。ドットを描画すると、各フレームは単にバッファ全体を画面に描画し、その上に矩形のオーバーレイを描画します。これは自分自身を配列の位置に制限しないという利点があり、将来的に同様のレイヤーの問題に対応できます。

は、より多くの情報のための私の答えhereを参照してくださいが、基本的なアプローチは、このようなものになるだろう:

var buffer; 
 

 
function setup() { 
 
    createCanvas(windowWidth, windowHeight); 
 
    frameRate(15); 
 

 
    buffer = createGraphics(width, height); 
 
    
 
    //start with white background 
 
    buffer.background(255); 
 
} 
 

 
function drawRandomCircleToBuffer() { 
 
    buffer.noStroke(); 
 
    buffer.fill(random(255), random(255), random(255)); 
 
    var diameter = random(5, 20); 
 
    buffer.ellipse(random(buffer.width), random(buffer.height), diameter, diameter); 
 
} 
 

 
function overlay() { 
 
    strokeWeight(1); 
 
    stroke(0, 0, 255, 75); 
 
    fill(0, 0, 255, 75); 
 
    rect(mouseX, mouseY, 200, 200); 
 
} 
 

 
function draw() { 
 
    
 
    drawRandomCircleToBuffer(); 
 

 
    image(buffer, 0, 0); 
 
    overlay(); 
 
}
body {padding: 0; margin: 0;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.0/p5.js"></script>

+1

うわー、あなたは完全に正しいです。これは、私がやっていた狂気のものよりも約5倍速く、はるかに簡単です。私の試行のある時点で、私は実際に半透明領域の下にピクセルを保存し、その領域だけを再描画する何かを持っていました。しかし、それは扱いにくく、細心の注意を払っていました。私は単にバッファに描画し、その全体をスクリーンに吹き飛ばしてしまうことに決して跳躍しませんでした!驚くばかり! –

+1

他のアイデアが入ってくるかどうかを確認するために、もう少し時間を空けておきたいと思いますが、私はあなたがそれを確定したと思います。 –

+1

@gubblebozer問題はありません。イメージバッファーを使ってたくさんの素晴らしいことができます。あなたに他の質問があれば教えてください! –

関連する問題