We are about to switch to a new forum software. Until then we have removed the registration on this forum.
Hello, In lieu of the layers library not being quite up and running for Processing2.0, I thought I'd give implementing a simple layering mechanism a try. Of course, much easier said than done. The sketch below is meant to have two layers where boxes and circles can be written to in the same order (boxes always on top of layers). While the result is kind of working, it just looks redundant, and I'm sure not efficient at all. Not only that, but I can't get the layers to erase when I invoke the clear() method. Additionally, nothing draws when I set noLoop() which I'd like to have set up by default.
Ideally, I would like to define a layer class that is an extension of PGraphics, so I can use custom objects, but at this point, that is a little beyond me.
Could someone take a look at this code and give me any pointers? Thanks in advance.
spot s; // declare object spot
box b; // declare object box
PGraphics layer_spots; // layer for spots
PGraphics layer_boxes; // layer for boxes
void setup() {
size (200, 200);
background (50);
//noLoop();
layer_spots = createGraphics (width, height);
layer_boxes = createGraphics (width, height);
// is there a way to set the layer order here so I don't have to set it up twice for each object below?
} // end of setup()
void draw() {
} // end of draw()
void keyPressed() {
if (key == 'x') {
println ("...pressed clear!");
layer_spots.clear();
layer_boxes.clear();
}
if (key == 'b') {
println ("...make box!");
layer_spots.beginDraw();
layer_spots.endDraw();
layer_boxes.beginDraw();
b = new box (random(width), random(height), int (15 + random(25)), int (random(255)) );
b.display(layer_boxes);
layer_boxes.endDraw();
image(layer_spots, 0, 0);
image(layer_boxes, 0, 0);
}
if (key == 's') {
println ("...make spot!");
layer_spots.beginDraw();
s = new spot (random(width), random(height), int (15 + random(25)), int (random(255)) );
s.display(layer_spots);
layer_spots.endDraw();
layer_boxes.beginDraw();
layer_boxes.endDraw();
image(layer_spots, 0, 0);
image(layer_boxes, 0, 0);
}
} // end of keyPressed()
//////////////classes
class box {
float x;
float y;
float side;
int value;
// constructor
box (float xp, float yp, float w,int v){
x = xp;
y = yp;
side = w;
value = v;
} // end of constructor
void display(PGraphics pg){
pg.fill (value);
pg.rect (x,y,side,side);
}
} // end of box
class spot {
float x;
float y;
float diameter;
int value;
// constructor
spot (float xp, float yp, float diam,int v){
x = xp;
y = yp;
diameter = diam;
value = v;
} // end of constructor
void display(PGraphics pg){
pg.fill (value);
pg.ellipse (x,y,diameter,diameter);
}
} // end of spot
Answers
"While the result is kind of working, it just looks redundant, and I'm sure not efficient at all."
What looks redundant and inefficient?
"Not only that, but I can't get the layers to erase when I invoke the clear() method._"
You erase the layers, but not the drawing surface...
"Additionally, nothing draws when I set noLoop() which I'd like to have set up by default."
Why set it by default? You have to invoke redraw() to update the screen.
Updated sketch (without the unchanged classes):
Thanks PhilHo, this is fantastic.
I thought my code was redundant, and inefficient, because the way I had written it before, I had to redraw both layers whether i was inserting a box or a spot. But seeing the layer order defined just once, as you did was what I was looking for:
Thanks for pointing out that if I setup my sketch with noLoop, I have to invoke redraw() whenever I make a change. That's what I was looking for.
Finally, I see how you got the code to clear the screen to work, but I still don't quite understand why you have to call beginDraw() and endDraw() before and after.
The bit of code below from the PGraphics documentation calls the clear() function successfully without having to call beginDraw()/endDraw() before and after. Why does it work there, but not in my code?
Thanks for your insights
In my short experience, beginDraw() is needed once only, before starting using it.
But endDraw() is always necessary to get updated result ASAP! 3:-O
That is, until endDraw() is issued, any modifications to it stay dormant! (~~)
clear() actually calls background(), which is a drawing operation like another, so it need to be withing begin/endDraw().
I first tried without and got an error, so I added it, it is as simple as that.
Even if it can work without, better stick to best practice to call them: some drawing surfaces (PGraphics implementations, like Java2D, OpenGL, PDF...) might not need it, but for others it can be mandatory.
Thank you guys. Most illuminating