当我开发一个更大的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 :(得分: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>